--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Mar 29 16:40:31 2011 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Mar 29 16:40:51 2011 +0100
@@ -1580,7 +1580,7 @@
// Attribute clazz expression and store
// symbol + type back into the attributed tree.
Type clazztype = attribType(clazz, env);
- Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype, cdef != null);
+ Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
clazztype = chk.checkDiamond(tree, clazztype);
chk.validate(clazz, localEnv);
if (tree.encl != null) {
@@ -1778,62 +1778,48 @@
Pair<Scope, Scope> mapping,
List<Type> argtypes,
List<Type> typeargtypes) {
- if (clazztype.isErroneous() || mapping == erroneousMapping) {
+ if (clazztype.isErroneous() ||
+ clazztype.isInterface() ||
+ mapping == erroneousMapping) {
//if the type of the instance creation expression is erroneous,
- //or something prevented us to form a valid mapping, return the
- //(possibly erroneous) type unchanged
+ //or if it's an interface, or if something prevented us to form a valid
+ //mapping, return the (possibly erroneous) type unchanged
return clazztype;
}
- else if (clazztype.isInterface()) {
- //if the type of the instance creation expression is an interface
- //skip the method resolution step (JLS 15.12.2.7). The type to be
- //inferred is of the kind <X1,X2, ... Xn>C<X1,X2, ... Xn>
- clazztype = new ForAll(clazztype.tsym.type.allparams(), clazztype.tsym.type) {
- @Override
- public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
- switch (ck) {
- case EXTENDS: return types.getBounds(tv);
- default: return List.nil();
- }
- }
- @Override
- public Type inst(List<Type> inferred, Types types) throws Infer.NoInstanceException {
- // check that inferred bounds conform to their bounds
- infer.checkWithinBounds(tvars,
- types.subst(tvars, tvars, inferred), Warner.noWarnings);
- return super.inst(inferred, types);
- }
- };
+
+ //dup attribution environment and augment the set of inference variables
+ Env<AttrContext> localEnv = env.dup(tree);
+ localEnv.info.tvars = clazztype.tsym.type.getTypeArguments();
+
+ //if the type of the instance creation expression is a class type
+ //apply method resolution inference (JLS 15.12.2.7). The return type
+ //of the resolved constructor will be a partially instantiated type
+ ((ClassSymbol) clazztype.tsym).members_field = mapping.snd;
+ Symbol constructor;
+ try {
+ constructor = rs.resolveDiamond(tree.pos(),
+ localEnv,
+ clazztype.tsym.type,
+ argtypes,
+ typeargtypes);
+ } finally {
+ ((ClassSymbol) clazztype.tsym).members_field = mapping.fst;
+ }
+ if (constructor.kind == MTH) {
+ ClassType ct = new ClassType(clazztype.getEnclosingType(),
+ clazztype.tsym.type.getTypeArguments(),
+ clazztype.tsym);
+ clazztype = checkMethod(ct,
+ constructor,
+ localEnv,
+ tree.args,
+ argtypes,
+ typeargtypes,
+ localEnv.info.varArgs).getReturnType();
} else {
- //if the type of the instance creation expression is a class type
- //apply method resolution inference (JLS 15.12.2.7). The return type
- //of the resolved constructor will be a partially instantiated type
- ((ClassSymbol) clazztype.tsym).members_field = mapping.snd;
- Symbol constructor;
- try {
- constructor = rs.resolveDiamond(tree.pos(),
- env,
- clazztype.tsym.type,
- argtypes,
- typeargtypes);
- } finally {
- ((ClassSymbol) clazztype.tsym).members_field = mapping.fst;
- }
- if (constructor.kind == MTH) {
- ClassType ct = new ClassType(clazztype.getEnclosingType(),
- clazztype.tsym.type.getTypeArguments(),
- clazztype.tsym);
- clazztype = checkMethod(ct,
- constructor,
- env,
- tree.args,
- argtypes,
- typeargtypes,
- env.info.varArgs).getReturnType();
- } else {
- clazztype = syms.errType;
- }
+ clazztype = syms.errType;
}
+
if (clazztype.tag == FORALL && !pt.isErroneous()) {
//if the resolved constructor's return type has some uninferred
//type-variables, infer them using the expected type and declared
@@ -1863,34 +1849,28 @@
* inference. The inferred return type of the synthetic constructor IS
* the inferred type for the diamond operator.
*/
- private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype, boolean overrideProtectedAccess) {
+ private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
if (ctype.tag != CLASS) {
return erroneousMapping;
}
+
Pair<Scope, Scope> mapping =
new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym));
- List<Type> typevars = ctype.tsym.type.getTypeArguments();
+
+ //for each constructor in the original scope, create a synthetic constructor
+ //whose return type is the type of the class in which the constructor is
+ //declared, and insert it into the new scope.
for (Scope.Entry e = mapping.fst.lookup(names.init);
e.scope != null;
e = e.next()) {
- MethodSymbol newConstr = (MethodSymbol) e.sym.clone(ctype.tsym);
- if (overrideProtectedAccess && (newConstr.flags() & PROTECTED) != 0) {
- //make protected constructor public (this is required for
- //anonymous inner class creation expressions using diamond)
- newConstr.flags_field |= PUBLIC;
- newConstr.flags_field &= ~PROTECTED;
- }
- newConstr.name = names.init;
- List<Type> oldTypeargs = List.nil();
- if (newConstr.type.tag == FORALL) {
- oldTypeargs = ((ForAll) newConstr.type).tvars;
- }
- newConstr.type = new MethodType(newConstr.type.getParameterTypes(),
- new ClassType(ctype.getEnclosingType(), ctype.tsym.type.getTypeArguments(), ctype.tsym),
- newConstr.type.getThrownTypes(),
- syms.methodClass);
- newConstr.type = new ForAll(typevars.prependList(oldTypeargs), newConstr.type);
- mapping.snd.enter(newConstr);
+ Type synthRestype = new ClassType(ctype.getEnclosingType(),
+ ctype.tsym.type.getTypeArguments(),
+ ctype.tsym);
+ MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(),
+ names.init,
+ types.createMethodTypeWithReturn(e.sym.type, synthRestype),
+ e.sym.owner);
+ mapping.snd.enter(synhConstr);
}
return mapping;
}