Mercurial > hg > icedtea9-forest > langtools
changeset 1249:d2508136751c
7148164: attribution code for diamond should not rely on mutable state
Summary: Update attribution code for diamond operator not to rely on mutable state
Reviewed-by: jjg
author | mcimadamore |
---|---|
date | Fri, 02 Mar 2012 12:58:35 +0000 |
parents | 6aafebe9a394 |
children | dda6a5b15580 |
files | src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Resolve.java |
diffstat | 2 files changed, 48 insertions(+), 56 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Mar 02 12:57:47 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Mar 02 12:58:35 2012 +0000 @@ -1627,7 +1627,6 @@ // Attribute clazz expression and store // symbol + type back into the attributed tree. Type clazztype = attribType(clazz, env); - Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype); clazztype = chk.checkDiamond(tree, clazztype); chk.validate(clazz, localEnv); if (tree.encl != null) { @@ -1654,7 +1653,7 @@ List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv); if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) { - clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes); + clazztype = attribDiamond(localEnv, tree, clazztype, argtypes, typeargtypes); clazz.type = clazztype; } else if (allowDiamondFinder && tree.def == null && @@ -1671,7 +1670,6 @@ inferred = attribDiamond(localEnv, tree, clazztype, - mapping, argtypes, typeargtypes); } @@ -1827,12 +1825,10 @@ Type attribDiamond(Env<AttrContext> env, JCNewClass tree, Type clazztype, - Pair<Scope, Scope> mapping, List<Type> argtypes, List<Type> typeargtypes) { if (clazztype.isErroneous() || - clazztype.isInterface() || - mapping == erroneousMapping) { + clazztype.isInterface()) { //if the type of the instance creation expression is erroneous, //or if it's an interface, or if something prevented us to form a valid //mapping, return the (possibly erroneous) type unchanged @@ -1841,27 +1837,22 @@ //dup attribution environment and augment the set of inference variables Env<AttrContext> localEnv = env.dup(tree); - localEnv.info.tvars = clazztype.tsym.type.getTypeArguments(); + + ClassType site = new ClassType(clazztype.getEnclosingType(), + clazztype.tsym.type.getTypeArguments(), + clazztype.tsym); //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(), + Symbol constructor = rs.resolveDiamond(tree.pos(), localEnv, - clazztype, + site, 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, + clazztype = checkMethod(site, constructor, localEnv, tree.args, @@ -1893,42 +1884,6 @@ true); } - /** Creates a synthetic scope containing fake generic constructors. - * Assuming that the original scope contains a constructor of the kind: - * Foo(X x, Y y), where X,Y are class type-variables declared in Foo, - * the synthetic scope is added a generic constructor of the kind: - * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond - * inference. The inferred return type of the synthetic constructor IS - * the inferred type for the diamond operator. - */ - 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)); - - //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()) { - 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; - } - - private final Pair<Scope,Scope> erroneousMapping = new Pair<Scope,Scope>(null, null); - /** Make an attributed null check tree. */ public JCExpression makeNullCheck(JCExpression arg) {
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Mar 02 12:57:47 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Mar 02 12:58:35 2012 +0000 @@ -1835,7 +1835,7 @@ steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { currentResolutionContext.step = steps.head; - sym = findConstructor(pos, env, site, argtypes, typeargtypes, + sym = findDiamond(env, site, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired()); currentResolutionContext.resolutionCache.put(steps.head, sym); @@ -1867,6 +1867,43 @@ } } + /** This method scans all the constructor symbol in a given class scope - + * assuming that the original scope contains a constructor of the kind: + * Foo(X x, Y y), where X,Y are class type-variables declared in Foo, + * a method check is executed against the modified constructor type: + * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond + * inference. The inferred return type of the synthetic constructor IS + * the inferred type for the diamond operator. + */ + private Symbol findDiamond(Env<AttrContext> env, + Type site, + List<Type> argtypes, + List<Type> typeargtypes, + boolean allowBoxing, + boolean useVarargs) { + Symbol bestSoFar = methodNotFound; + for (Scope.Entry e = site.tsym.members().lookup(names.init); + e.scope != null; + e = e.next()) { + //- System.out.println(" e " + e.sym); + if (e.sym.kind == MTH && + (e.sym.flags_field & SYNTHETIC) == 0) { + List<Type> oldParams = e.sym.type.tag == FORALL ? + ((ForAll)e.sym.type).tvars : + List.<Type>nil(); + Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), + types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site)); + bestSoFar = selectBest(env, site, argtypes, typeargtypes, + new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym), + bestSoFar, + allowBoxing, + useVarargs, + false); + } + } + return bestSoFar; + } + /** Resolve constructor. * @param pos The position to use for error reporting. * @param env The environment current at the constructor invocation.