< prev index next >

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

Print this page




  32 import javax.lang.model.element.ElementKind;
  33 import javax.tools.JavaFileObject;
  34 
  35 import com.sun.source.tree.CaseTree.CaseKind;
  36 import com.sun.source.tree.IdentifierTree;
  37 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  38 import com.sun.source.tree.MemberSelectTree;
  39 import com.sun.source.tree.TreeVisitor;
  40 import com.sun.source.util.SimpleTreeVisitor;
  41 import com.sun.tools.javac.code.*;
  42 import com.sun.tools.javac.code.Lint.LintCategory;
  43 import com.sun.tools.javac.code.Scope.WriteableScope;
  44 import com.sun.tools.javac.code.Source.Feature;
  45 import com.sun.tools.javac.code.Symbol.*;
  46 import com.sun.tools.javac.code.Type.*;
  47 import com.sun.tools.javac.code.TypeMetadata.Annotations;
  48 import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
  49 import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
  50 import com.sun.tools.javac.comp.Check.CheckContext;
  51 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;

  52 import com.sun.tools.javac.jvm.*;
  53 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
  54 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
  55 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs;
  56 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  57 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  58 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  59 import com.sun.tools.javac.tree.*;
  60 import com.sun.tools.javac.tree.JCTree.*;
  61 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  62 import com.sun.tools.javac.util.*;
  63 import com.sun.tools.javac.util.DefinedBy.Api;
  64 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  65 import com.sun.tools.javac.util.JCDiagnostic.Error;
  66 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  67 import com.sun.tools.javac.util.JCDiagnostic.Warning;
  68 import com.sun.tools.javac.util.List;
  69 
  70 import static com.sun.tools.javac.code.Flags.*;
  71 import static com.sun.tools.javac.code.Flags.ANNOTATION;
  72 import static com.sun.tools.javac.code.Flags.BLOCK;
  73 import static com.sun.tools.javac.code.Kinds.*;
  74 import static com.sun.tools.javac.code.Kinds.Kind.*;
  75 import static com.sun.tools.javac.code.TypeTag.*;
  76 import static com.sun.tools.javac.code.TypeTag.WILDCARD;
  77 import com.sun.tools.javac.comp.Analyzer.AnalyzerMode;


  78 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  79 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  80 import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
  81 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
  82 
  83 /** This is the main context-dependent analysis phase in GJC. It
  84  *  encompasses name resolution, type checking and constant folding as
  85  *  subtasks. Some subtasks involve auxiliary classes.
  86  *  @see Check
  87  *  @see Resolve
  88  *  @see ConstFold
  89  *  @see Infer
  90  *
  91  *  <p><b>This is NOT part of any supported API.
  92  *  If you write code that depends on this, you do so at your own risk.
  93  *  This code and its internal interfaces are subject to change or
  94  *  deletion without notice.</b>
  95  */
  96 public class Attr extends JCTree.Visitor {
  97     protected static final Context.Key<Attr> attrKey = new Context.Key<>();


 103     final Operators operators;
 104     final Infer infer;
 105     final Analyzer analyzer;
 106     final DeferredAttr deferredAttr;
 107     final Check chk;
 108     final Flow flow;
 109     final MemberEnter memberEnter;
 110     final TypeEnter typeEnter;
 111     final TreeMaker make;
 112     final ConstFold cfolder;
 113     final Enter enter;
 114     final Target target;
 115     final Types types;
 116     final JCDiagnostic.Factory diags;
 117     final TypeAnnotations typeAnnotations;
 118     final DeferredLintHandler deferredLintHandler;
 119     final TypeEnvs typeEnvs;
 120     final Dependencies dependencies;
 121     final Annotate annotate;
 122     final ArgumentAttr argumentAttr;

 123 
 124     public static Attr instance(Context context) {
 125         Attr instance = context.get(attrKey);
 126         if (instance == null)
 127             instance = new Attr(context);
 128         return instance;
 129     }
 130 
 131     protected Attr(Context context) {
 132         context.put(attrKey, this);
 133 
 134         names = Names.instance(context);
 135         log = Log.instance(context);
 136         syms = Symtab.instance(context);
 137         rs = Resolve.instance(context);
 138         operators = Operators.instance(context);
 139         chk = Check.instance(context);
 140         flow = Flow.instance(context);
 141         memberEnter = MemberEnter.instance(context);
 142         typeEnter = TypeEnter.instance(context);
 143         make = TreeMaker.instance(context);
 144         enter = Enter.instance(context);
 145         infer = Infer.instance(context);
 146         analyzer = Analyzer.instance(context);
 147         deferredAttr = DeferredAttr.instance(context);
 148         cfolder = ConstFold.instance(context);
 149         target = Target.instance(context);
 150         types = Types.instance(context);
 151         diags = JCDiagnostic.Factory.instance(context);
 152         annotate = Annotate.instance(context);
 153         typeAnnotations = TypeAnnotations.instance(context);
 154         deferredLintHandler = DeferredLintHandler.instance(context);
 155         typeEnvs = TypeEnvs.instance(context);
 156         dependencies = Dependencies.instance(context);
 157         argumentAttr = ArgumentAttr.instance(context);

 158 
 159         Options options = Options.instance(context);
 160 
 161         Source source = Source.instance(context);
 162         allowPoly = Feature.POLY.allowedInSource(source);
 163         allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source);
 164         allowLambda = Feature.LAMBDA.allowedInSource(source);
 165         allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
 166         allowStaticInterfaceMethods = Feature.STATIC_INTERFACE_METHODS.allowedInSource(source);
 167         sourceName = source.name;
 168         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
 169 
 170         statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
 171         varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
 172         unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
 173         methodAttrInfo = new MethodAttrInfo();
 174         unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
 175         unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
 176         recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
 177     }


 278     }
 279 
 280     /** Check that variable can be assigned to.
 281      *  @param pos    The current source code position.
 282      *  @param v      The assigned variable
 283      *  @param base   If the variable is referred to in a Select, the part
 284      *                to the left of the `.', null otherwise.
 285      *  @param env    The current environment.
 286      */
 287     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 288         if (v.name == names._this) {
 289             log.error(pos, Errors.CantAssignValToThis);
 290         } else if ((v.flags() & FINAL) != 0 &&
 291             ((v.flags() & HASINIT) != 0
 292              ||
 293              !((base == null ||
 294                TreeInfo.isThisQualifier(base)) &&
 295                isAssignableAsBlankFinal(v, env)))) {
 296             if (v.isResourceVariable()) { //TWR resource
 297                 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));


 298             } else {
 299                 log.error(pos, Errors.CantAssignValToFinalVar(v));
 300             }
 301         }
 302     }
 303 
 304     /** Does tree represent a static reference to an identifier?
 305      *  It is assumed that tree is either a SELECT or an IDENT.
 306      *  We have to weed out selects from non-type names here.
 307      *  @param tree    The candidate tree.
 308      */
 309     boolean isStaticReference(JCTree tree) {
 310         if (tree.hasTag(SELECT)) {
 311             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 312             if (lsym == null || lsym.kind != TYP) {
 313                 return false;
 314             }
 315         }
 316         return true;
 317     }


 855             if (itype.constValue() != null) {
 856                 return coerce(itype, type).constValue();
 857             } else {
 858                 return null;
 859             }
 860         } finally {
 861             log.useSource(prevSource);
 862             deferredLintHandler.setPos(prevLintPos);
 863         }
 864     }
 865 
 866     /** Attribute type reference in an `extends' or `implements' clause.
 867      *  Supertypes of anonymous inner classes are usually already attributed.
 868      *
 869      *  @param tree              The tree making up the type reference.
 870      *  @param env               The environment current at the reference.
 871      *  @param classExpected     true if only a class is expected here.
 872      *  @param interfaceExpected true if only an interface is expected here.
 873      */
 874     Type attribBase(JCTree tree,

 875                     Env<AttrContext> env,
 876                     boolean classExpected,
 877                     boolean interfaceExpected,
 878                     boolean checkExtensible) {
 879         Type t = tree.type != null ?
 880             tree.type :
 881             attribType(tree, env);
 882         return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
 883     }
 884     Type checkBase(Type t,

 885                    JCTree tree,
 886                    Env<AttrContext> env,
 887                    boolean classExpected,
 888                    boolean interfaceExpected,
 889                    boolean checkExtensible) {
 890         final DiagnosticPosition pos = tree.hasTag(TYPEAPPLY) ?
 891                 (((JCTypeApply) tree).clazz).pos() : tree.pos();
 892         if (t.tsym.isAnonymous()) {
 893             log.error(pos, Errors.CantInheritFromAnon);
 894             return types.createErrorType(t);
 895         }
 896         if (t.isErroneous())
 897             return t;
 898         if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
 899             // check that type variable is already visible
 900             if (t.getUpperBound() == null) {
 901                 log.error(pos, Errors.IllegalForwardRef);
 902                 return types.createErrorType(t);
 903             }
 904         } else {


1072                         log.error(tree.pos(),
1073                                   Errors.DefaultAllowedInIntfAnnotationMember);
1074                 }
1075                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1076                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1077             } else if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1078                 if ((owner.flags() & INTERFACE) != 0) {
1079                     log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1080                 } else {
1081                     log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1082                 }
1083             } else if ((tree.mods.flags & NATIVE) != 0) {
1084                 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1085             } else {
1086                 // Add an implicit super() call unless an explicit call to
1087                 // super(...) or this(...) is given
1088                 // or we are compiling class java.lang.Object.
1089                 if (tree.name == names.init && owner.type != syms.objectType) {
1090                     JCBlock body = tree.body;
1091                     if (body.stats.isEmpty() ||
1092                             !TreeInfo.isSelfCall(body.stats.head)) {
1093                         body.stats = body.stats.
1094                                 prepend(typeEnter.SuperCall(make.at(body.pos),
1095                                         List.nil(),
1096                                         List.nil(),
1097                                         false));
1098                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1099                             (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1100                             TreeInfo.isSuperCall(body.stats.head)) {
1101                         // enum constructors are not allowed to call super
1102                         // directly, so make sure there aren't any super calls
1103                         // in enum constructors, except in the compiler
1104                         // generated one.
1105                         log.error(tree.body.stats.head.pos(),
1106                                   Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1107                     }
1108                 }
1109 
1110                 // Attribute all type annotations in the body
1111                 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
1112                 annotate.flush();
1113 
1114                 // Attribute method body.
1115                 attribStat(tree.body, localEnv);
1116             }
1117 


1302                 } else {
1303                     cs.appendInitTypeAttributes(tas);
1304                 }
1305             }
1306         } else {
1307             // Create a new local environment with a local scope.
1308             Env<AttrContext> localEnv =
1309                 env.dup(tree, env.info.dup(env.info.scope.dup()));
1310             try {
1311                 attribStats(tree.stats, localEnv);
1312             } finally {
1313                 localEnv.info.scope.leave();
1314             }
1315         }
1316         result = null;
1317     }
1318 
1319     public void visitDoLoop(JCDoWhileLoop tree) {
1320         attribStat(tree.body, env.dup(tree));
1321         attribExpr(tree.cond, env, syms.booleanType);






1322         result = null;
1323     }
1324 
1325     public void visitWhileLoop(JCWhileLoop tree) {
1326         attribExpr(tree.cond, env, syms.booleanType);
1327         attribStat(tree.body, env.dup(tree));












1328         result = null;
1329     }
1330 





