src/share/classes/com/sun/tools/javac/comp/Attr.java

Print this page

        

*** 37,46 **** --- 37,47 ---- import com.sun.source.util.SimpleTreeVisitor; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; + import com.sun.tools.javac.code.TypeAnnotationPosition.*; import com.sun.tools.javac.comp.Check.CheckContext; import com.sun.tools.javac.comp.DeferredAttr.AttrMode; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Infer.FreeTypeListener; import com.sun.tools.javac.jvm.*;
*** 92,101 **** --- 93,105 ---- final JCDiagnostic.Factory diags; final Annotate annotate; final TypeAnnotations typeAnnotations; final DeferredLintHandler deferredLintHandler; + /** The creator that will be used for any varDef's we visit. */ + Annotate.PositionCreator creator; + public static Attr instance(Context context) { Attr instance = context.get(attrKey); if (instance == null) instance = new Attr(context); return instance;
*** 120,129 **** --- 124,135 ---- types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); annotate = Annotate.instance(context); typeAnnotations = TypeAnnotations.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); + creator = null; + speculative = false; Options options = Options.instance(context); Source source = Source.instance(context); allowGenerics = source.allowGenerics();
*** 229,238 **** --- 235,249 ---- /** * Switch: name of source level; used for error reporting. */ String sourceName; + /** + * Whether or not this is speculative attribution + */ + boolean speculative; + /** Check kind and type of given tree against protokind and prototype. * If check succeeds, store type in tree and return it. * If check fails, store errType in tree and return it. * No checks are performed if the prototype is a method type. * It is not necessary in this case since we know that kind and type
*** 423,445 **** public Type coerce(Type etype, Type ttype) { return cfolder.coerce(etype, ttype); } ! public Type attribType(JCTree node, TypeSymbol sym) { Env<AttrContext> env = enter.typeEnvs.get(sym); Env<AttrContext> localEnv = env.dup(node, env.info.dup()); ! return attribTree(node, localEnv, unknownTypeInfo); } ! public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) { // Attribute qualifying package or class. JCFieldAccess s = (JCFieldAccess)tree.qualid; ! return attribTree(s.selected, ! env, new ResultInfo(tree.staticImport ? TYP : (TYP | PCK), ! Type.noType)); } public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) { breakTree = tree; JavaFileObject prev = log.useSource(env.toplevel.sourcefile); --- 434,462 ---- public Type coerce(Type etype, Type ttype) { return cfolder.coerce(etype, ttype); } ! public Type attribType(JCTree node, TypeSymbol sym, ! JCLambda currentLambda, boolean speculative) { Env<AttrContext> env = enter.typeEnvs.get(sym); Env<AttrContext> localEnv = env.dup(node, env.info.dup()); ! return attribTree(node, localEnv, currentLambda, ! unknownTypeInfo, speculative); } ! public Type attribType(JCTree node, TypeSymbol sym) { ! return attribType(node, sym, currentLambda, speculative); ! } ! ! public Type attribImportQualifier(JCImport tree, Env<AttrContext> env, ! JCLambda currLambda, boolean speculative) { // Attribute qualifying package or class. JCFieldAccess s = (JCFieldAccess)tree.qualid; ! return attribTree(s.selected, env, currentLambda, new ResultInfo(tree.staticImport ? TYP : (TYP | PCK), ! Type.noType), speculative); } public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) { breakTree = tree; JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
*** 569,578 **** --- 586,597 ---- /** Visitor argument: the current environment. */ Env<AttrContext> env; + JCLambda currentLambda; + /** Visitor argument: the currently expected attribution result. */ ResultInfo resultInfo; /** Visitor result: the computed type.
*** 584,599 **** * * @param tree The tree to be visited. * @param env The environment visitor argument. * @param resultInfo The result info visitor argument. */ ! Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { Env<AttrContext> prevEnv = this.env; ResultInfo prevResult = this.resultInfo; try { this.env = env; this.resultInfo = resultInfo; tree.accept(this); if (tree == breakTree && resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) { throw new BreakAttr(copyEnv(env)); } --- 603,624 ---- * * @param tree The tree to be visited. * @param env The environment visitor argument. * @param resultInfo The result info visitor argument. */ ! Type attribTree(JCTree tree, Env<AttrContext> env, ! JCLambda lambda, ResultInfo resultInfo, ! boolean speculative) { Env<AttrContext> prevEnv = this.env; ResultInfo prevResult = this.resultInfo; + JCLambda prevLambda = this.currentLambda; + boolean prevSpeculative = this.speculative; try { this.env = env; this.resultInfo = resultInfo; + this.currentLambda = lambda; + this.speculative = speculative; tree.accept(this); if (tree == breakTree && resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) { throw new BreakAttr(copyEnv(env)); }
*** 602,612 **** --- 627,648 ---- tree.type = syms.errType; return chk.completionError(tree.pos(), ex); } finally { this.env = prevEnv; this.resultInfo = prevResult; + this.currentLambda = prevLambda; + this.speculative = prevSpeculative; + } } + + Type attribTree(JCTree tree, Env<AttrContext> env, + JCLambda currentLambda, ResultInfo resultInfo) { + return attribTree(tree, env, currentLambda, resultInfo, speculative); + } + + Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { + return attribTree(tree, env, currentLambda, resultInfo, speculative); } Env<AttrContext> copyEnv(Env<AttrContext> env) { Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
*** 631,682 **** return newScope; } /** Derived visitor method: attribute an expression tree. */ public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) { ! return attribTree(tree, env, new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType)); } /** Derived visitor method: attribute an expression tree with * no constraints on the computed type. */ public Type attribExpr(JCTree tree, Env<AttrContext> env) { ! return attribTree(tree, env, unknownExprInfo); } /** Derived visitor method: attribute a type tree. */ public Type attribType(JCTree tree, Env<AttrContext> env) { ! Type result = attribType(tree, env, Type.noType); return result; } /** Derived visitor method: attribute a type tree. */ ! Type attribType(JCTree tree, Env<AttrContext> env, Type pt) { ! Type result = attribTree(tree, env, new ResultInfo(TYP, pt)); return result; } /** Derived visitor method: attribute a statement or definition tree. */ public Type attribStat(JCTree tree, Env<AttrContext> env) { ! return attribTree(tree, env, statInfo); } /** Attribute a list of expressions, returning a list of types. */ List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) { ListBuffer<Type> ts = new ListBuffer<>(); for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) ! ts.append(attribExpr(l.head, env, pt)); return ts.toList(); } /** Attribute a list of statements, returning nothing. */ <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) { for (List<T> l = trees; l.nonEmpty(); l = l.tail) attribStat(l.head, env); } --- 667,761 ---- return newScope; } /** Derived visitor method: attribute an expression tree. */ + public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, + JCLambda currentLambda, boolean speculative) { + return attribTree(tree, env, currentLambda, + new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType), + speculative); + } + public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) { ! return attribExpr(tree, env, pt, currentLambda, speculative); } /** Derived visitor method: attribute an expression tree with * no constraints on the computed type. */ public Type attribExpr(JCTree tree, Env<AttrContext> env) { ! return attribTree(tree, env, currentLambda, ! unknownExprInfo, speculative); } /** Derived visitor method: attribute a type tree. */ + public Type attribType(JCTree tree, Env<AttrContext> env) { ! Type result = attribType(tree, env, Type.noType, ! currentLambda, speculative); ! return result; ! } ! ! public Type attribType(JCTree tree, Env<AttrContext> env, ! JCLambda currentLambda, boolean speculative) { ! Type result = attribType(tree, env, Type.noType, ! currentLambda, speculative); return result; } /** Derived visitor method: attribute a type tree. */ ! Type attribType(JCTree tree, Env<AttrContext> env, Type pt, ! JCLambda currentLambda, boolean speculative) { ! Type result = attribTree(tree, env, currentLambda, ! new ResultInfo(TYP, pt), speculative); return result; } /** Derived visitor method: attribute a statement or definition tree. */ + public Type attribStat(JCTree tree, Env<AttrContext> env) { ! return attribTree(tree, env, currentLambda, statInfo, speculative); ! } ! ! public Type attribStat(JCTree tree, JCLambda lambda, ! Env<AttrContext> env) { ! return attribTree(tree, env, lambda, statInfo, speculative); ! } ! ! public Type attribStat(JCTree tree, JCLambda lambda, ! Env<AttrContext> env, boolean speculative) { ! return attribTree(tree, env, lambda, statInfo, speculative); } /** Attribute a list of expressions, returning a list of types. */ List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) { ListBuffer<Type> ts = new ListBuffer<>(); for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) ! ts.append(attribExpr(l.head, env, pt, currentLambda, speculative)); return ts.toList(); } /** Attribute a list of statements, returning nothing. */ + <T extends JCTree> void attribStats(List<T> trees, JCLambda lambda, + Env<AttrContext> env, + boolean speculative) { + for (List<T> l = trees; l.nonEmpty(); l = l.tail) + attribStat(l.head, lambda, env, speculative); + } + + <T extends JCTree> void attribStats(List<T> trees, JCLambda lambda, + Env<AttrContext> env) { + for (List<T> l = trees; l.nonEmpty(); l = l.tail) + attribStat(l.head, lambda, env); + } + <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) { for (List<T> l = trees; l.nonEmpty(); l = l.tail) attribStat(l.head, env); }
*** 684,698 **** */ int attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) { int kind = VAL; for (JCExpression arg : trees) { Type argtype; ! if (allowPoly && deferredAttr.isDeferred(env, arg)) { ! argtype = deferredAttr.new DeferredType(arg, env); kind |= POLY; } else { ! argtype = chk.checkNonVoid(arg, attribTree(arg, env, unknownAnyPolyInfo)); } argtypes.append(argtype); } return kind; } --- 763,778 ---- */ int attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) { int kind = VAL; for (JCExpression arg : trees) { Type argtype; ! if (allowPoly && deferredAttr.isDeferred(env, arg, currentLambda)) { ! argtype = deferredAttr.new DeferredType(arg, env, currentLambda, ! annotate.noCreator); kind |= POLY; } else { ! argtype = chk.checkNonVoid(arg, attribTree(arg, env, currentLambda, unknownAnyPolyInfo, speculative)); } argtypes.append(argtype); } return kind; }
*** 719,737 **** * Attribute type variables (of generic classes or methods). * Compound types are attributed later in attribBounds. * @param typarams the type variables to enter * @param env the current environment */ ! void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) { for (JCTypeParameter tvar : typarams) { TypeVar a = (TypeVar)tvar.type; a.tsym.flags_field |= UNATTRIBUTED; a.bound = Type.noType; if (!tvar.bounds.isEmpty()) { ! List<Type> bounds = List.of(attribType(tvar.bounds.head, env)); for (JCExpression bound : tvar.bounds.tail) ! bounds = bounds.prepend(attribType(bound, env)); types.setBounds(a, bounds.reverse()); } else { // if no bounds are given, assume a single bound of // java.lang.Object. types.setBounds(a, List.of(syms.objectType)); --- 799,821 ---- * Attribute type variables (of generic classes or methods). * Compound types are attributed later in attribBounds. * @param typarams the type variables to enter * @param env the current environment */ ! void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env, ! JCLambda currentLambda, boolean speculative) { for (JCTypeParameter tvar : typarams) { TypeVar a = (TypeVar)tvar.type; a.tsym.flags_field |= UNATTRIBUTED; a.bound = Type.noType; if (!tvar.bounds.isEmpty()) { ! List<Type> bounds = ! List.of(attribType(tvar.bounds.head, env, ! currentLambda, speculative)); for (JCExpression bound : tvar.bounds.tail) ! bounds = bounds.prepend(attribType(bound, env, currentLambda, ! speculative)); types.setBounds(a, bounds.reverse()); } else { // if no bounds are given, assume a single bound of // java.lang.Object. types.setBounds(a, List.of(syms.objectType));
*** 745,777 **** /** * Attribute the type references in a list of annotations. */ void attribAnnotationTypes(List<JCAnnotation> annotations, ! Env<AttrContext> env) { for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { JCAnnotation a = al.head; ! attribType(a.annotationType, env); } } /** * Attribute a "lazy constant value". * @param env The env for the const value * @param initializer The initializer for the const value * @param type The expected type, or null * @see VarSymbol#setLazyConstValue */ ! public Object attribLazyConstantValue(Env<AttrContext> env, JCVariableDecl variable, ! Type type) { DiagnosticPosition prevLintPos = deferredLintHandler.setPos(variable.pos()); try { ! Type itype = attribExpr(variable.init, env, type); if (itype.constValue() != null) { return coerce(itype, type).constValue(); } else { return null; } --- 829,871 ---- /** * Attribute the type references in a list of annotations. */ void attribAnnotationTypes(List<JCAnnotation> annotations, ! Env<AttrContext> env, ! JCLambda currentLambda, ! boolean speculative) { for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { JCAnnotation a = al.head; ! attribType(a.annotationType, env, currentLambda, speculative); ! } } + + void attribAnnotationTypes(List<JCAnnotation> annotations, + Env<AttrContext> env) { + attribAnnotationTypes(annotations, env, currentLambda, speculative); } /** * Attribute a "lazy constant value". * @param env The env for the const value * @param initializer The initializer for the const value * @param type The expected type, or null * @see VarSymbol#setLazyConstValue */ ! public Object attribLazyConstantValue(final Env<AttrContext> env, JCVariableDecl variable, ! Type type, ! JCLambda currentLambda, ! boolean speculative) { DiagnosticPosition prevLintPos = deferredLintHandler.setPos(variable.pos()); try { ! Type itype = attribExpr(variable.init, env, type, ! currentLambda, speculative); if (itype.constValue() != null) { return coerce(itype, type).constValue(); } else { return null; }
*** 790,803 **** */ Type attribBase(JCTree tree, Env<AttrContext> env, boolean classExpected, boolean interfaceExpected, ! boolean checkExtensible) { Type t = tree.type != null ? tree.type : ! attribType(tree, env); return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); } Type checkBase(Type t, JCTree tree, Env<AttrContext> env, --- 884,899 ---- */ Type attribBase(JCTree tree, Env<AttrContext> env, boolean classExpected, boolean interfaceExpected, ! boolean checkExtensible, ! JCLambda currentLambda, ! boolean speculative) { Type t = tree.type != null ? tree.type : ! attribType(tree, env, currentLambda, speculative); return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); } Type checkBase(Type t, JCTree tree, Env<AttrContext> env,
*** 878,887 **** --- 974,984 ---- ((JCNewClass) env.tree).encl == null) { c.flags_field |= NOOUTERTHIS; } attribClass(tree.pos(), c); + result = tree.type = c.type; } } public void visitMethodDef(JCMethodDecl tree) {
*** 1015,1028 **** "call.to.super.not.allowed.in.enum.ctor", env.enclClass.sym); } } - // Attribute all type annotations in the body - annotate.annotateTypeLater(tree.body, localEnv, m, null); - annotate.flush(); - // Attribute method body. attribStat(tree.body, localEnv); } localEnv.info.scope.leave(); --- 1112,1121 ----
*** 1032,1056 **** chk.setLint(prevLint); chk.setMethod(prevMethod); } } ! public void visitVarDef(JCVariableDecl tree) { // Local variables have not been entered yet, so we need to do it now: if (env.info.scope.owner.kind == MTH) { if (tree.sym != null) { // parameters have already been entered env.info.scope.enter(tree.sym); } else { ! memberEnter.memberEnter(tree, env); ! annotate.flush(); } ! } else { ! if (tree.init != null) { ! // Field initializer expression need to be entered. ! annotate.annotateTypeLater(tree.init, env, tree.sym, tree.pos()); annotate.flush(); } } VarSymbol v = tree.sym; Lint lint = env.info.lint.augment(v); --- 1125,1153 ---- chk.setLint(prevLint); chk.setMethod(prevMethod); } } ! public void visitVarDef(final JCVariableDecl tree) { // Local variables have not been entered yet, so we need to do it now: if (env.info.scope.owner.kind == MTH) { if (tree.sym != null) { // parameters have already been entered env.info.scope.enter(tree.sym); } else { ! Annotate.PositionCreator oldcreator = creator; ! ! if (creator == null) { ! creator = annotate.localVarCreator(tree.pos); } ! ! annotate.enterStart(); ! memberEnter.memberEnter(tree, env, creator, ! currentLambda, speculative); ! annotate.enterDone(); annotate.flush(); + creator = oldcreator; } } VarSymbol v = tree.sym; Lint lint = env.info.lint.augment(v);
*** 1097,1117 **** public void visitBlock(JCBlock tree) { if (env.info.scope.owner.kind == TYP) { // Block is a static or instance initializer; // let the owner of the environment be a freshly // created BLOCK-method. ! Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); localEnv.info.scope.owner = new MethodSymbol(tree.flags | BLOCK | env.info.scope.owner.flags() & STRICTFP, names.empty, null, env.info.scope.owner); - if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; ! // Attribute all type annotations in the block ! annotate.annotateTypeLater(tree, localEnv, localEnv.info.scope.owner, null); ! annotate.flush(); { // Store init and clinit type annotations with the ClassSymbol // to allow output in Gen.normalizeDefs. ClassSymbol cs = (ClassSymbol)env.info.scope.owner; --- 1194,1212 ---- public void visitBlock(JCBlock tree) { if (env.info.scope.owner.kind == TYP) { // Block is a static or instance initializer; // let the owner of the environment be a freshly // created BLOCK-method. ! final Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); localEnv.info.scope.owner = new MethodSymbol(tree.flags | BLOCK | env.info.scope.owner.flags() & STRICTFP, names.empty, null, env.info.scope.owner); ! if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; ! attribStats(tree.stats, localEnv); { // Store init and clinit type annotations with the ClassSymbol // to allow output in Gen.normalizeDefs. ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
*** 1120,1131 **** cs.appendClassInitTypeAttributes(tas); } else { cs.appendInitTypeAttributes(tas); } } - - attribStats(tree.stats, localEnv); } else { // Create a new local environment with a local scope. Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup())); try { --- 1215,1224 ----
*** 1344,1354 **** --- 1437,1450 ---- chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details)); } }; ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext); if (resource.hasTag(VARDEF)) { + Annotate.PositionCreator oldcreator = creator; + creator = annotate.resourceVarCreator(tree.pos); attribStat(resource, tryEnv); + creator = oldcreator; twrResult.check(resource, resource.type); //check that resource type cannot throw InterruptedException checkAutoCloseable(resource.pos(), localEnv, resource.type);
*** 1369,1379 **** --- 1465,1478 ---- for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { JCCatch c = l.head; Env<AttrContext> catchEnv = localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup())); try { + Annotate.PositionCreator oldcreator = creator; + creator = annotate.exceptionParamCreator(tree.pos); Type ctype = attribStat(c.param, catchEnv); + creator = oldcreator; if (TreeInfo.isMultiCatch(c)) { //multi-catch parameter is implicitly marked as final c.param.sym.flags_field |= FINAL | UNION; } if (c.param.sym.kind == Kinds.VAR) {
*** 1475,1495 **** JCConditional condTree = (JCConditional)tree; return isBooleanOrNumeric(env, condTree.truepart) && isBooleanOrNumeric(env, condTree.falsepart); case APPLY: JCMethodInvocation speculativeMethodTree = ! (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo); Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType(); return types.unboxedTypeOrType(owntype).isPrimitive(); case NEWCLASS: JCExpression className = removeClassParams.translate(((JCNewClass)tree).clazz); JCExpression speculativeNewClassTree = ! (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo); return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive(); default: ! Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type; speculativeType = types.unboxedTypeOrType(speculativeType); return speculativeType.isPrimitive(); } } //where --- 1574,1599 ---- JCConditional condTree = (JCConditional)tree; return isBooleanOrNumeric(env, condTree.truepart) && isBooleanOrNumeric(env, condTree.falsepart); case APPLY: JCMethodInvocation speculativeMethodTree = ! (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo, ! currentLambda, annotate.noCreator); Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType(); return types.unboxedTypeOrType(owntype).isPrimitive(); case NEWCLASS: JCExpression className = removeClassParams.translate(((JCNewClass)tree).clazz); JCExpression speculativeNewClassTree = ! (JCExpression)deferredAttr.attribSpeculative(className, ! env, ! unknownTypeInfo, ! currentLambda, ! annotate.newObjCreator(tree.pos)); return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive(); default: ! Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo, currentLambda, annotate.noCreator).type; speculativeType = types.unboxedTypeOrType(speculativeType); return speculativeType.isPrimitive(); } } //where
*** 1748,1758 **** localEnv.info.isSelfCall = true; // Attribute arguments, yielding list of argument types. attribArgs(tree.args, localEnv, argtypesBuf); argtypes = argtypesBuf.toList(); ! typeargtypes = attribTypes(tree.typeargs, localEnv); // Variable `site' points to the class in which the called // constructor is defined. Type site = env.enclClass.sym.type; if (methName == names._super) { --- 1852,1882 ---- localEnv.info.isSelfCall = true; // Attribute arguments, yielding list of argument types. attribArgs(tree.args, localEnv, argtypesBuf); argtypes = argtypesBuf.toList(); ! ! // Attribute and annotate the type arguments ! ListBuffer<Type> typeargtypesbuf = new ListBuffer<>(); ! int i = 0; ! ! for (List<JCExpression> l = tree.typeargs; ! l.nonEmpty(); l = l.tail, i++) { ! final JCExpression arg = l.head; ! annotate.enterStart(); ! typeargtypesbuf.append(attribType(arg, localEnv)); ! annotate.annotateTypeLater(arg, localEnv, ! localEnv.info.scope.owner, ! tree.pos(), currentLambda, ! annotate.constructorInvokeTypeArgCreator(i, tree.pos), ! speculative); ! annotate.enterDone(); ! annotate.flush(); ! } ! ! typeargtypes = ! chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList()); // Variable `site' points to the class in which the called // constructor is defined. Type site = env.enclClass.sym.type; if (methName == names._super) {
*** 1821,1831 **** } else { // Otherwise, we are seeing a regular method call. // Attribute the arguments, yielding list of argument types, ... int kind = attribArgs(tree.args, localEnv, argtypesBuf); argtypes = argtypesBuf.toList(); ! typeargtypes = attribAnyTypes(tree.typeargs, localEnv); // ... and attribute the method using as a prototype a methodtype // whose formal argument types is exactly the list of actual // arguments (this will also set the method symbol). Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes); --- 1945,1974 ---- } else { // Otherwise, we are seeing a regular method call. // Attribute the arguments, yielding list of argument types, ... int kind = attribArgs(tree.args, localEnv, argtypesBuf); argtypes = argtypesBuf.toList(); ! ! // Attribute and annotate the type arguments ! ListBuffer<Type> typeargtypesbuf = new ListBuffer<>(); ! int i = 0; ! ! for (List<JCExpression> l = tree.typeargs; ! l.nonEmpty(); l = l.tail, i++) { ! final JCExpression arg = l.head; ! annotate.enterStart(); ! typeargtypesbuf.append(attribType(arg, localEnv)); ! annotate.annotateTypeLater(arg, localEnv, ! localEnv.info.scope.owner, ! tree.pos(), currentLambda, ! annotate.methodInvokeTypeArgCreator(i, tree.pos), ! speculative); ! annotate.flush(); ! annotate.enterDone(); ! } ! ! typeargtypes = typeargtypesbuf.toList(); // ... and attribute the method using as a prototype a methodtype // whose formal argument types is exactly the list of actual // arguments (this will also set the method symbol). Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
*** 1846,1855 **** --- 1989,1999 ---- // Check that value of resulting type is admissible in the // current context. Also, capture the return type result = check(tree, capture(restype), VAL, resultInfo); } + chk.validate(tree.typeargs, localEnv); } //where Type adjustMethodReturnType(Type qualifierType, Name methodName, List<Type> argtypes, Type restype) { if (allowCovariantReturns &&
*** 1921,1938 **** clazzid = ((JCTypeApply) clazz).clazz; if (clazzid.hasTag(ANNOTATED_TYPE)) { annoclazzid = (JCAnnotatedType) clazzid; clazzid = annoclazzid.underlyingType; } ! } else { ! if (clazz.hasTag(ANNOTATED_TYPE)) { annoclazzid = (JCAnnotatedType) clazz; clazzid = annoclazzid.underlyingType; } else { clazzid = clazz; } - } JCExpression clazzid1 = clazzid; // The same in fully qualified form if (tree.encl != null) { // We are seeing a qualified new, of the form --- 2065,2080 ---- clazzid = ((JCTypeApply) clazz).clazz; if (clazzid.hasTag(ANNOTATED_TYPE)) { annoclazzid = (JCAnnotatedType) clazzid; clazzid = annoclazzid.underlyingType; } ! } else if (clazz.hasTag(ANNOTATED_TYPE)) { annoclazzid = (JCAnnotatedType) clazz; clazzid = annoclazzid.underlyingType; } else { clazzid = clazz; } JCExpression clazzid1 = clazzid; // The same in fully qualified form if (tree.encl != null) { // We are seeing a qualified new, of the form
*** 1950,1964 **** clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name); EndPosTable endPosTable = this.env.toplevel.endPositions; endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable)); ! if (clazz.hasTag(ANNOTATED_TYPE)) { ! JCAnnotatedType annoType = (JCAnnotatedType) clazz; ! List<JCAnnotation> annos = annoType.annotations; - if (annoType.underlyingType.hasTag(TYPEAPPLY)) { clazzid1 = make.at(tree.pos). TypeApply(clazzid1, ((JCTypeApply) clazz).arguments); } --- 2092,2107 ---- clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name); EndPosTable endPosTable = this.env.toplevel.endPositions; endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable)); ! if (annoclazzid != null) { ! JCAnnotatedType annoType = annoclazzid; ! List<JCAnnotation> annos = annoclazzid.annotations; ! ! if (clazz.hasTag(TYPEAPPLY)) { clazzid1 = make.at(tree.pos). TypeApply(clazzid1, ((JCTypeApply) clazz).arguments); }
*** 1971,1986 **** --- 2114,2136 ---- } clazz = clazzid1; } + annotate.enterStart(); // Attribute clazz expression and store // symbol + type back into the attributed tree. Type clazztype = TreeInfo.isEnumInit(env.tree) ? attribIdentAsEnumType(env, (JCIdent)clazz) : attribType(clazz, env); + annotate.annotateTypeLater(clazz, env, env.info.scope.owner, + tree.pos(), currentLambda, + annotate.newObjCreator(tree.pos), + speculative); + annotate.enterDone(); + annotate.flush(); clazztype = chk.checkDiamond(tree, clazztype); chk.validate(clazz, localEnv); if (tree.encl != null) { // We have to work in this case to store // symbol + type back into the attributed tree.
*** 2005,2015 **** // Attribute constructor arguments. ListBuffer<Type> argtypesBuf = new ListBuffer<>(); int pkind = attribArgs(tree.args, localEnv, argtypesBuf); List<Type> argtypes = argtypesBuf.toList(); ! List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv); // If we have made no mistakes in the class type... if (clazztype.hasTag(CLASS)) { // Enums may not be instantiated except implicitly if (allowEnums && --- 2155,2185 ---- // Attribute constructor arguments. ListBuffer<Type> argtypesBuf = new ListBuffer<>(); int pkind = attribArgs(tree.args, localEnv, argtypesBuf); List<Type> argtypes = argtypesBuf.toList(); ! List<Type> typeargtypes; ! ! // Attribute and annotate the type arguments ! ListBuffer<Type> typeargtypesbuf = new ListBuffer<>(); ! int i = 0; ! ! for (List<JCExpression> l = tree.typeargs; ! l.nonEmpty(); l = l.tail, i++) { ! final JCExpression arg = l.head; ! annotate.enterStart(); ! typeargtypesbuf.append(attribType(arg, localEnv)); ! annotate.annotateTypeLater(arg, localEnv, ! localEnv.info.scope.owner, ! tree.pos(), currentLambda, ! annotate.constructorInvokeTypeArgCreator(i, tree.pos), ! speculative); ! annotate.flush(); ! annotate.enterDone(); ! } ! typeargtypes = ! chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList()); // If we have made no mistakes in the class type... if (clazztype.hasTag(CLASS)) { // Enums may not be instantiated except implicitly if (allowEnums &&
*** 2188,2198 **** try { //create a 'fake' diamond AST node by removing type-argument trees ta.arguments = List.nil(); ResultInfo findDiamondResult = new ResultInfo(VAL, resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt()); ! Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type; Type polyPt = allowPoly ? syms.objectType : clazztype; if (!inferred.isErroneous() && (allowPoly && pt() == Infer.anyPoly ? --- 2358,2371 ---- try { //create a 'fake' diamond AST node by removing type-argument trees ta.arguments = List.nil(); ResultInfo findDiamondResult = new ResultInfo(VAL, resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt()); ! Type inferred = deferredAttr.attribSpeculative(tree, env, ! findDiamondResult, ! currentLambda, ! annotate.newObjCreator(tree.pos)).type; Type polyPt = allowPoly ? syms.objectType : clazztype; if (!inferred.isErroneous() && (allowPoly && pt() == Infer.anyPoly ?
*** 2250,2261 **** --- 2423,2445 ---- public void visitNewArray(JCNewArray tree) { Type owntype = types.createErrorType(tree.type); Env<AttrContext> localEnv = env.dup(tree); Type elemtype; + + for(List<JCAnnotation> dim : tree.dimAnnotations) { + this.attribAnnotationTypes(dim, localEnv); + } + if (tree.elemtype != null) { + annotate.enterStart(); elemtype = attribType(tree.elemtype, localEnv); + annotate.annotateTypeLater(tree, env, env.info.scope.owner, tree.pos(), + currentLambda, annotate.newObjCreator(tree.pos), + speculative); + annotate.enterDone(); + annotate.flush(); chk.validate(tree.elemtype, localEnv); owntype = elemtype; for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) { attribExpr(l.head, localEnv, syms.intType); owntype = new ArrayType(owntype, syms.arrayClass,
*** 2272,2281 **** --- 2456,2466 ---- pt()); } elemtype = types.createErrorType(pt()); } } + if (tree.elems != null) { attribExprs(tree.elems, localEnv, elemtype); owntype = new ArrayType(elemtype, syms.arrayClass, Type.noAnnotations); }
*** 2310,2320 **** localEnv.info.isSerializable = true; } List<Type> explicitParamTypes = null; if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { //attribute lambda parameters ! attribStats(that.params, localEnv); explicitParamTypes = TreeInfo.types(that.params); } Type lambdaType; if (pt() != Type.recoveryType) { --- 2495,2512 ---- localEnv.info.isSerializable = true; } List<Type> explicitParamTypes = null; if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { //attribute lambda parameters ! int i = 0; ! Annotate.PositionCreator oldcreator = creator; ! for (List<JCVariableDecl> l = that.params; ! l.nonEmpty(); l = l.tail, i++) { ! creator = annotate.paramCreator(i); ! attribStat(l.head, that, localEnv); ! } ! creator = oldcreator; explicitParamTypes = TreeInfo.types(that.params); } Type lambdaType; if (pt() != Type.recoveryType) {
*** 2366,2376 **** actuals.tail; params = params.tail; } //attribute lambda parameters ! attribStats(that.params, localEnv); if (arityMismatch) { resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda")); result = that.type = types.createErrorType(currentTarget); return; --- 2558,2568 ---- actuals.tail; params = params.tail; } //attribute lambda parameters ! attribStats(that.params, that, localEnv); if (arityMismatch) { resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda")); result = that.type = types.createErrorType(currentTarget); return;
*** 2391,2404 **** recoveryInfo : new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); localEnv.info.returnResult = bodyResultInfo; if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { ! attribTree(that.getBody(), localEnv, bodyResultInfo); } else { JCBlock body = (JCBlock)that.body; ! attribStats(body.stats, localEnv); } result = check(that, currentTarget, VAL, resultInfo); boolean isSpeculativeRound = --- 2583,2596 ---- recoveryInfo : new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); localEnv.info.returnResult = bodyResultInfo; if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { ! attribTree(that.getBody(), localEnv, that, bodyResultInfo); } else { JCBlock body = (JCBlock)that.body; ! attribStats(body.stats, that, localEnv); } result = check(that, currentTarget, VAL, resultInfo); boolean isSpeculativeRound =
*** 2666,2688 **** --- 2858,2890 ---- return lambdaEnv; } @Override public void visitReference(final JCMemberReference that) { + final boolean isConstructor = that.getName() == names.init; + if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) { if (pt().hasTag(NONE)) { //method reference only allowed in assignment or method invocation/cast context log.error(that.pos(), "unexpected.mref"); } result = that.type = types.createErrorType(pt()); return; } final Env<AttrContext> localEnv = env.dup(that); try { + annotate.enterStart(); //attribute member reference qualifier - if this is a constructor //reference, the expected kind must be a type Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that)); + final Annotate.PositionCreator creator = + isConstructor ? annotate.constructorRefCreator(that.pos) : + annotate.methodRefCreator(that.pos); + annotate.annotateTypeLater(that.expr, localEnv, env.info.scope.owner, that.pos(), + currentLambda, creator, speculative); + annotate.enterDone(); + annotate.flush(); if (that.getMode() == JCMemberReference.ReferenceMode.NEW) { exprType = chk.checkConstructorRefType(that.expr, exprType); if (!exprType.isErroneous() && exprType.isRaw() &&
*** 2708,2718 **** --- 2910,2935 ---- } //attrib type-arguments List<Type> typeargtypes = List.nil(); if (that.typeargs != null) { + annotate.enterStart(); typeargtypes = attribTypes(that.typeargs, localEnv); + + // Annotate type arguments + int i = 0; + for (List<JCExpression> l = that.typeargs; + l.nonEmpty(); l = l.tail, i++) { + final Annotate.PositionCreator typeArgCreator = + isConstructor ? annotate.constructorRefTypeArgCreator(i, that.pos) : + annotate.methodRefTypeArgCreator(i, that.pos); + final JCExpression arg = l.head; + annotate.annotateTypeLater(arg, env, env.info.scope.owner, that.pos(), + currentLambda, typeArgCreator, speculative); + } + annotate.flush(); + annotate.enterDone(); } Type desc; Type currentTarget = pt(); boolean isTargetSerializable =
*** 3081,3091 **** --- 3298,3315 ---- } result = check(tree, owntype, VAL, resultInfo); } public void visitTypeCast(final JCTypeCast tree) { + annotate.enterStart(); Type clazztype = attribType(tree.clazz, env); + annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner, + tree.pos(), currentLambda, + annotate.castCreator(tree.pos), + speculative); + annotate.flush(); + annotate.enterDone(); chk.validate(tree.clazz, env, false); //a fresh environment is required for 292 inference to work properly --- //see Infer.instantiatePolymorphicSignatureInstance() Env<AttrContext> localEnv = env.dup(tree); //should we propagate the target type?
*** 3114,3124 **** --- 3338,3355 ---- } public void visitTypeTest(JCInstanceOf tree) { Type exprtype = chk.checkNullOrRefType( tree.expr.pos(), attribExpr(tree.expr, env)); + annotate.enterStart(); Type clazztype = attribType(tree.clazz, env); + annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner, tree.pos(), + currentLambda, annotate.instanceOfCreator(tree.pos), + speculative); + annotate.flush(); + annotate.enterDone(); + if (!clazztype.hasTag(TYPEVAR)) { clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype); } if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) { log.error(tree.clazz.pos(), "illegal.generic.type.for.instof");
*** 4074,4085 **** public void visitAnnotation(JCAnnotation tree) { Assert.error("should be handled in Annotate"); } public void visitAnnotatedType(JCAnnotatedType tree) { ! Type underlyingType = attribType(tree.getUnderlyingType(), env); this.attribAnnotationTypes(tree.annotations, env); annotateType(tree, tree.annotations); result = tree.type = underlyingType; } --- 4305,4321 ---- public void visitAnnotation(JCAnnotation tree) { Assert.error("should be handled in Annotate"); } + /* This needs to be removed or otherwise changed, as it implicitly + * relies on the annotated types having previously been visited by + * Annotate.TypeAnnotate. + */ public void visitAnnotatedType(JCAnnotatedType tree) { ! Type underlyingType = attribTree(tree.getUnderlyingType(), env, ! resultInfo); this.attribAnnotationTypes(tree.annotations, env); annotateType(tree, tree.annotations); result = tree.type = underlyingType; }
*** 4094,4105 **** --- 4330,4343 ---- } @Override public void run() { List<Attribute.TypeCompound> compounds = fromAnnotations(annotations); Assert.check(annotations.size() == compounds.size()); + if (!tree.type.hasTag(TypeTag.PACKAGE)) { tree.type = tree.type.annotatedType(compounds); } + } }); } private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) { if (annotations.isEmpty()) {
*** 4346,4362 **** isSerializable(c.type) && (c.flags() & Flags.ENUM) == 0 && checkForSerial(c)) { checkSerialVersionUID(tree, c); } - if (allowTypeAnnos) { - // Correctly organize the postions of the type annotations - typeAnnotations.organizeTypeAnnotationsBodies(tree); - - // Check type annotations applicability rules - validateTypeAnnotations(tree, false); - } } // where boolean checkForSerial(ClassSymbol c) { if ((c.flags() & ABSTRACT) == 0) { return true; --- 4584,4593 ----
*** 4426,4435 **** --- 4657,4671 ---- private Type capture(Type type) { return types.capture(type); } + /************************************** + * * + * This code is considered deprecated * + * * + **************************************/ public void validateTypeAnnotations(JCTree tree, boolean sigOnly) { tree.accept(new TypeAnnotationsValidator(sigOnly)); } //where private final class TypeAnnotationsValidator extends TreeScanner {
*** 4476,4486 **** scan(tree.defaultValue); scan(tree.body); } } public void visitVarDef(final JCVariableDecl tree) { - //System.err.println("validateTypeAnnotations.visitVarDef " + tree); if (tree.sym != null && tree.sym.type != null) validateAnnotatedType(tree.vartype, tree.sym.type); scan(tree.mods); scan(tree.vartype); if (!sigOnly) { --- 4712,4721 ----
*** 4519,4529 **** validateAnnotatedType(tree.elemtype, tree.elemtype.type); } super.visitNewArray(tree); } public void visitClassDef(JCClassDecl tree) { - //System.err.println("validateTypeAnnotations.visitClassDef " + tree); if (sigOnly) { scan(tree.mods); scan(tree.typarams); scan(tree.extending); scan(tree.implementing); --- 4754,4763 ----
*** 4548,4558 **** * of the symbol. * Therefore, we need to override each individual location where a type * can occur. */ private void validateAnnotatedType(final JCTree errtree, final Type type) { - //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type); if (type.isPrimitiveOrVoid()) { return; } --- 4782,4791 ----
*** 4588,4604 **** } } else if (enclTr.hasTag(ANNOTATED_TYPE)) { JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr; if (enclTy == null || enclTy.hasTag(NONE)) { if (at.getAnnotations().size() == 1) { ! log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute); } else { ListBuffer<Attribute.Compound> comps = new ListBuffer<>(); for (JCAnnotation an : at.getAnnotations()) { comps.add(an.attribute); } ! log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList()); } repeat = false; } enclTr = at.underlyingType; // enclTy doesn't need to be changed --- 4821,4837 ---- } } else if (enclTr.hasTag(ANNOTATED_TYPE)) { JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr; if (enclTy == null || enclTy.hasTag(NONE)) { if (at.getAnnotations().size() == 1) { ! //log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute); } else { ListBuffer<Attribute.Compound> comps = new ListBuffer<>(); for (JCAnnotation an : at.getAnnotations()) { comps.add(an.attribute); } ! //log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList()); } repeat = false; } enclTr = at.underlyingType; // enclTy doesn't need to be changed
*** 4645,4654 **** --- 4878,4889 ---- // Ensure that no declaration annotations are present. // Note that a tree type might be an AnnotatedType with // empty annotations, if only declaration annotations were given. // This method will raise an error for such a type. for (JCAnnotation ai : annotations) { + Assert.checkNonNull(ai.type); + if (!ai.type.isErroneous() && typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { log.error(ai.pos(), "annotation.type.not.applicable"); } }