1331     public void visitForLoop(JCForLoop tree) {
1332         Env<AttrContext> loopEnv =
1333             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1334         try {
1335             attribStats(tree.init, loopEnv);
1336             if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
1337             loopEnv.tree = tree; // before, we were not in loop!
1338             attribStats(tree.step, loopEnv);
1339             attribStat(tree.body, loopEnv);










1340             result = null;
1341         }
1342         finally {
1343             loopEnv.info.scope.leave();






1344         }
1345     }
1346 
1347     public void visitForeachLoop(JCEnhancedForLoop tree) {
1348         Env<AttrContext> loopEnv =
1349             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1350         try {
1351             //the Formal Parameter of a for-each loop is not in the scope when
1352             //attributing the for-each expression; we mimick this by attributing
1353             //the for-each expression first (against original scope).
1354             Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
1355             chk.checkNonVoid(tree.pos(), exprType);
1356             Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
1357             if (elemtype == null) {
1358                 // or perhaps expr implements Iterable<T>?
1359                 Type base = types.asSuper(exprType, syms.iterableType.tsym);
1360                 if (base == null) {
1361                     log.error(tree.expr.pos(),
1362                               Errors.ForeachNotApplicableToType(exprType,
1363                                                                 Fragments.TypeReqArrayOrIterable));


1675 
1676     public void visitConditional(JCConditional tree) {
1677         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
1678 
1679         tree.polyKind = (!allowPoly ||
1680                 pt().hasTag(NONE) && pt() != Type.recoveryType && pt() != Infer.anyPoly ||
1681                 isBooleanOrNumeric(env, tree)) ?
1682                 PolyKind.STANDALONE : PolyKind.POLY;
1683 
1684         if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
1685             //this means we are returning a poly conditional from void-compatible lambda expression
1686             resultInfo.checkContext.report(tree, diags.fragment(Fragments.ConditionalTargetCantBeVoid));
1687             result = tree.type = types.createErrorType(resultInfo.pt);
1688             return;
1689         }
1690 
1691         ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
1692                 unknownExprInfo :
1693                 resultInfo.dup(conditionalContext(resultInfo.checkContext));
1694 
1695         Type truetype = attribTree(tree.truepart, env, condInfo);
1696         Type falsetype = attribTree(tree.falsepart, env, condInfo);


















1697 
1698         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ?
1699                 condType(List.of(tree.truepart.pos(), tree.falsepart.pos()),
1700                          List.of(truetype, falsetype)) : pt();
1701         if (condtype.constValue() != null &&
1702                 truetype.constValue() != null &&
1703                 falsetype.constValue() != null &&
1704                 !owntype.hasTag(NONE)) {
1705             //constant folding
1706             owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
1707         }
1708         result = check(tree, owntype, KindSelector.VAL, resultInfo);
1709     }
1710     //where
1711         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
1712             switch (tree.getTag()) {
1713                 case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
1714                               ((JCLiteral)tree).typetag == BOOLEAN ||
1715                               ((JCLiteral)tree).typetag == BOT;
1716                 case LAMBDA: case REFERENCE: return false;


1831                                  .map(t -> chk.checkNonVoid(posIt.next(), t))
1832                                  .collect(List.collector());
1833 
1834             // both are known to be reference types.  The result is
1835             // lub(thentype,elsetype). This cannot fail, as it will
1836             // always be possible to infer "Object" if nothing better.
1837             return types.lub(condTypes.stream().map(t -> t.baseType()).collect(List.collector()));
1838         }
1839 
1840     final static TypeTag[] primitiveTags = new TypeTag[]{
1841         BYTE,
1842         CHAR,
1843         SHORT,
1844         INT,
1845         LONG,
1846         FLOAT,
1847         DOUBLE,
1848         BOOLEAN,
1849     };
1850 






1851     public void visitIf(JCIf tree) {
1852         attribExpr(tree.cond, env, syms.booleanType);
1853         attribStat(tree.thenpart, env);
1854         if (tree.elsepart != null)
1855             attribStat(tree.elsepart, env);



























1856         chk.checkEmptyIf(tree);












1857         result = null;
1858     }
1859 















1860     public void visitExec(JCExpressionStatement tree) {
1861         //a fresh environment is required for 292 inference to work properly ---
1862         //see Infer.instantiatePolymorphicSignatureInstance()
1863         Env<AttrContext> localEnv = env.dup(tree);
1864         attribExpr(tree.expr, localEnv);
1865         result = null;
1866     }
1867 
1868     public void visitBreak(JCBreak tree) {
1869         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
1870         result = null;
1871     }
1872 
1873     public void visitYield(JCYield tree) {
1874         if (env.info.yieldResult != null) {
1875             attribTree(tree.value, env, env.info.yieldResult);
1876             tree.target = findJumpTarget(tree.pos(), tree.getTag(), names.empty, env);
1877         } else {
1878             log.error(tree.pos(), tree.value.hasTag(PARENS)
1879                     ? Errors.NoSwitchExpressionQualify


2654         //create an environment for attribution of the lambda expression
2655         final Env<AttrContext> localEnv = lambdaEnv(that, env);
2656         boolean needsRecovery =
2657                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
2658         try {
2659             if (needsRecovery && isSerializable(pt())) {
2660                 localEnv.info.isSerializable = true;
2661                 localEnv.info.isLambda = true;
2662             }
2663             List<Type> explicitParamTypes = null;
2664             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
2665                 //attribute lambda parameters
2666                 attribStats(that.params, localEnv);
2667                 explicitParamTypes = TreeInfo.types(that.params);
2668             }
2669 
2670             TargetInfo targetInfo = getTargetInfo(that, resultInfo, explicitParamTypes);
2671             Type currentTarget = targetInfo.target;
2672             Type lambdaType = targetInfo.descriptor;
2673 




2674             if (currentTarget.isErroneous()) {
2675                 result = that.type = currentTarget;
2676                 return;
2677             }
2678 
2679             setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
2680 
2681             if (lambdaType.hasTag(FORALL)) {
2682                 //lambda expression target desc cannot be a generic method
2683                 Fragment msg = Fragments.InvalidGenericLambdaTarget(lambdaType,
2684                                                                     kindName(currentTarget.tsym),
2685                                                                     currentTarget.tsym);
2686                 resultInfo.checkContext.report(that, diags.fragment(msg));
2687                 result = that.type = types.createErrorType(pt());
2688                 return;
2689             }
2690 
2691             if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
2692                 //add param type info in the AST
2693                 List<Type> actuals = lambdaType.getParameterTypes();


3521                 !argtype.isErroneous()) {
3522             owntype = (tree.getTag().isIncOrDecUnaryOp())
3523                 ? tree.arg.type
3524                 : operator.type.getReturnType();
3525             int opc = ((OperatorSymbol)operator).opcode;
3526 
3527             // If the argument is constant, fold it.
3528             if (argtype.constValue() != null) {
3529                 Type ctype = cfolder.fold1(opc, argtype);
3530                 if (ctype != null) {
3531                     owntype = cfolder.coerce(ctype, owntype);
3532                 }
3533             }
3534         }
3535         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3536     }
3537 
3538     public void visitBinary(JCBinary tree) {
3539         // Attribute arguments.
3540         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
3541         Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env));




















3542         // Find operator.
3543         Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
3544         Type owntype = types.createErrorType(tree.type);
3545         if (operator != operators.noOpSymbol &&
3546                 !left.isErroneous() &&
3547                 !right.isErroneous()) {
3548             owntype = operator.type.getReturnType();
3549             int opc = ((OperatorSymbol)operator).opcode;
3550             // If both arguments are constants, fold them.
3551             if (left.constValue() != null && right.constValue() != null) {
3552                 Type ctype = cfolder.fold2(opc, left, right);
3553                 if (ctype != null) {
3554                     owntype = cfolder.coerce(ctype, owntype);
3555                 }
3556             }
3557 
3558             // Check that argument types of a reference ==, != are
3559             // castable to each other, (JLS 15.21).  Note: unboxing
3560             // comparisons will not have an acmp* opc at this point.
3561             if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {


3587                 public boolean compatible(Type found, Type req, Warner warn) {
3588                     return types.isCastable(found, req, warn);
3589                 }
3590             });
3591         } else {
3592             //standalone cast - target-type info is not propagated
3593             castInfo = unknownExprInfo;
3594         }
3595         Type exprtype = attribTree(tree.expr, localEnv, castInfo);
3596         Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
3597         if (exprtype.constValue() != null)
3598             owntype = cfolder.coerce(exprtype, owntype);
3599         result = check(tree, capture(owntype), KindSelector.VAL, resultInfo);
3600         if (!isPoly)
3601             chk.checkRedundantCast(localEnv, tree);
3602     }
3603 
3604     public void visitTypeTest(JCInstanceOf tree) {
3605         Type exprtype = chk.checkNullOrRefType(
3606                 tree.expr.pos(), attribExpr(tree.expr, env));
3607         Type clazztype = attribType(tree.clazz, env);
3608         if (!clazztype.hasTag(TYPEVAR)) {
3609             clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype);
3610         }
3611         if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) {
3612             log.error(tree.clazz.pos(), Errors.IllegalGenericTypeForInstof);
3613             clazztype = types.createErrorType(clazztype);











3614         }
3615         chk.validate(tree.clazz, env, false);
3616         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
3617         result = check(tree, syms.booleanType, KindSelector.VAL, resultInfo);
3618     }
3619 















3620     public void visitIndexed(JCArrayAccess tree) {
3621         Type owntype = types.createErrorType(tree.type);
3622         Type atype = attribExpr(tree.indexed, env);
3623         attribExpr(tree.index, env, syms.intType);
3624         if (types.isArray(atype))
3625             owntype = types.elemtype(atype);
3626         else if (!atype.hasTag(ERROR))
3627             log.error(tree.pos(), Errors.ArrayReqButFound(atype));
3628         if (!pkind().contains(KindSelector.VAL))
3629             owntype = capture(owntype);
3630         result = check(tree, owntype, KindSelector.VAR, resultInfo);
3631     }
3632 
3633     public void visitIdent(JCIdent tree) {
3634         Symbol sym;
3635 
3636         // Find symbol
3637         if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
3638             // If we are looking for a method, the prototype `pt' will be a
3639             // method type with the type of the call's arguments as parameters.


4467         tree.type = result = checkIntersection(tree, tree.bounds);
4468     }
4469 
4470     public void visitTypeParameter(JCTypeParameter tree) {
4471         TypeVar typeVar = (TypeVar) tree.type;
4472 
4473         if (tree.annotations != null && tree.annotations.nonEmpty()) {
4474             annotate.annotateTypeParameterSecondStage(tree, tree.annotations);
4475         }
4476 
4477         if (!typeVar.getUpperBound().isErroneous()) {
4478             //fixup type-parameter bound computed in 'attribTypeVariables'
4479             typeVar.setUpperBound(checkIntersection(tree, tree.bounds));
4480         }
4481     }
4482 
4483     Type checkIntersection(JCTree tree, List<JCExpression> bounds) {
4484         Set<Type> boundSet = new HashSet<>();
4485         if (bounds.nonEmpty()) {
4486             // accept class or interface or typevar as first bound.
4487             bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
4488             boundSet.add(types.erasure(bounds.head.type));
4489             if (bounds.head.type.isErroneous()) {
4490                 return bounds.head.type;
4491             }
4492             else if (bounds.head.type.hasTag(TYPEVAR)) {
4493                 // if first bound was a typevar, do not accept further bounds.
4494                 if (bounds.tail.nonEmpty()) {
4495                     log.error(bounds.tail.head.pos(),
4496                               Errors.TypeVarMayNotBeFollowedByOtherBounds);
4497                     return bounds.head.type;
4498                 }
4499             } else {
4500                 // if first bound was a class or interface, accept only interfaces
4501                 // as further bounds.
4502                 for (JCExpression bound : bounds.tail) {
4503                     bound.type = checkBase(bound.type, bound, env, false, true, false);
4504                     if (bound.type.isErroneous()) {
4505                         bounds = List.of(bound);
4506                     }
4507                     else if (bound.type.hasTag(CLASS)) {
4508                         chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
4509                     }
4510                 }
4511             }
4512         }
4513 
4514         if (bounds.length() == 0) {
4515             return syms.objectType;
4516         } else if (bounds.length() == 1) {
4517             return bounds.head.type;
4518         } else {
4519             Type owntype = types.makeIntersectionType(TreeInfo.types(bounds));
4520             // ... the variable's bound is a class type flagged COMPOUND
4521             // (see comment for TypeVar.bound).
4522             // In this case, generate a class tree that represents the
4523             // bound class, ...


4990                 scan(tree.defaultValue);
4991                 scan(tree.body);
4992             }
4993         }
4994         public void visitVarDef(final JCVariableDecl tree) {
4995             //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
4996             if (tree.sym != null && tree.sym.type != null && !tree.isImplicitlyTyped())
4997                 validateAnnotatedType(tree.vartype, tree.sym.type);
4998             scan(tree.mods);
4999             scan(tree.vartype);
5000             if (!sigOnly) {
5001                 scan(tree.init);
5002             }
5003         }
5004         public void visitTypeCast(JCTypeCast tree) {
5005             if (tree.clazz != null && tree.clazz.type != null)
5006                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5007             super.visitTypeCast(tree);
5008         }
5009         public void visitTypeTest(JCInstanceOf tree) {
5010             if (tree.clazz != null && tree.clazz.type != null)
5011                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5012             super.visitTypeTest(tree);
5013         }
5014         public void visitNewClass(JCNewClass tree) {
5015             if (tree.clazz != null && tree.clazz.type != null) {
5016                 if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
5017                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
5018                             tree.clazz.type.tsym);
5019                 }
5020                 if (tree.def != null) {
5021                     checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
5022                 }
5023 
5024                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5025             }
5026             super.visitNewClass(tree);
5027         }
5028         public void visitNewArray(JCNewArray tree) {
5029             if (tree.elemtype != null && tree.elemtype.type != null) {
5030                 if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
5031                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,


5249         @Override
5250         public void visitMethodDef(JCMethodDecl that) {
5251             initTypeIfNeeded(that);
5252             if (that.sym == null) {
5253                 that.sym = new MethodSymbol(0, that.name, that.type, syms.noSymbol);
5254             }
5255             super.visitMethodDef(that);
5256         }
5257 
5258         @Override
5259         public void visitVarDef(JCVariableDecl that) {
5260             initTypeIfNeeded(that);
5261             if (that.sym == null) {
5262                 that.sym = new VarSymbol(0, that.name, that.type, syms.noSymbol);
5263                 that.sym.adr = 0;
5264             }
5265             if (that.vartype == null) {
5266                 that.vartype = make.at(Position.NOPOS).Erroneous();
5267             }
5268             super.visitVarDef(that);










5269         }
5270 
5271         @Override
5272         public void visitNewClass(JCNewClass that) {
5273             if (that.constructor == null) {
5274                 that.constructor = new MethodSymbol(0, names.init,
5275                         dummyMethodType(), syms.noSymbol);
5276             }
5277             if (that.constructorType == null) {
5278                 that.constructorType = syms.unknownType;
5279             }
5280             super.visitNewClass(that);
5281         }
5282 
5283         @Override
5284         public void visitAssignop(JCAssignOp that) {
5285             if (that.operator == null) {
5286                 that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
5287                         -1, syms.noSymbol);
5288             }




  32 import javax.lang.model.element.ElementKind;
  33 import javax.tools.JavaFileObject;
  34 
  35 import com.sun.source.tree.CaseTree.CaseKind;
  36 import com.sun.source.tree.IdentifierTree;
  37 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  38 import com.sun.source.tree.MemberSelectTree;
  39 import com.sun.source.tree.TreeVisitor;
  40 import com.sun.source.util.SimpleTreeVisitor;
  41 import com.sun.tools.javac.code.*;
  42 import com.sun.tools.javac.code.Lint.LintCategory;
  43 import com.sun.tools.javac.code.Scope.WriteableScope;
  44 import com.sun.tools.javac.code.Source.Feature;
  45 import com.sun.tools.javac.code.Symbol.*;
  46 import com.sun.tools.javac.code.Type.*;
  47 import com.sun.tools.javac.code.TypeMetadata.Annotations;
  48 import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
  49 import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
  50 import com.sun.tools.javac.comp.Check.CheckContext;
  51 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
  52 import com.sun.tools.javac.comp.MatchBindingsComputer.BindingSymbol;
  53 import com.sun.tools.javac.jvm.*;
  54 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
  55 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
  56 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs;
  57 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  58 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  59 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  60 import com.sun.tools.javac.tree.*;
  61 import com.sun.tools.javac.tree.JCTree.*;
  62 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  63 import com.sun.tools.javac.util.*;
  64 import com.sun.tools.javac.util.DefinedBy.Api;
  65 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  66 import com.sun.tools.javac.util.JCDiagnostic.Error;
  67 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  68 import com.sun.tools.javac.util.JCDiagnostic.Warning;
  69 import com.sun.tools.javac.util.List;
  70 
  71 import static com.sun.tools.javac.code.Flags.*;
  72 import static com.sun.tools.javac.code.Flags.ANNOTATION;
  73 import static com.sun.tools.javac.code.Flags.BLOCK;
  74 import static com.sun.tools.javac.code.Kinds.*;
  75 import static com.sun.tools.javac.code.Kinds.Kind.*;
  76 import static com.sun.tools.javac.code.TypeTag.*;
  77 import static com.sun.tools.javac.code.TypeTag.WILDCARD;
  78 import com.sun.tools.javac.comp.Analyzer.AnalyzerMode;
  79 import com.sun.tools.javac.comp.MatchBindingsComputer.BindingSymbol;
  80 import com.sun.tools.javac.tree.JCTree.JCBreak;
  81 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  82 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  83 import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
  84 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
  85 
  86 /** This is the main context-dependent analysis phase in GJC. It
  87  *  encompasses name resolution, type checking and constant folding as
  88  *  subtasks. Some subtasks involve auxiliary classes.
  89  *  @see Check
  90  *  @see Resolve
  91  *  @see ConstFold
  92  *  @see Infer
  93  *
  94  *  <p><b>This is NOT part of any supported API.
  95  *  If you write code that depends on this, you do so at your own risk.
  96  *  This code and its internal interfaces are subject to change or
  97  *  deletion without notice.</b>
  98  */
  99 public class Attr extends JCTree.Visitor {
 100     protected static final Context.Key<Attr> attrKey = new Context.Key<>();


 106     final Operators operators;
 107     final Infer infer;
 108     final Analyzer analyzer;
 109     final DeferredAttr deferredAttr;
 110     final Check chk;
 111     final Flow flow;
 112     final MemberEnter memberEnter;
 113     final TypeEnter typeEnter;
 114     final TreeMaker make;
 115     final ConstFold cfolder;
 116     final Enter enter;
 117     final Target target;
 118     final Types types;
 119     final JCDiagnostic.Factory diags;
 120     final TypeAnnotations typeAnnotations;
 121     final DeferredLintHandler deferredLintHandler;
 122     final TypeEnvs typeEnvs;
 123     final Dependencies dependencies;
 124     final Annotate annotate;
 125     final ArgumentAttr argumentAttr;
 126     final MatchBindingsComputer matchBindingsComputer;
 127 
 128     public static Attr instance(Context context) {
 129         Attr instance = context.get(attrKey);
 130         if (instance == null)
 131             instance = new Attr(context);
 132         return instance;
 133     }
 134 
 135     protected Attr(Context context) {
 136         context.put(attrKey, this);
 137 
 138         names = Names.instance(context);
 139         log = Log.instance(context);
 140         syms = Symtab.instance(context);
 141         rs = Resolve.instance(context);
 142         operators = Operators.instance(context);
 143         chk = Check.instance(context);
 144         flow = Flow.instance(context);
 145         memberEnter = MemberEnter.instance(context);
 146         typeEnter = TypeEnter.instance(context);
 147         make = TreeMaker.instance(context);
 148         enter = Enter.instance(context);
 149         infer = Infer.instance(context);
 150         analyzer = Analyzer.instance(context);
 151         deferredAttr = DeferredAttr.instance(context);
 152         cfolder = ConstFold.instance(context);
 153         target = Target.instance(context);
 154         types = Types.instance(context);
 155         diags = JCDiagnostic.Factory.instance(context);
 156         annotate = Annotate.instance(context);
 157         typeAnnotations = TypeAnnotations.instance(context);
 158         deferredLintHandler = DeferredLintHandler.instance(context);
 159         typeEnvs = TypeEnvs.instance(context);
 160         dependencies = Dependencies.instance(context);
 161         argumentAttr = ArgumentAttr.instance(context);
 162         matchBindingsComputer = MatchBindingsComputer.instance(context);
 163 
 164         Options options = Options.instance(context);
 165 
 166         Source source = Source.instance(context);
 167         allowPoly = Feature.POLY.allowedInSource(source);
 168         allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source);
 169         allowLambda = Feature.LAMBDA.allowedInSource(source);
 170         allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
 171         allowStaticInterfaceMethods = Feature.STATIC_INTERFACE_METHODS.allowedInSource(source);
 172         sourceName = source.name;
 173         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
 174 
 175         statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
 176         varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
 177         unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
 178         methodAttrInfo = new MethodAttrInfo();
 179         unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
 180         unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
 181         recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
 182     }


 283     }
 284 
 285     /** Check that variable can be assigned to.
 286      *  @param pos    The current source code position.
 287      *  @param v      The assigned variable
 288      *  @param base   If the variable is referred to in a Select, the part
 289      *                to the left of the `.', null otherwise.
 290      *  @param env    The current environment.
 291      */
 292     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 293         if (v.name == names._this) {
 294             log.error(pos, Errors.CantAssignValToThis);
 295         } else if ((v.flags() & FINAL) != 0 &&
 296             ((v.flags() & HASINIT) != 0
 297              ||
 298              !((base == null ||
 299                TreeInfo.isThisQualifier(base)) &&
 300                isAssignableAsBlankFinal(v, env)))) {
 301             if (v.isResourceVariable()) { //TWR resource
 302                 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
 303             } else if ((v.flags() & MATCH_BINDING) != 0) {
 304                 log.error(pos, Errors.PatternBindingMayNotBeAssigned(v));
 305             } else {
 306                 log.error(pos, Errors.CantAssignValToFinalVar(v));
 307             }
 308         }
 309     }
 310 
 311     /** Does tree represent a static reference to an identifier?
 312      *  It is assumed that tree is either a SELECT or an IDENT.
 313      *  We have to weed out selects from non-type names here.
 314      *  @param tree    The candidate tree.
 315      */
 316     boolean isStaticReference(JCTree tree) {
 317         if (tree.hasTag(SELECT)) {
 318             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 319             if (lsym == null || lsym.kind != TYP) {
 320                 return false;
 321             }
 322         }
 323         return true;
 324     }


 862             if (itype.constValue() != null) {
 863                 return coerce(itype, type).constValue();
 864             } else {
 865                 return null;
 866             }
 867         } finally {
 868             log.useSource(prevSource);
 869             deferredLintHandler.setPos(prevLintPos);
 870         }
 871     }
 872 
 873     /** Attribute type reference in an `extends' or `implements' clause.
 874      *  Supertypes of anonymous inner classes are usually already attributed.
 875      *
 876      *  @param tree              The tree making up the type reference.
 877      *  @param env               The environment current at the reference.
 878      *  @param classExpected     true if only a class is expected here.
 879      *  @param interfaceExpected true if only an interface is expected here.
 880      */
 881     Type attribBase(JCTree tree,
 882                     ClassSymbol subType,
 883                     Env<AttrContext> env,
 884                     boolean classExpected,
 885                     boolean interfaceExpected,
 886                     boolean checkExtensible) {
 887         Type t = tree.type != null ?
 888             tree.type :
 889             attribType(tree, env);
 890         return checkBase(t, subType, tree, env, classExpected, interfaceExpected, checkExtensible);
 891     }
 892     Type checkBase(Type t,
 893                    ClassSymbol subType,
 894                    JCTree tree,
 895                    Env<AttrContext> env,
 896                    boolean classExpected,
 897                    boolean interfaceExpected,
 898                    boolean checkExtensible) {
 899         final DiagnosticPosition pos = tree.hasTag(TYPEAPPLY) ?
 900                 (((JCTypeApply) tree).clazz).pos() : tree.pos();
 901         if (t.tsym.isAnonymous()) {
 902             log.error(pos, Errors.CantInheritFromAnon);
 903             return types.createErrorType(t);
 904         }
 905         if (t.isErroneous())
 906             return t;
 907         if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
 908             // check that type variable is already visible
 909             if (t.getUpperBound() == null) {
 910                 log.error(pos, Errors.IllegalForwardRef);
 911                 return types.createErrorType(t);
 912             }
 913         } else {


1081                         log.error(tree.pos(),
1082                                   Errors.DefaultAllowedInIntfAnnotationMember);
1083                 }
1084                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1085                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1086             } else if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1087                 if ((owner.flags() & INTERFACE) != 0) {
1088                     log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1089                 } else {
1090                     log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1091                 }
1092             } else if ((tree.mods.flags & NATIVE) != 0) {
1093                 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1094             } else {
1095                 // Add an implicit super() call unless an explicit call to
1096                 // super(...) or this(...) is given
1097                 // or we are compiling class java.lang.Object.
1098                 if (tree.name == names.init && owner.type != syms.objectType) {
1099                     JCBlock body = tree.body;
1100                     if (body.stats.isEmpty() ||
1101                             TreeInfo.getConstructorInvocationName(body.stats, names,
1102                                     (env.enclClass.sym.flags() & RECORD) != 0) == names.empty) {
1103                         JCStatement supCall = make.at(body.pos).Exec(make.Apply(List.nil(),
1104                                 make.Ident(names._super), make.Idents(List.nil())));
1105                         body.stats = body.stats.prepend(supCall);

1106                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1107                             (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1108                             TreeInfo.isSuperCall(body.stats.head)) {
1109                         // enum constructors are not allowed to call super
1110                         // directly, so make sure there aren't any super calls
1111                         // in enum constructors, except in the compiler
1112                         // generated one.
1113                         log.error(tree.body.stats.head.pos(),
1114                                   Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1115                     }
1116                 }
1117 
1118                 // Attribute all type annotations in the body
1119                 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
1120                 annotate.flush();
1121 
1122                 // Attribute method body.
1123                 attribStat(tree.body, localEnv);
1124             }
1125 


1310                 } else {
1311                     cs.appendInitTypeAttributes(tas);
1312                 }
1313             }
1314         } else {
1315             // Create a new local environment with a local scope.
1316             Env<AttrContext> localEnv =
1317                 env.dup(tree, env.info.dup(env.info.scope.dup()));
1318             try {
1319                 attribStats(tree.stats, localEnv);
1320             } finally {
1321                 localEnv.info.scope.leave();
1322             }
1323         }
1324         result = null;
1325     }
1326 
1327     public void visitDoLoop(JCDoWhileLoop tree) {
1328         attribStat(tree.body, env.dup(tree));
1329         attribExpr(tree.cond, env, syms.booleanType);
1330         if (!breaksOutOf(tree, tree.body)) {
1331             List<BindingSymbol> bindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
1332 
1333             bindings.forEach(env.info.scope::enter);
1334             bindings.forEach(BindingSymbol::preserveBinding);
1335         }
1336         result = null;
1337     }
1338 
1339     public void visitWhileLoop(JCWhileLoop tree) {
1340         attribExpr(tree.cond, env, syms.booleanType);
1341         // include x.T in while's body
1342         Env<AttrContext> whileEnv = bindingEnv(env, matchBindingsComputer.getMatchBindings(tree.cond, true));
1343         try {
1344             attribStat(tree.body, whileEnv.dup(tree));
1345         } finally {
1346             whileEnv.info.scope.leave();
1347         }
1348         if (!breaksOutOf(tree, tree.body)) {
1349             List<BindingSymbol> bindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
1350 
1351             bindings.forEach(env.info.scope::enter);
1352             bindings.forEach(BindingSymbol::preserveBinding);
1353         }
1354         result = null;
1355     }
1356 
1357     private boolean breaksOutOf(JCTree loop, JCTree body) {
1358         preFlow(body);
1359         return flow.breaksOutOf(env, loop, body, make);
1360     }
1361 
1362     public void visitForLoop(JCForLoop tree) {
1363         Env<AttrContext> loopEnv =
1364             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1365         try {
1366             attribStats(tree.init, loopEnv);
1367             List<BindingSymbol> matchBindings = List.nil();
1368             if (tree.cond != null) {
1369                 attribExpr(tree.cond, loopEnv, syms.booleanType);
1370                 // include x.T in the evaluation scopes of body & step.
1371                 matchBindings = matchBindingsComputer.getMatchBindings(tree.cond, true);
1372             }
1373             Env<AttrContext> bodyEnv = bindingEnv(loopEnv, matchBindings);
1374             try {
1375                 bodyEnv.tree = tree; // before, we were not in loop!
1376                 attribStats(tree.step, bodyEnv);
1377                 attribStat(tree.body, bodyEnv);
1378             } finally {
1379                 bodyEnv.info.scope.leave();
1380             }
1381             result = null;
1382         }
1383         finally {
1384             loopEnv.info.scope.leave(); // all injected match bindings vanish here.
1385         }
1386         if (!breaksOutOf(tree, tree.body)) {
1387             List<BindingSymbol> bindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
1388 
1389             bindings.forEach(env.info.scope::enter);
1390             bindings.forEach(BindingSymbol::preserveBinding);
1391         }
1392     }
1393 
1394     public void visitForeachLoop(JCEnhancedForLoop tree) {
1395         Env<AttrContext> loopEnv =
1396             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1397         try {
1398             //the Formal Parameter of a for-each loop is not in the scope when
1399             //attributing the for-each expression; we mimick this by attributing
1400             //the for-each expression first (against original scope).
1401             Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
1402             chk.checkNonVoid(tree.pos(), exprType);
1403             Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
1404             if (elemtype == null) {
1405                 // or perhaps expr implements Iterable<T>?
1406                 Type base = types.asSuper(exprType, syms.iterableType.tsym);
1407                 if (base == null) {
1408                     log.error(tree.expr.pos(),
1409                               Errors.ForeachNotApplicableToType(exprType,
1410                                                                 Fragments.TypeReqArrayOrIterable));


1722 
1723     public void visitConditional(JCConditional tree) {
1724         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
1725 
1726         tree.polyKind = (!allowPoly ||
1727                 pt().hasTag(NONE) && pt() != Type.recoveryType && pt() != Infer.anyPoly ||
1728                 isBooleanOrNumeric(env, tree)) ?
1729                 PolyKind.STANDALONE : PolyKind.POLY;
1730 
1731         if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
1732             //this means we are returning a poly conditional from void-compatible lambda expression
1733             resultInfo.checkContext.report(tree, diags.fragment(Fragments.ConditionalTargetCantBeVoid));
1734             result = tree.type = types.createErrorType(resultInfo.pt);
1735             return;
1736         }
1737 
1738         ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
1739                 unknownExprInfo :
1740                 resultInfo.dup(conditionalContext(resultInfo.checkContext));
1741 
1742         /*  if e = "x ? y : z", then:
1743                 include x.T in y
1744                 include x.F in z
1745         */
1746 
1747         Type truetype;
1748         Env<AttrContext> trueEnv = bindingEnv(env, matchBindingsComputer.getMatchBindings(tree.cond, true));
1749         try {
1750             truetype = attribTree(tree.truepart, trueEnv, condInfo);
1751         } finally {
1752             trueEnv.info.scope.leave();
1753         }
1754 
1755         Type falsetype;
1756         Env<AttrContext> falseEnv = bindingEnv(env, matchBindingsComputer.getMatchBindings(tree.cond, false));
1757         try {
1758             falsetype = attribTree(tree.falsepart, falseEnv, condInfo);
1759         } finally {
1760             falseEnv.info.scope.leave();
1761         }
1762 
1763         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ?
1764                 condType(List.of(tree.truepart.pos(), tree.falsepart.pos()),
1765                          List.of(truetype, falsetype)) : pt();
1766         if (condtype.constValue() != null &&
1767                 truetype.constValue() != null &&
1768                 falsetype.constValue() != null &&
1769                 !owntype.hasTag(NONE)) {
1770             //constant folding
1771             owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
1772         }
1773         result = check(tree, owntype, KindSelector.VAL, resultInfo);
1774     }
1775     //where
1776         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
1777             switch (tree.getTag()) {
1778                 case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
1779                               ((JCLiteral)tree).typetag == BOOLEAN ||
1780                               ((JCLiteral)tree).typetag == BOT;
1781                 case LAMBDA: case REFERENCE: return false;


1896                                  .map(t -> chk.checkNonVoid(posIt.next(), t))
1897                                  .collect(List.collector());
1898 
1899             // both are known to be reference types.  The result is
1900             // lub(thentype,elsetype). This cannot fail, as it will
1901             // always be possible to infer "Object" if nothing better.
1902             return types.lub(condTypes.stream().map(t -> t.baseType()).collect(List.collector()));
1903         }
1904 
1905     final static TypeTag[] primitiveTags = new TypeTag[]{
1906         BYTE,
1907         CHAR,
1908         SHORT,
1909         INT,
1910         LONG,
1911         FLOAT,
1912         DOUBLE,
1913         BOOLEAN,
1914     };
1915 
1916     Env<AttrContext> bindingEnv(Env<AttrContext> env, List<BindingSymbol> bindings) {
1917         Env<AttrContext> env1 = env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1918         bindings.forEach(env1.info.scope::enter);
1919         return env1;
1920     }
1921 
1922     public void visitIf(JCIf tree) {
1923         attribExpr(tree.cond, env, syms.booleanType);
1924 
1925         // if (x) { y } [ else z ] include x.T in y; include x.F in z
1926 
1927         List<BindingSymbol> thenBindings = matchBindingsComputer.getMatchBindings(tree.cond, true);
1928         Env<AttrContext> thenEnv = bindingEnv(env, thenBindings);
1929 
1930         try {
1931             attribStat(tree.thenpart, thenEnv);
1932         } finally {
1933             thenEnv.info.scope.leave();
1934         }
1935 
1936         preFlow(tree.thenpart);
1937         boolean aliveAfterThen = flow.aliveAfter(env, tree.thenpart, make);
1938         boolean aliveAfterElse;
1939         List<BindingSymbol> elseBindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
1940 
1941         if (tree.elsepart != null) {
1942             Env<AttrContext> elseEnv = bindingEnv(env, elseBindings);
1943             try {
1944                 attribStat(tree.elsepart, elseEnv);
1945             } finally {
1946                 elseEnv.info.scope.leave();
1947             }
1948             preFlow(tree.elsepart);
1949             aliveAfterElse = flow.aliveAfter(env, tree.elsepart, make);
1950         } else {
1951             aliveAfterElse = true;
1952         }
1953 
1954         chk.checkEmptyIf(tree);
1955 
1956         List<BindingSymbol> afterIfBindings = List.nil();
1957 
1958         if (aliveAfterThen && !aliveAfterElse) {
1959             afterIfBindings = thenBindings;
1960         } else if (aliveAfterElse && !aliveAfterThen) {
1961             afterIfBindings = elseBindings;
1962         }
1963 
1964         afterIfBindings.forEach(env.info.scope::enter);
1965         afterIfBindings.forEach(BindingSymbol::preserveBinding);
1966 
1967         result = null;
1968     }
1969 
1970         void preFlow(JCTree tree) {
1971             new PostAttrAnalyzer() {
1972                 @Override
1973                 public void scan(JCTree tree) {
1974                     if (tree == null ||
1975                             (tree.type != null &&
1976                             tree.type == Type.stuckType)) {
1977                         //don't touch stuck expressions!
1978                         return;
1979                     }
1980                     super.scan(tree);
1981                 }
1982             }.scan(tree);
1983         }
1984 
1985     public void visitExec(JCExpressionStatement tree) {
1986         //a fresh environment is required for 292 inference to work properly ---
1987         //see Infer.instantiatePolymorphicSignatureInstance()
1988         Env<AttrContext> localEnv = env.dup(tree);
1989         attribExpr(tree.expr, localEnv);
1990         result = null;
1991     }
1992 
1993     public void visitBreak(JCBreak tree) {
1994         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
1995         result = null;
1996     }
1997 
1998     public void visitYield(JCYield tree) {
1999         if (env.info.yieldResult != null) {
2000             attribTree(tree.value, env, env.info.yieldResult);
2001             tree.target = findJumpTarget(tree.pos(), tree.getTag(), names.empty, env);
2002         } else {
2003             log.error(tree.pos(), tree.value.hasTag(PARENS)
2004                     ? Errors.NoSwitchExpressionQualify


2779         //create an environment for attribution of the lambda expression
2780         final Env<AttrContext> localEnv = lambdaEnv(that, env);
2781         boolean needsRecovery =
2782                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
2783         try {
2784             if (needsRecovery && isSerializable(pt())) {
2785                 localEnv.info.isSerializable = true;
2786                 localEnv.info.isLambda = true;
2787             }
2788             List<Type> explicitParamTypes = null;
2789             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
2790                 //attribute lambda parameters
2791                 attribStats(that.params, localEnv);
2792                 explicitParamTypes = TreeInfo.types(that.params);
2793             }
2794 
2795             TargetInfo targetInfo = getTargetInfo(that, resultInfo, explicitParamTypes);
2796             Type currentTarget = targetInfo.target;
2797             Type lambdaType = targetInfo.descriptor;
2798 
2799             if (currentTarget.tsym != null && ((ClassSymbol)currentTarget.tsym).isSealed()) {
2800                 log.error(that, Errors.CantInheritFromSealed(currentTarget.tsym));
2801             }
2802 
2803             if (currentTarget.isErroneous()) {
2804                 result = that.type = currentTarget;
2805                 return;
2806             }
2807 
2808             setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
2809 
2810             if (lambdaType.hasTag(FORALL)) {
2811                 //lambda expression target desc cannot be a generic method
2812                 Fragment msg = Fragments.InvalidGenericLambdaTarget(lambdaType,
2813                                                                     kindName(currentTarget.tsym),
2814                                                                     currentTarget.tsym);
2815                 resultInfo.checkContext.report(that, diags.fragment(msg));
2816                 result = that.type = types.createErrorType(pt());
2817                 return;
2818             }
2819 
2820             if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
2821                 //add param type info in the AST
2822                 List<Type> actuals = lambdaType.getParameterTypes();


3650                 !argtype.isErroneous()) {
3651             owntype = (tree.getTag().isIncOrDecUnaryOp())
3652                 ? tree.arg.type
3653                 : operator.type.getReturnType();
3654             int opc = ((OperatorSymbol)operator).opcode;
3655 
3656             // If the argument is constant, fold it.
3657             if (argtype.constValue() != null) {
3658                 Type ctype = cfolder.fold1(opc, argtype);
3659                 if (ctype != null) {
3660                     owntype = cfolder.coerce(ctype, owntype);
3661                 }
3662             }
3663         }
3664         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3665     }
3666 
3667     public void visitBinary(JCBinary tree) {
3668         // Attribute arguments.
3669         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
3670         // If e = "x && y", then, include x.T in y;  If e = "x || y", then, include x.F in y
3671         List<BindingSymbol> matchBindings;
3672         switch (tree.getTag()) {
3673             case AND:
3674                 matchBindings = matchBindingsComputer.getMatchBindings(tree.lhs, true);
3675                 break;
3676             case OR:
3677                 matchBindings = matchBindingsComputer.getMatchBindings(tree.lhs, false);
3678                 break;
3679             default:
3680                 matchBindings = List.nil();
3681                 break;
3682         }
3683         Env<AttrContext> rhsEnv = bindingEnv(env, matchBindings);
3684         Type right;
3685         try {
3686             right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, rhsEnv));
3687         } finally {
3688             rhsEnv.info.scope.leave();
3689         }
3690 
3691         // Find operator.
3692         Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
3693         Type owntype = types.createErrorType(tree.type);
3694         if (operator != operators.noOpSymbol &&
3695                 !left.isErroneous() &&
3696                 !right.isErroneous()) {
3697             owntype = operator.type.getReturnType();
3698             int opc = ((OperatorSymbol)operator).opcode;
3699             // If both arguments are constants, fold them.
3700             if (left.constValue() != null && right.constValue() != null) {
3701                 Type ctype = cfolder.fold2(opc, left, right);
3702                 if (ctype != null) {
3703                     owntype = cfolder.coerce(ctype, owntype);
3704                 }
3705             }
3706 
3707             // Check that argument types of a reference ==, != are
3708             // castable to each other, (JLS 15.21).  Note: unboxing
3709             // comparisons will not have an acmp* opc at this point.
3710             if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {


3736                 public boolean compatible(Type found, Type req, Warner warn) {
3737                     return types.isCastable(found, req, warn);
3738                 }
3739             });
3740         } else {
3741             //standalone cast - target-type info is not propagated
3742             castInfo = unknownExprInfo;
3743         }
3744         Type exprtype = attribTree(tree.expr, localEnv, castInfo);
3745         Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
3746         if (exprtype.constValue() != null)
3747             owntype = cfolder.coerce(exprtype, owntype);
3748         result = check(tree, capture(owntype), KindSelector.VAL, resultInfo);
3749         if (!isPoly)
3750             chk.checkRedundantCast(localEnv, tree);
3751     }
3752 
3753     public void visitTypeTest(JCInstanceOf tree) {
3754         Type exprtype = chk.checkNullOrRefType(
3755                 tree.expr.pos(), attribExpr(tree.expr, env));
3756         Type clazztype;
3757         if (tree.pattern.getTag() == BINDINGPATTERN) {
3758             attribTree(tree.pattern, env, unknownExprInfo);
3759             clazztype = tree.pattern.type;
3760             if (!clazztype.hasTag(TYPEVAR)) {
3761                 JCBindingPattern pattern = (JCBindingPattern) tree.pattern;
3762                 clazztype = chk.checkClassOrArrayType(pattern.vartype.pos(), clazztype);
3763             }
3764         } else {
3765             clazztype = attribType(tree.pattern, env);
3766             if (!clazztype.hasTag(TYPEVAR)) {
3767                 clazztype = chk.checkClassOrArrayType(tree.pattern.pos(), clazztype);
3768             }
3769             if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) {
3770                 log.error(tree.pattern.pos(), Errors.IllegalGenericTypeForInstof);
3771                 clazztype = types.createErrorType(clazztype);
3772             }
3773             chk.validate(tree.pattern, env, false);
3774         }

3775         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
3776         result = check(tree, syms.booleanType, KindSelector.VAL, resultInfo);
3777     }
3778 
3779     public void visitBindingPattern(JCBindingPattern tree) {
3780         if (tree.vartype != null) {
3781             ResultInfo varInfo = new ResultInfo(KindSelector.TYP, resultInfo.pt, resultInfo.checkContext);
3782             tree.type = attribTree(tree.vartype, env, varInfo);
3783         } else {
3784             tree.type = resultInfo.pt;
3785         }
3786         VarSymbol v = tree.symbol = new BindingSymbol(tree.name, tree.vartype != null ? tree.vartype.type : (tree.type.hasTag(BOT) ? syms.objectType : tree.type), env.info.scope.owner);
3787         if (chk.checkUnique(tree.pos(), v, env.info.scope)) {
3788             chk.checkTransparentVar(tree.pos(), v, env.info.scope);
3789             // env.info.scope.enter(v); // we inject into scopes expressly at various points.
3790         }
3791         result = tree.type;
3792     }
3793 
3794     public void visitIndexed(JCArrayAccess tree) {
3795         Type owntype = types.createErrorType(tree.type);
3796         Type atype = attribExpr(tree.indexed, env);
3797         attribExpr(tree.index, env, syms.intType);
3798         if (types.isArray(atype))
3799             owntype = types.elemtype(atype);
3800         else if (!atype.hasTag(ERROR))
3801             log.error(tree.pos(), Errors.ArrayReqButFound(atype));
3802         if (!pkind().contains(KindSelector.VAL))
3803             owntype = capture(owntype);
3804         result = check(tree, owntype, KindSelector.VAR, resultInfo);
3805     }
3806 
3807     public void visitIdent(JCIdent tree) {
3808         Symbol sym;
3809 
3810         // Find symbol
3811         if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
3812             // If we are looking for a method, the prototype `pt' will be a
3813             // method type with the type of the call's arguments as parameters.


4641         tree.type = result = checkIntersection(tree, tree.bounds);
4642     }
4643 
4644     public void visitTypeParameter(JCTypeParameter tree) {
4645         TypeVar typeVar = (TypeVar) tree.type;
4646 
4647         if (tree.annotations != null && tree.annotations.nonEmpty()) {
4648             annotate.annotateTypeParameterSecondStage(tree, tree.annotations);
4649         }
4650 
4651         if (!typeVar.getUpperBound().isErroneous()) {
4652             //fixup type-parameter bound computed in 'attribTypeVariables'
4653             typeVar.setUpperBound(checkIntersection(tree, tree.bounds));
4654         }
4655     }
4656 
4657     Type checkIntersection(JCTree tree, List<JCExpression> bounds) {
4658         Set<Type> boundSet = new HashSet<>();
4659         if (bounds.nonEmpty()) {
4660             // accept class or interface or typevar as first bound.
4661             bounds.head.type = checkBase(bounds.head.type, syms.unknownSymbol, bounds.head, env, false, false, false);
4662             boundSet.add(types.erasure(bounds.head.type));
4663             if (bounds.head.type.isErroneous()) {
4664                 return bounds.head.type;
4665             }
4666             else if (bounds.head.type.hasTag(TYPEVAR)) {
4667                 // if first bound was a typevar, do not accept further bounds.
4668                 if (bounds.tail.nonEmpty()) {
4669                     log.error(bounds.tail.head.pos(),
4670                               Errors.TypeVarMayNotBeFollowedByOtherBounds);
4671                     return bounds.head.type;
4672                 }
4673             } else {
4674                 // if first bound was a class or interface, accept only interfaces
4675                 // as further bounds.
4676                 for (JCExpression bound : bounds.tail) {
4677                     bound.type = checkBase(bound.type, syms.unknownSymbol, bound, env, false, true, false);
4678                     if (bound.type.isErroneous()) {
4679                         bounds = List.of(bound);
4680                     }
4681                     else if (bound.type.hasTag(CLASS)) {
4682                         chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
4683                     }
4684                 }
4685             }
4686         }
4687 
4688         if (bounds.length() == 0) {
4689             return syms.objectType;
4690         } else if (bounds.length() == 1) {
4691             return bounds.head.type;
4692         } else {
4693             Type owntype = types.makeIntersectionType(TreeInfo.types(bounds));
4694             // ... the variable's bound is a class type flagged COMPOUND
4695             // (see comment for TypeVar.bound).
4696             // In this case, generate a class tree that represents the
4697             // bound class, ...


5164                 scan(tree.defaultValue);
5165                 scan(tree.body);
5166             }
5167         }
5168         public void visitVarDef(final JCVariableDecl tree) {
5169             //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
5170             if (tree.sym != null && tree.sym.type != null && !tree.isImplicitlyTyped())
5171                 validateAnnotatedType(tree.vartype, tree.sym.type);
5172             scan(tree.mods);
5173             scan(tree.vartype);
5174             if (!sigOnly) {
5175                 scan(tree.init);
5176             }
5177         }
5178         public void visitTypeCast(JCTypeCast tree) {
5179             if (tree.clazz != null && tree.clazz.type != null)
5180                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5181             super.visitTypeCast(tree);
5182         }
5183         public void visitTypeTest(JCInstanceOf tree) {
5184             if (tree.pattern != null && !(tree.pattern instanceof JCPattern) && tree.pattern.type != null)
5185                 validateAnnotatedType(tree.pattern, tree.pattern.type);
5186             super.visitTypeTest(tree);
5187         }
5188         public void visitNewClass(JCNewClass tree) {
5189             if (tree.clazz != null && tree.clazz.type != null) {
5190                 if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
5191                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
5192                             tree.clazz.type.tsym);
5193                 }
5194                 if (tree.def != null) {
5195                     checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
5196                 }
5197 
5198                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5199             }
5200             super.visitNewClass(tree);
5201         }
5202         public void visitNewArray(JCNewArray tree) {
5203             if (tree.elemtype != null && tree.elemtype.type != null) {
5204                 if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
5205                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,


5423         @Override
5424         public void visitMethodDef(JCMethodDecl that) {
5425             initTypeIfNeeded(that);
5426             if (that.sym == null) {
5427                 that.sym = new MethodSymbol(0, that.name, that.type, syms.noSymbol);
5428             }
5429             super.visitMethodDef(that);
5430         }
5431 
5432         @Override
5433         public void visitVarDef(JCVariableDecl that) {
5434             initTypeIfNeeded(that);
5435             if (that.sym == null) {
5436                 that.sym = new VarSymbol(0, that.name, that.type, syms.noSymbol);
5437                 that.sym.adr = 0;
5438             }
5439             if (that.vartype == null) {
5440                 that.vartype = make.at(Position.NOPOS).Erroneous();
5441             }
5442             super.visitVarDef(that);
5443         }
5444 
5445         @Override
5446         public void visitBindingPattern(JCBindingPattern that) {
5447             //initTypeIfNeeded(that);
5448             if (that.symbol == null) {
5449                 that.symbol = new BindingSymbol(that.name, that.type, syms.noSymbol);
5450                 that.symbol.adr = 0;
5451             }
5452             super.visitBindingPattern(that);
5453         }
5454 
5455         @Override
5456         public void visitNewClass(JCNewClass that) {
5457             if (that.constructor == null) {
5458                 that.constructor = new MethodSymbol(0, names.init,
5459                         dummyMethodType(), syms.noSymbol);
5460             }
5461             if (that.constructorType == null) {
5462                 that.constructorType = syms.unknownType;
5463             }
5464             super.visitNewClass(that);
5465         }
5466 
5467         @Override
5468         public void visitAssignop(JCAssignOp that) {
5469             if (that.operator == null) {
5470                 that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
5471                         -1, syms.noSymbol);
5472             }


< prev index next >