src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
author Dusan Balek <dbalek@netbeans.org>
Fri, 25 Aug 2017 16:36:44 +0200
changeset 5960 9b58471932b6
parent 5954 f453b3a76796
permissions -rw-r--r--
Issue #271310 - NullPointerException at com.sun.tools.javac.comp.Attr.enclosingInitEnv - fixed.
duke@0
     1
/*
vromero@5800
     2
 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
duke@0
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0
     4
 *
duke@0
     5
 * This code is free software; you can redistribute it and/or modify it
duke@0
     6
 * under the terms of the GNU General Public License version 2 only, as
ohair@961
     7
 * published by the Free Software Foundation.  Oracle designates this
duke@0
     8
 * particular file as subject to the "Classpath" exception as provided
ohair@961
     9
 * by Oracle in the LICENSE file that accompanied this code.
duke@0
    10
 *
duke@0
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
duke@0
    14
 * version 2 for more details (a copy is included in the LICENSE file that
duke@0
    15
 * accompanied this code).
duke@0
    16
 *
duke@0
    17
 * You should have received a copy of the GNU General Public License version
duke@0
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0
    20
 *
ohair@961
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@961
    22
 * or visit www.oracle.com if you need additional information or have any
ohair@961
    23
 * questions.
duke@0
    24
 */
duke@0
    25
duke@0
    26
package com.sun.tools.javac.comp;
duke@0
    27
jjg@2196
    28
import java.util.*;
jjg@2196
    29
jjg@2196
    30
import javax.lang.model.element.ElementKind;
jjg@2196
    31
import javax.tools.JavaFileObject;
duke@0
    32
duke@0
    33
import com.sun.source.tree.IdentifierTree;
mcimadamore@2195
    34
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
duke@0
    35
import com.sun.source.tree.MemberSelectTree;
duke@0
    36
import com.sun.source.tree.TreeVisitor;
duke@0
    37
import com.sun.source.util.SimpleTreeVisitor;
jjg@2196
    38
import com.sun.tools.javac.code.*;
jjg@2196
    39
import com.sun.tools.javac.code.Lint.LintCategory;
jlahoda@4103
    40
import com.sun.tools.javac.code.Scope.WriteableScope;
jjg@2196
    41
import com.sun.tools.javac.code.Symbol.*;
jjg@2196
    42
import com.sun.tools.javac.code.Type.*;
jjg@4454
    43
import com.sun.tools.javac.code.TypeMetadata.Annotations;
mcimadamore@4431
    44
import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
mcimadamore@4935
    45
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
jjg@2196
    46
import com.sun.tools.javac.comp.Check.CheckContext;
jjg@2196
    47
import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
jjg@2196
    48
import com.sun.tools.javac.jvm.*;
sadayapalam@4445
    49
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
sadayapalam@4445
    50
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
sadayapalam@4445
    51
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs;
sadayapalam@4445
    52
import com.sun.tools.javac.resources.CompilerProperties.Errors;
mcimadamore@4431
    53
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
jjg@2196
    54
import com.sun.tools.javac.tree.*;
jjg@2196
    55
import com.sun.tools.javac.tree.JCTree.*;
mcimadamore@2361
    56
import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
jjg@2196
    57
import com.sun.tools.javac.util.*;
jlahoda@4176
    58
import com.sun.tools.javac.util.DefinedBy.Api;
jjg@2196
    59
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
sadayapalam@4445
    60
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
jjg@2196
    61
import com.sun.tools.javac.util.List;
alanb@5016
    62
duke@0
    63
import static com.sun.tools.javac.code.Flags.*;
jjg@1972
    64
import static com.sun.tools.javac.code.Flags.ANNOTATION;
jjg@1972
    65
import static com.sun.tools.javac.code.Flags.BLOCK;
duke@0
    66
import static com.sun.tools.javac.code.Kinds.*;
emc@4248
    67
import static com.sun.tools.javac.code.Kinds.Kind.*;
jjg@2213
    68
import static com.sun.tools.javac.code.TypeTag.*;
jjg@2213
    69
import static com.sun.tools.javac.code.TypeTag.WILDCARD;
jjg@1972
    70
import static com.sun.tools.javac.tree.JCTree.Tag.*;
jlahoda@5330
    71
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
duke@0
    72
duke@0
    73
/** This is the main context-dependent analysis phase in GJC. It
duke@0
    74
 *  encompasses name resolution, type checking and constant folding as
duke@0
    75
 *  subtasks. Some subtasks involve auxiliary classes.
duke@0
    76
 *  @see Check
duke@0
    77
 *  @see Resolve
duke@0
    78
 *  @see ConstFold
duke@0
    79
 *  @see Infer
duke@0
    80
 *
jjg@971
    81
 *  <p><b>This is NOT part of any supported API.
jjg@971
    82
 *  If you write code that depends on this, you do so at your own risk.
duke@0
    83
 *  This code and its internal interfaces are subject to change or
duke@0
    84
 *  deletion without notice.</b>
duke@0
    85
 */
duke@0
    86
public class Attr extends JCTree.Visitor {
briangoetz@3808
    87
    protected static final Context.Key<Attr> attrKey = new Context.Key<>();
duke@0
    88
jjg@294
    89
    final Names names;
duke@0
    90
    final Log log;
duke@0
    91
    final Symtab syms;
duke@0
    92
    final Resolve rs;
mcimadamore@4399
    93
    final Operators operators;
mcimadamore@927
    94
    final Infer infer;
mcimadamore@4333
    95
    final Analyzer analyzer;
mcimadamore@2190
    96
    final DeferredAttr deferredAttr;
duke@0
    97
    final Check chk;
mcimadamore@2191
    98
    final Flow flow;
duke@0
    99
    final MemberEnter memberEnter;
jlahoda@4314
   100
    final TypeEnter typeEnter;
duke@0
   101
    final TreeMaker make;
duke@0
   102
    final ConstFold cfolder;
duke@0
   103
    final Enter enter;
duke@0
   104
    final Target target;
duke@0
   105
    final Types types;
mcimadamore@268
   106
    final JCDiagnostic.Factory diags;
jfranck@4203
   107
    final TypeAnnotations typeAnnotations;
mcimadamore@1317
   108
    final DeferredLintHandler deferredLintHandler;
pgovereau@4044
   109
    final TypeEnvs typeEnvs;
mcimadamore@4139
   110
    final Dependencies dependencies;
jjg@4454
   111
    final Annotate annotate;
mcimadamore@4608
   112
    final ArgumentAttr argumentAttr;
dbalek@721
   113
    private final boolean isBackgroundCompilation;
duke@0
   114
duke@0
   115
    public static Attr instance(Context context) {
duke@0
   116
        Attr instance = context.get(attrKey);
duke@0
   117
        if (instance == null)
duke@0
   118
            instance = new Attr(context);
duke@0
   119
        return instance;
duke@0
   120
    }
duke@0
   121
duke@0
   122
    protected Attr(Context context) {
duke@0
   123
        context.put(attrKey, this);
duke@0
   124
jjg@294
   125
        names = Names.instance(context);
duke@0
   126
        log = Log.instance(context);
duke@0
   127
        syms = Symtab.instance(context);
duke@0
   128
        rs = Resolve.instance(context);
mcimadamore@4399
   129
        operators = Operators.instance(context);
duke@0
   130
        chk = Check.instance(context);
mcimadamore@2191
   131
        flow = Flow.instance(context);
duke@0
   132
        memberEnter = MemberEnter.instance(context);
jlahoda@4314
   133
        typeEnter = TypeEnter.instance(context);
duke@0
   134
        make = TreeMaker.instance(context);
duke@0
   135
        enter = Enter.instance(context);
mcimadamore@927
   136
        infer = Infer.instance(context);
mcimadamore@4333
   137
        analyzer = Analyzer.instance(context);
mcimadamore@2190
   138
        deferredAttr = DeferredAttr.instance(context);
duke@0
   139
        cfolder = ConstFold.instance(context);
duke@0
   140
        target = Target.instance(context);
duke@0
   141
        types = Types.instance(context);
mcimadamore@268
   142
        diags = JCDiagnostic.Factory.instance(context);
duke@0
   143
        annotate = Annotate.instance(context);
jfranck@4203
   144
        typeAnnotations = TypeAnnotations.instance(context);
mcimadamore@1317
   145
        deferredLintHandler = DeferredLintHandler.instance(context);
pgovereau@4044
   146
        typeEnvs = TypeEnvs.instance(context);
mcimadamore@4139
   147
        dependencies = Dependencies.instance(context);
mcimadamore@4608
   148
        argumentAttr = ArgumentAttr.instance(context);
duke@0
   149
duke@0
   150
        Options options = Options.instance(context);
duke@0
   151
duke@0
   152
        Source source = Source.instance(context);
darcy@720
   153
        allowStringsInSwitch = source.allowStringsInSwitch();
mcimadamore@2260
   154
        allowPoly = source.allowPoly();
vromero@2834
   155
        allowTypeAnnos = source.allowTypeAnnotations();
mcimadamore@2191
   156
        allowLambda = source.allowLambda();
mcimadamore@2234
   157
        allowDefaultMethods = source.allowDefaultMethods();
dlsmith@4034
   158
        allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
darcy@720
   159
        sourceName = source.name;
jjg@1132
   160
        useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
mcimadamore@2078
   161
emc@4248
   162
        statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
jlahoda@4301
   163
        varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
emc@4248
   164
        unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
mcimadamore@4608
   165
        methodAttrInfo = new MethodAttrInfo();
emc@4248
   166
        unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
emc@4248
   167
        unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
mcimadamore@2191
   168
        recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
mcimadamore@4339
   169
jlahoda@5
   170
        isBackgroundCompilation = options.get("backgroundCompilation") != null;     //NOI18N
duke@0
   171
    }
duke@0
   172
mcimadamore@2190
   173
    /** Switch: support target-typing inference
mcimadamore@2190
   174
     */
mcimadamore@2190
   175
    boolean allowPoly;
mcimadamore@2190
   176
vromero@2834
   177
    /** Switch: support type annotations.
vromero@2834
   178
     */
vromero@2834
   179
    boolean allowTypeAnnos;
vromero@2834
   180
mcimadamore@2260
   181
    /** Switch: support lambda expressions ?
mcimadamore@2260
   182
     */
mcimadamore@2260
   183
    boolean allowLambda;
mcimadamore@2260
   184
mcimadamore@2234
   185
    /** Switch: support default methods ?
mcimadamore@2234
   186
     */
mcimadamore@2234
   187
    boolean allowDefaultMethods;
mcimadamore@2234
   188
dlsmith@4034
   189
    /** Switch: static interface methods enabled?
dlsmith@4034
   190
     */
dlsmith@4034
   191
    boolean allowStaticInterfaceMethods;
dlsmith@4034
   192
duke@0
   193
    /**
duke@0
   194
     * Switch: warn about use of variable before declaration?
duke@0
   195
     * RFE: 6425594
duke@0
   196
     */
duke@0
   197
    boolean useBeforeDeclarationWarning;
duke@0
   198
jjg@667
   199
    /**
darcy@720
   200
     * Switch: allow strings in switch?
darcy@720
   201
     */
darcy@720
   202
    boolean allowStringsInSwitch;
darcy@720
   203
darcy@720
   204
    /**
darcy@720
   205
     * Switch: name of source level; used for error reporting.
darcy@720
   206
     */
darcy@720
   207
    String sourceName;
darcy@720
   208
duke@0
   209
    /** Check kind and type of given tree against protokind and prototype.
duke@0
   210
     *  If check succeeds, store type in tree and return it.
duke@0
   211
     *  If check fails, store errType in tree and return it.
duke@0
   212
     *  No checks are performed if the prototype is a method type.
jjg@289
   213
     *  It is not necessary in this case since we know that kind and type
duke@0
   214
     *  are correct.
duke@0
   215
     *
duke@0
   216
     *  @param tree     The tree whose kind and type is checked
mcimadamore@4353
   217
     *  @param found    The computed type of the tree
duke@0
   218
     *  @param ownkind  The computed kind of the tree
mcimadamore@2063
   219
     *  @param resultInfo  The expected result of the tree
duke@0
   220
     */
emc@4248
   221
    Type check(final JCTree tree,
emc@4248
   222
               final Type found,
emc@4248
   223
               final KindSelector ownkind,
emc@4248
   224
               final ResultInfo resultInfo) {
mcimadamore@2190
   225
        InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
vromero@4059
   226
        Type owntype;
mcimadamore@4339
   227
        boolean shouldCheck = !found.hasTag(ERROR) &&
mcimadamore@4339
   228
                !resultInfo.pt.hasTag(METHOD) &&
mcimadamore@4339
   229
                !resultInfo.pt.hasTag(FORALL);
mcimadamore@4339
   230
        if (shouldCheck && !ownkind.subset(resultInfo.pkind)) {
mcimadamore@4339
   231
            log.error(tree.pos(), "unexpected.type",
mcimadamore@4339
   232
            resultInfo.pkind.kindNames(),
mcimadamore@4339
   233
            ownkind.kindNames());
mcimadamore@4339
   234
            owntype = types.createErrorType(found);
mcimadamore@4339
   235
        } else if (allowPoly && inferenceContext.free(found)) {
mcimadamore@4339
   236
            //delay the check if there are inference variables in the found type
mcimadamore@4339
   237
            //this means we are dealing with a partially inferred poly expression
mcimadamore@4339
   238
            owntype = shouldCheck ? resultInfo.pt : found;
sadayapalam@4483
   239
            if (resultInfo.checkMode.installPostInferenceHook()) {
mcimadamore@4952
   240
                inferenceContext.addFreeTypeListener(List.of(found),
sadayapalam@4445
   241
                        instantiatedContext -> {
sadayapalam@4445
   242
                            ResultInfo pendingResult =
sadayapalam@4445
   243
                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
sadayapalam@4483
   244
                            check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
sadayapalam@4445
   245
                        });
sadayapalam@4445
   246
            }
vromero@4059
   247
        } else {
mcimadamore@4339
   248
            owntype = shouldCheck ?
mcimadamore@4339
   249
            resultInfo.check(tree, found) :
mcimadamore@4339
   250
            found;
duke@0
   251
        }
sadayapalam@4483
   252
        if (resultInfo.checkMode.updateTreeType()) {
mcimadamore@4339
   253
            tree.type = owntype;
mcimadamore@4339
   254
        }
duke@0
   255
        return owntype;
duke@0
   256
    }
duke@0
   257
duke@0
   258
    /** Is given blank final variable assignable, i.e. in a scope where it
duke@0
   259
     *  may be assigned to even though it is final?
duke@0
   260
     *  @param v      The blank final variable.
duke@0
   261
     *  @param env    The current environment.
duke@0
   262
     */
duke@0
   263
    boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
mcimadamore@4141
   264
        Symbol owner = env.info.scope.owner;
duke@0
   265
           // owner refers to the innermost variable, method or
duke@0
   266
           // initializer block declaration at this point.
duke@0
   267
        return
duke@0
   268
            v.owner == owner
duke@0
   269
            ||
duke@0
   270
            ((owner.name == names.init ||    // i.e. we are in a constructor
duke@0
   271
              owner.kind == VAR ||           // i.e. we are in a variable initializer
duke@0
   272
              (owner.flags() & BLOCK) != 0)  // i.e. we are in an initializer block
duke@0
   273
             &&
duke@0
   274
             v.owner == owner.owner
duke@0
   275
             &&
duke@0
   276
             ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
duke@0
   277
    }
duke@0
   278
duke@0
   279
    /** Check that variable can be assigned to.
duke@0
   280
     *  @param pos    The current source code position.
avstepan@4558
   281
     *  @param v      The assigned variable
duke@0
   282
     *  @param base   If the variable is referred to in a Select, the part
duke@0
   283
     *                to the left of the `.', null otherwise.
duke@0
   284
     *  @param env    The current environment.
duke@0
   285
     */
duke@0
   286
    void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
alundblad@5026
   287
        if (v.name == names._this) {
alundblad@5026
   288
            log.error(pos, Errors.CantAssignValToThis);
alundblad@5026
   289
        } else if ((v.flags() & FINAL) != 0 &&
duke@0
   290
            ((v.flags() & HASINIT) != 0
duke@0
   291
             ||
duke@0
   292
             !((base == null ||
jjg@1972
   293
               (base.hasTag(IDENT) && TreeInfo.name(base) == names._this)) &&
duke@0
   294
               isAssignableAsBlankFinal(v, env)))) {
darcy@1000
   295
            if (v.isResourceVariable()) { //TWR resource
mcimadamore@1187
   296
                log.error(pos, "try.resource.may.not.be.assigned", v);
darcy@1000
   297
            } else {
darcy@1000
   298
                log.error(pos, "cant.assign.val.to.final.var", v);
darcy@1000
   299
            }
duke@0
   300
        }
duke@0
   301
    }
duke@0
   302
duke@0
   303
    /** Does tree represent a static reference to an identifier?
duke@0
   304
     *  It is assumed that tree is either a SELECT or an IDENT.
duke@0
   305
     *  We have to weed out selects from non-type names here.
duke@0
   306
     *  @param tree    The candidate tree.
duke@0
   307
     */
duke@0
   308
    boolean isStaticReference(JCTree tree) {
jjg@1972
   309
        if (tree.hasTag(SELECT)) {
duke@0
   310
            Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
duke@0
   311
            if (lsym == null || lsym.kind != TYP) {
duke@0
   312
                return false;
duke@0
   313
            }
duke@0
   314
        }
duke@0
   315
        return true;
duke@0
   316
    }
duke@0
   317
duke@0
   318
    /** Is this symbol a type?
duke@0
   319
     */
duke@0
   320
    static boolean isType(Symbol sym) {
duke@0
   321
        return sym != null && sym.kind == TYP;
duke@0
   322
    }
duke@0
   323
duke@0
   324
    /** The current `this' symbol.
duke@0
   325
     *  @param env    The current environment.
duke@0
   326
     */
duke@0
   327
    Symbol thisSym(DiagnosticPosition pos, Env<AttrContext> env) {
duke@0
   328
        return rs.resolveSelf(pos, env, env.enclClass.sym, names._this);
duke@0
   329
    }
duke@0
   330
duke@0
   331
    /** Attribute a parsed identifier.
duke@0
   332
     * @param tree Parsed identifier name
duke@0
   333
     * @param topLevel The toplevel to use
duke@0
   334
     */
duke@0
   335
    public Symbol attribIdent(JCTree tree, JCCompilationUnit topLevel) {
duke@0
   336
        Env<AttrContext> localEnv = enter.topLevelEnv(topLevel);
duke@0
   337
        localEnv.enclClass = make.ClassDef(make.Modifiers(0),
duke@0
   338
                                           syms.errSymbol.name,
duke@0
   339
                                           null, null, null, null);
duke@0
   340
        localEnv.enclClass.sym = syms.errSymbol;
alanb@5016
   341
        return attribIdent(tree, localEnv);
alanb@5016
   342
    }
alanb@5016
   343
alanb@5016
   344
    /** Attribute a parsed identifier.
alanb@5016
   345
     * @param tree Parsed identifier name
alanb@5016
   346
     * @param env The env to use
alanb@5016
   347
     */
alanb@5016
   348
    public Symbol attribIdent(JCTree tree, Env<AttrContext> env) {
alanb@5016
   349
        return tree.accept(identAttributer, env);
duke@0
   350
    }
duke@0
   351
    // where
duke@0
   352
        private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer();
duke@0
   353
        private class IdentAttributer extends SimpleTreeVisitor<Symbol,Env<AttrContext>> {
jlahoda@4176
   354
            @Override @DefinedBy(Api.COMPILER_TREE)
duke@0
   355
            public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) {
duke@0
   356
                Symbol site = visit(node.getExpression(), env);
dbalek@4427
   357
                if (!site.kind.isValid())
duke@0
   358
                    return site;
duke@0
   359
                Name name = (Name)node.getIdentifier();
duke@0
   360
                if (site.kind == PCK) {
duke@0
   361
                    env.toplevel.packge = (PackageSymbol)site;
emc@4248
   362
                    return rs.findIdentInPackage(env, (TypeSymbol)site, name,
emc@4248
   363
                            KindSelector.TYP_PCK);
duke@0
   364
                } else {
duke@0
   365
                    env.enclClass.sym = (ClassSymbol)site;
duke@0
   366
                    return rs.findMemberType(env, site.asType(), name, (TypeSymbol)site);
duke@0
   367
                }
duke@0
   368
            }
duke@0
   369
jlahoda@4176
   370
            @Override @DefinedBy(Api.COMPILER_TREE)
duke@0
   371
            public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) {
emc@4248
   372
                return rs.findIdent(env, (Name)node.getName(), KindSelector.TYP_PCK);
duke@0
   373
            }
duke@0
   374
        }
duke@0
   375
duke@0
   376
    public Type coerce(Type etype, Type ttype) {
duke@0
   377
        return cfolder.coerce(etype, ttype);
duke@0
   378
    }
duke@0
   379
duke@0
   380
    public Type attribType(JCTree node, TypeSymbol sym) {
pgovereau@4044
   381
        Env<AttrContext> env = typeEnvs.get(sym);
duke@0
   382
        Env<AttrContext> localEnv = env.dup(node, env.info.dup());
mcimadamore@2063
   383
        return attribTree(node, localEnv, unknownTypeInfo);
mcimadamore@2063
   384
    }
mcimadamore@2063
   385
mcimadamore@2063
   386
    public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) {
mcimadamore@2063
   387
        // Attribute qualifying package or class.
mcimadamore@2063
   388
        JCFieldAccess s = (JCFieldAccess)tree.qualid;
emc@4248
   389
        return attribTree(s.selected, env,
emc@4248
   390
                          new ResultInfo(tree.staticImport ?
emc@4248
   391
                                         KindSelector.TYP : KindSelector.TYP_PCK,
mcimadamore@2063
   392
                       Type.noType));
duke@0
   393
    }
duke@0
   394
duke@0
   395
    public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
dbalek@1261
   396
        Env<AttrContext> localEnv = env.dup(env.tree, env.info.dup(env.info.scope.dupUnshared()));
duke@0
   397
        breakTree = tree;
duke@0
   398
        try {
dbalek@1261
   399
            attribExpr(expr, localEnv);
duke@0
   400
        } catch (BreakAttr b) {
duke@0
   401
            return b.env;
sundar@1065
   402
        } catch (AssertionError ae) {
sundar@1065
   403
            if (ae.getCause() instanceof BreakAttr) {
sundar@1065
   404
                return ((BreakAttr)(ae.getCause())).env;
sundar@1065
   405
            } else {
sundar@1065
   406
                throw ae;
sundar@1065
   407
            }
duke@0
   408
        } finally {
duke@0
   409
            breakTree = null;
duke@0
   410
        }
dbalek@1261
   411
        return localEnv;
duke@0
   412
    }
duke@0
   413
duke@0
   414
    public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) {
dbalek@1261
   415
        Env<AttrContext> localEnv = env.dup(env.tree, env.info.dup(env.info.scope.dupUnshared()));
duke@0
   416
        breakTree = tree;
duke@0
   417
        try {
dbalek@1261
   418
            attribStat(stmt, localEnv);
duke@0
   419
        } catch (BreakAttr b) {
duke@0
   420
            return b.env;
sundar@1065
   421
        } catch (AssertionError ae) {
sundar@1065
   422
            if (ae.getCause() instanceof BreakAttr) {
sundar@1065
   423
                return ((BreakAttr)(ae.getCause())).env;
sundar@1065
   424
            } else {
sundar@1065
   425
                throw ae;
sundar@1065
   426
            }
duke@0
   427
        } finally {
duke@0
   428
            breakTree = null;
duke@0
   429
        }
dbalek@1261
   430
        return localEnv;
duke@0
   431
    }
duke@0
   432
duke@0
   433
    private JCTree breakTree = null;
duke@0
   434
jlahoda@5
   435
    public static class BreakAttr extends RuntimeException {
duke@0
   436
        static final long serialVersionUID = -6924771130405446405L;
dbalek@4835
   437
        private final Env<AttrContext> env;
dbalek@4835
   438
        private final Type result;
dbalek@4835
   439
        private BreakAttr(Env<AttrContext> env, Type result) {
mcimadamore@2890
   440
            this.env = env;
dbalek@4835
   441
            this.result = result;
duke@0
   442
        }
duke@0
   443
    }
duke@0
   444
sadayapalam@4483
   445
    /**
sadayapalam@4483
   446
     * Mode controlling behavior of Attr.Check
sadayapalam@4483
   447
     */
sadayapalam@4483
   448
    enum CheckMode {
sadayapalam@4483
   449
sadayapalam@4483
   450
        NORMAL,
sadayapalam@4483
   451
mcimadamore@5853
   452
        /**
mcimadamore@5853
   453
         * Mode signalling 'fake check' - skip tree update. A side-effect of this mode is
mcimadamore@5853
   454
         * that the captured var cache in {@code InferenceContext} will be used in read-only
mcimadamore@5853
   455
         * mode when performing inference checks.
mcimadamore@5853
   456
         */
mcimadamore@5853
   457
        NO_TREE_UPDATE {
sadayapalam@4483
   458
            @Override
sadayapalam@4483
   459
            public boolean updateTreeType() {
sadayapalam@4483
   460
                return false;
sadayapalam@4483
   461
            }
sadayapalam@4483
   462
        },
mcimadamore@5853
   463
        /**
mcimadamore@5853
   464
         * Mode signalling that caller will manage free types in tree decorations.
mcimadamore@5853
   465
         */
mcimadamore@5853
   466
        NO_INFERENCE_HOOK {
sadayapalam@4483
   467
            @Override
sadayapalam@4483
   468
            public boolean installPostInferenceHook() {
sadayapalam@4483
   469
                return false;
sadayapalam@4483
   470
            }
sadayapalam@4483
   471
        };
sadayapalam@4483
   472
sadayapalam@4483
   473
        public boolean updateTreeType() {
sadayapalam@4483
   474
            return true;
sadayapalam@4483
   475
        }
sadayapalam@4483
   476
        public boolean installPostInferenceHook() {
sadayapalam@4483
   477
            return true;
sadayapalam@4483
   478
        }
sadayapalam@4483
   479
    }
sadayapalam@4483
   480
sadayapalam@4483
   481
mcimadamore@2078
   482
    class ResultInfo {
emc@4248
   483
        final KindSelector pkind;
mcimadamore@2190
   484
        final Type pt;
mcimadamore@2190
   485
        final CheckContext checkContext;
sadayapalam@4483
   486
        final CheckMode checkMode;
mcimadamore@2063
   487
emc@4248
   488
        ResultInfo(KindSelector pkind, Type pt) {
sadayapalam@4483
   489
            this(pkind, pt, chk.basicHandler, CheckMode.NORMAL);
sadayapalam@4483
   490
        }
sadayapalam@4483
   491
sadayapalam@4483
   492
        ResultInfo(KindSelector pkind, Type pt, CheckMode checkMode) {
sadayapalam@4483
   493
            this(pkind, pt, chk.basicHandler, checkMode);
mcimadamore@2078
   494
        }
mcimadamore@2078
   495
emc@4248
   496
        protected ResultInfo(KindSelector pkind,
emc@4248
   497
                             Type pt, CheckContext checkContext) {
sadayapalam@4483
   498
            this(pkind, pt, checkContext, CheckMode.NORMAL);
sadayapalam@4483
   499
        }
sadayapalam@4483
   500
sadayapalam@4483
   501
        protected ResultInfo(KindSelector pkind,
sadayapalam@4483
   502
                             Type pt, CheckContext checkContext, CheckMode checkMode) {
mcimadamore@2063
   503
            this.pkind = pkind;
mcimadamore@2063
   504
            this.pt = pt;
mcimadamore@2078
   505
            this.checkContext = checkContext;
sadayapalam@4483
   506
            this.checkMode = checkMode;
sadayapalam@4424
   507
        }
sadayapalam@4424
   508
mcimadamore@5897
   509
        /**
mcimadamore@5897
   510
         * Should {@link Attr#attribTree} use the {@ArgumentAttr} visitor instead of this one?
mcimadamore@5897
   511
         * @param tree The tree to be type-checked.
mcimadamore@5897
   512
         * @return true if {@ArgumentAttr} should be used.
mcimadamore@5897
   513
         */
mcimadamore@5897
   514
        protected boolean needsArgumentAttr(JCTree tree) { return false; }
mcimadamore@2078
   515
mcimadamore@2190
   516
        protected Type check(final DiagnosticPosition pos, final Type found) {
mcimadamore@2078
   517
            return chk.checkType(pos, found, pt, checkContext);
mcimadamore@2063
   518
        }
mcimadamore@2190
   519
mcimadamore@2190
   520
        protected ResultInfo dup(Type newPt) {
sadayapalam@4483
   521
            return new ResultInfo(pkind, newPt, checkContext, checkMode);
mcimadamore@2190
   522
        }
mcimadamore@2260
   523
mcimadamore@2260
   524
        protected ResultInfo dup(CheckContext newContext) {
sadayapalam@4483
   525
            return new ResultInfo(pkind, pt, newContext, checkMode);
mcimadamore@2260
   526
        }
vromero@3181
   527
vromero@3993
   528
        protected ResultInfo dup(Type newPt, CheckContext newContext) {
sadayapalam@4483
   529
            return new ResultInfo(pkind, newPt, newContext, checkMode);
sadayapalam@4483
   530
        }
sadayapalam@4483
   531
sadayapalam@4483
   532
        protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) {
sadayapalam@4483
   533
            return new ResultInfo(pkind, newPt, newContext, newMode);
sadayapalam@4483
   534
        }
sadayapalam@4483
   535
sadayapalam@4483
   536
        protected ResultInfo dup(CheckMode newMode) {
sadayapalam@4483
   537
            return new ResultInfo(pkind, pt, checkContext, newMode);
vromero@3993
   538
        }
vromero@3993
   539
vromero@3181
   540
        @Override
vromero@3181
   541
        public String toString() {
vromero@3181
   542
            if (pt != null) {
vromero@3181
   543
                return pt.toString();
vromero@3181
   544
            } else {
vromero@3181
   545
                return "";
vromero@3181
   546
            }
vromero@3181
   547
        }
mcimadamore@2063
   548
    }
mcimadamore@2063
   549
mcimadamore@4608
   550
    class MethodAttrInfo extends ResultInfo {
mcimadamore@4608
   551
        public MethodAttrInfo() {
mcimadamore@4608
   552
            this(chk.basicHandler);
mcimadamore@4608
   553
        }
mcimadamore@4608
   554
mcimadamore@4608
   555
        public MethodAttrInfo(CheckContext checkContext) {
mcimadamore@4608
   556
            super(KindSelector.VAL, Infer.anyPoly, checkContext);
mcimadamore@4608
   557
        }
mcimadamore@4608
   558
mcimadamore@4608
   559
        @Override
mcimadamore@5897
   560
        protected boolean needsArgumentAttr(JCTree tree) {
mcimadamore@5897
   561
            return true;
mcimadamore@4608
   562
        }
mcimadamore@4608
   563
mcimadamore@4608
   564
        protected ResultInfo dup(Type newPt) {
mcimadamore@4608
   565
            throw new IllegalStateException();
mcimadamore@4608
   566
        }
mcimadamore@4608
   567
mcimadamore@4608
   568
        protected ResultInfo dup(CheckContext newContext) {
mcimadamore@4608
   569
            return new MethodAttrInfo(newContext);
mcimadamore@4608
   570
        }
mcimadamore@4608
   571
mcimadamore@4608
   572
        protected ResultInfo dup(Type newPt, CheckContext newContext) {
mcimadamore@4608
   573
            throw new IllegalStateException();
mcimadamore@4608
   574
        }
mcimadamore@4608
   575
mcimadamore@4608
   576
        protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) {
mcimadamore@4608
   577
            throw new IllegalStateException();
mcimadamore@4608
   578
        }
mcimadamore@4608
   579
mcimadamore@4608
   580
        protected ResultInfo dup(CheckMode newMode) {
mcimadamore@4608
   581
            throw new IllegalStateException();
mcimadamore@4608
   582
        }
mcimadamore@4608
   583
    }
mcimadamore@4608
   584
mcimadamore@2191
   585
    class RecoveryInfo extends ResultInfo {
mcimadamore@2191
   586
mcimadamore@2191
   587
        public RecoveryInfo(final DeferredAttr.DeferredAttrContext deferredAttrContext) {
dbalek@2450
   588
            this(deferredAttrContext, Type.recoveryType);
dbalek@2450
   589
        }
dbalek@2450
   590
        
dbalek@2450
   591
        public RecoveryInfo(final DeferredAttr.DeferredAttrContext deferredAttrContext, final Type pt) {
dbalek@4426
   592
            super(KindSelector.VAL, pt, new Check.NestedCheckContext(chk.basicHandler) {
mcimadamore@2191
   593
                @Override
mcimadamore@2191
   594
                public DeferredAttr.DeferredAttrContext deferredAttrContext() {
mcimadamore@2191
   595
                    return deferredAttrContext;
mcimadamore@2191
   596
                }
mcimadamore@2191
   597
                @Override
mcimadamore@2191
   598
                public boolean compatible(Type found, Type req, Warner warn) {
mcimadamore@2191
   599
                    return true;
mcimadamore@2191
   600
                }
mcimadamore@2191
   601
                @Override
mcimadamore@2191
   602
                public void report(DiagnosticPosition pos, JCDiagnostic details) {
mcimadamore@2260
   603
                    chk.basicHandler.report(pos, details);
mcimadamore@2191
   604
                }
mcimadamore@2191
   605
            });
mcimadamore@2191
   606
        }
mcimadamore@2191
   607
    }
mcimadamore@2191
   608
mcimadamore@2190
   609
    final ResultInfo statInfo;
jlahoda@4301
   610
    final ResultInfo varAssignmentInfo;
mcimadamore@4608
   611
    final ResultInfo methodAttrInfo;
mcimadamore@2190
   612
    final ResultInfo unknownExprInfo;
mcimadamore@2190
   613
    final ResultInfo unknownTypeInfo;
mcimadamore@2626
   614
    final ResultInfo unknownTypeExprInfo;
mcimadamore@2191
   615
    final ResultInfo recoveryInfo;
mcimadamore@2063
   616
mcimadamore@2063
   617
    Type pt() {
mcimadamore@2063
   618
        return resultInfo.pt;
mcimadamore@2063
   619
    }
mcimadamore@2063
   620
emc@4248
   621
    KindSelector pkind() {
mcimadamore@2063
   622
        return resultInfo.pkind;
mcimadamore@2063
   623
    }
duke@0
   624
duke@0
   625
/* ************************************************************************
duke@0
   626
 * Visitor methods
duke@0
   627
 *************************************************************************/
duke@0
   628
duke@0
   629
    /** Visitor argument: the current environment.
duke@0
   630
     */
duke@0
   631
    Env<AttrContext> env;
duke@0
   632
mcimadamore@2063
   633
    /** Visitor argument: the currently expected attribution result.
duke@0
   634
     */
mcimadamore@2063
   635
    ResultInfo resultInfo;
duke@0
   636
duke@0
   637
    /** Visitor result: the computed type.
duke@0
   638
     */
duke@0
   639
    Type result;
duke@0
   640
duke@0
   641
    /** Visitor method: attribute a tree, catching any completion failure
duke@0
   642
     *  exceptions. Return the tree's type.
duke@0
   643
     *
duke@0
   644
     *  @param tree    The tree to be visited.
duke@0
   645
     *  @param env     The environment visitor argument.
mcimadamore@2063
   646
     *  @param resultInfo   The result info visitor argument.
duke@0
   647
     */
mcimadamore@2190
   648
    Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
duke@0
   649
        Env<AttrContext> prevEnv = this.env;
mcimadamore@2063
   650
        ResultInfo prevResult = this.resultInfo;
duke@0
   651
        try {
duke@0
   652
            this.env = env;
mcimadamore@2063
   653
            this.resultInfo = resultInfo;
dbalek@5867
   654
            try {
dbalek@5947
   655
                if (resultInfo.needsArgumentAttr(tree)) {
dbalek@5947
   656
                    result = argumentAttr.attribArg(tree, env);
dbalek@5947
   657
                } else {
dbalek@5947
   658
                    tree.accept(this);
dbalek@5947
   659
                }
dbalek@5867
   660
            } catch (Resolve.InapplicableMethodException ime) {
dbalek@5867
   661
                if (tree != breakTree ||
dbalek@5867
   662
                        resultInfo.checkContext.deferredAttrContext().mode != AttrMode.CHECK) {
dbalek@5867
   663
                    throw ime;
dbalek@5867
   664
                }
dbalek@5867
   665
            }
mcimadamore@2260
   666
            if (tree == breakTree &&
mcimadamore@2260
   667
                    resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
dbalek@4835
   668
                throw new BreakAttr(copyEnv(env), result);
mcimadamore@2260
   669
            }
duke@0
   670
            return result;
duke@0
   671
        } catch (CompletionFailure ex) {
duke@0
   672
            tree.type = syms.errType;
duke@0
   673
            return chk.completionError(tree.pos(), ex);
duke@0
   674
        } finally {
duke@0
   675
            this.env = prevEnv;
mcimadamore@2063
   676
            this.resultInfo = prevResult;
duke@0
   677
        }
duke@0
   678
    }
duke@0
   679
mcimadamore@2890
   680
    Env<AttrContext> copyEnv(Env<AttrContext> env) {
mcimadamore@2890
   681
        Env<AttrContext> newEnv =
mcimadamore@2890
   682
                env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
mcimadamore@2890
   683
        if (newEnv.outer != null) {
mcimadamore@2890
   684
            newEnv.outer = copyEnv(newEnv.outer);
mcimadamore@2890
   685
        }
mcimadamore@2890
   686
        return newEnv;
mcimadamore@2890
   687
    }
mcimadamore@2890
   688
jlahoda@4103
   689
    WriteableScope copyScope(WriteableScope sc) {
jlahoda@4103
   690
        WriteableScope newScope = WriteableScope.create(sc.owner);
mcimadamore@2890
   691
        List<Symbol> elemsList = List.nil();
jlahoda@4103
   692
        for (Symbol sym : sc.getSymbols()) {
jlahoda@4103
   693
            elemsList = elemsList.prepend(sym);
mcimadamore@2890
   694
        }
mcimadamore@2890
   695
        for (Symbol s : elemsList) {
mcimadamore@2890
   696
            newScope.enter(s);
mcimadamore@2890
   697
        }
mcimadamore@2890
   698
        return newScope;
mcimadamore@2890
   699
    }
mcimadamore@2890
   700
duke@0
   701
    /** Derived visitor method: attribute an expression tree.
duke@0
   702
     */
duke@0
   703
    public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
dbalek@4426
   704
        return attribTree(tree, env, new ResultInfo(KindSelector.VAL, pt != null && !pt.hasTag(ERROR) ? pt : Type.noType));
darcy@1000
   705
    }
darcy@1000
   706
duke@0
   707
    /** Derived visitor method: attribute an expression tree with
duke@0
   708
     *  no constraints on the computed type.
duke@0
   709
     */
jjg@2254
   710
    public Type attribExpr(JCTree tree, Env<AttrContext> env) {
mcimadamore@2063
   711
        return attribTree(tree, env, unknownExprInfo);
duke@0
   712
    }
duke@0
   713
duke@0
   714
    /** Derived visitor method: attribute a type tree.
duke@0
   715
     */
jjg@2254
   716
    public Type attribType(JCTree tree, Env<AttrContext> env) {
mcimadamore@927
   717
        Type result = attribType(tree, env, Type.noType);
mcimadamore@927
   718
        return result;
mcimadamore@927
   719
    }
mcimadamore@927
   720
mcimadamore@927
   721
    /** Derived visitor method: attribute a type tree.
mcimadamore@927
   722
     */
mcimadamore@927
   723
    Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
emc@4248
   724
        Type result = attribTree(tree, env, new ResultInfo(KindSelector.TYP, pt));
duke@0
   725
        return result;
duke@0
   726
    }
duke@0
   727
duke@0
   728
    /** Derived visitor method: attribute a statement or definition tree.
duke@0
   729
     */
duke@0
   730
    public Type attribStat(JCTree tree, Env<AttrContext> env) {
dbalek@5954
   731
        Env<AttrContext> analyzeEnv = analyzer.copyEnvIfNeeded(tree, env);
dbalek@4742
   732
        boolean baCatched = false;
mcimadamore@4333
   733
        try {
mcimadamore@4333
   734
            return attribTree(tree, env, statInfo);
dbalek@4742
   735
        } catch (BreakAttr ba) {
dbalek@4742
   736
            baCatched = true;
dbalek@4742
   737
            throw ba;
mcimadamore@4333
   738
        } finally {
dbalek@4742
   739
            if (!baCatched) {
dbalek@4742
   740
                analyzer.analyzeIfNeeded(tree, analyzeEnv);
dbalek@4742
   741
            }
mcimadamore@4333
   742
        }
duke@0
   743
    }
duke@0
   744
duke@0
   745
    /** Attribute a list of expressions, returning a list of types.
duke@0
   746
     */
duke@0
   747
    List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) {
briangoetz@3808
   748
        ListBuffer<Type> ts = new ListBuffer<>();
duke@0
   749
        for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
duke@0
   750
            ts.append(attribExpr(l.head, env, pt));
duke@0
   751
        return ts.toList();
duke@0
   752
    }
duke@0
   753
duke@0
   754
    /** Attribute a list of statements, returning nothing.
duke@0
   755
     */
duke@0
   756
    <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) {
duke@0
   757
        for (List<T> l = trees; l.nonEmpty(); l = l.tail)
duke@0
   758
            attribStat(l.head, env);
duke@0
   759
    }
duke@0
   760
vromero@2834
   761
    /** Attribute the arguments in a method call, returning the method kind.
duke@0
   762
     */
mcimadamore@4313
   763
    KindSelector attribArgs(KindSelector initialKind, List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
mcimadamore@4313
   764
        KindSelector kind = initialKind;
dbalek@4766
   765
        for (JCExpression arg : trees) {
dbalek@4835
   766
            try {
dbalek@4835
   767
                Type argtype = chk.checkNonVoid(arg, attribTree(arg, env, allowPoly ? methodAttrInfo : unknownExprInfo));
dbalek@4835
   768
                if (argtype.hasTag(DEFERRED)) {
dbalek@4835
   769
                    kind = KindSelector.of(KindSelector.POLY, kind);
dbalek@4835
   770
                }
dbalek@4835
   771
                argtypes.append(argtype);
dbalek@4835
   772
            } catch (BreakAttr ba) {
dbalek@4856
   773
                if (ba.result != null && !ba.result.hasTag(PACKAGE) && !ba.result.hasTag(METHOD) && env.tree == ba.env.tree) {
dbalek@4835
   774
                    argtypes.append(chk.checkNonVoid(arg, ba.result));
dbalek@4835
   775
                }
dbalek@4835
   776
                throw ba;
vromero@2834
   777
            }
mcimadamore@2190
   778
        }
mcimadamore@4313
   779
        return kind;
duke@0
   780
    }
duke@0
   781
duke@0
   782
    /** Attribute a type argument list, returning a list of types.
jrose@557
   783
     *  Caller is responsible for calling checkRefTypes.
duke@0
   784
     */
jrose@557
   785
    List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) {
briangoetz@3808
   786
        ListBuffer<Type> argtypes = new ListBuffer<>();
duke@0
   787
        for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
jrose@557
   788
            argtypes.append(attribType(l.head, env));
duke@0
   789
        return argtypes.toList();
duke@0
   790
    }
duke@0
   791
jrose@557
   792
    /** Attribute a type argument list, returning a list of types.
jrose@557
   793
     *  Check that all the types are references.
jrose@557
   794
     */
jrose@557
   795
    List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) {
jrose@557
   796
        List<Type> types = attribAnyTypes(trees, env);
jrose@557
   797
        return chk.checkRefTypes(trees, types);
jrose@557
   798
    }
duke@0
   799
duke@0
   800
    /**
duke@0
   801
     * Attribute type variables (of generic classes or methods).
duke@0
   802
     * Compound types are attributed later in attribBounds.
duke@0
   803
     * @param typarams the type variables to enter
duke@0
   804
     * @param env      the current environment
duke@0
   805
     */
duke@0
   806
    void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) {
duke@0
   807
        for (JCTypeParameter tvar : typarams) {
duke@0
   808
            TypeVar a = (TypeVar)tvar.type;
mcimadamore@222
   809
            a.tsym.flags_field |= UNATTRIBUTED;
mcimadamore@222
   810
            a.bound = Type.noType;
duke@0
   811
            if (!tvar.bounds.isEmpty()) {
jfranck@4203
   812
                List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
duke@0
   813
                for (JCExpression bound : tvar.bounds.tail)
duke@0
   814
                    bounds = bounds.prepend(attribType(bound, env));
duke@0
   815
                types.setBounds(a, bounds.reverse());
duke@0
   816
            } else {
duke@0
   817
                // if no bounds are given, assume a single bound of
duke@0
   818
                // java.lang.Object.
duke@0
   819
                types.setBounds(a, List.of(syms.objectType));
duke@0
   820
            }
mcimadamore@222
   821
            a.tsym.flags_field &= ~UNATTRIBUTED;
duke@0
   822
        }
mcimadamore@2276
   823
        for (JCTypeParameter tvar : typarams) {
duke@0
   824
            chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
duke@0
   825
        }
duke@0
   826
    }
duke@0
   827
duke@0
   828
    /**
duke@0
   829
     * Attribute the type references in a list of annotations.
duke@0
   830
     */
duke@0
   831
    void attribAnnotationTypes(List<JCAnnotation> annotations,
duke@0
   832
                               Env<AttrContext> env) {
duke@0
   833
        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
duke@0
   834
            JCAnnotation a = al.head;
duke@0
   835
            attribType(a.annotationType, env);
duke@0
   836
        }
duke@0
   837
    }
duke@0
   838
jjg@1306
   839
    /**
jjg@1306
   840
     * Attribute a "lazy constant value".
jjg@1306
   841
     *  @param env         The env for the const value
avstepan@4558
   842
     *  @param variable    The initializer for the const value
jjg@1306
   843
     *  @param type        The expected type, or null
jjg@2197
   844
     *  @see VarSymbol#setLazyConstValue
jjg@1306
   845
     */
jfranck@4203
   846
    public Object attribLazyConstantValue(Env<AttrContext> env,
jlahoda@3044
   847
                                      JCVariableDecl variable,
jjg@1306
   848
                                      Type type) {
jjg@1306
   849
jlahoda@3044
   850
        DiagnosticPosition prevLintPos
jlahoda@3044
   851
                = deferredLintHandler.setPos(variable.pos());
jjg@1306
   852
sadayapalam@5157
   853
        final JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
jjg@1306
   854
        try {
dbalek@4844
   855
            if (variable.init == null) {
dbalek@4844
   856
                return null;
dbalek@4844
   857
            }
jlahoda@3044
   858
            Type itype = attribExpr(variable.init, env, type);
vromero@2848
   859
            if (itype.constValue() != null) {
jjg@1306
   860
                return coerce(itype, type).constValue();
vromero@2848
   861
            } else {
jjg@1306
   862
                return null;
vromero@2848
   863
            }
jjg@1306
   864
        } finally {
sadayapalam@5157
   865
            log.useSource(prevSource);
jlahoda@3044
   866
            deferredLintHandler.setPos(prevLintPos);
jjg@1306
   867
        }
jjg@1306
   868
    }
jjg@1306
   869
duke@0
   870
    /** Attribute type reference in an `extends' or `implements' clause.
mcimadamore@927
   871
     *  Supertypes of anonymous inner classes are usually already attributed.
duke@0
   872
     *
duke@0
   873
     *  @param tree              The tree making up the type reference.
duke@0
   874
     *  @param env               The environment current at the reference.
duke@0
   875
     *  @param classExpected     true if only a class is expected here.
duke@0
   876
     *  @param interfaceExpected true if only an interface is expected here.
duke@0
   877
     */
duke@0
   878
    Type attribBase(JCTree tree,
duke@0
   879
                    Env<AttrContext> env,
duke@0
   880
                    boolean classExpected,
duke@0
   881
                    boolean interfaceExpected,
duke@0
   882
                    boolean checkExtensible) {
mcimadamore@927
   883
        Type t = tree.type != null ?
mcimadamore@927
   884
            tree.type :
mcimadamore@927
   885
            attribType(tree, env);
emc@3214
   886
        return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
duke@0
   887
    }
duke@0
   888
    Type checkBase(Type t,
duke@0
   889
                   JCTree tree,
duke@0
   890
                   Env<AttrContext> env,
duke@0
   891
                   boolean classExpected,
emc@3214
   892
                   boolean interfaceExpected,
duke@0
   893
                   boolean checkExtensible) {
sadayapalam@4688
   894
        final DiagnosticPosition pos = tree.hasTag(TYPEAPPLY) ?
sadayapalam@4688
   895
                (((JCTypeApply) tree).clazz).pos() : tree.pos();
pgovereau@3927
   896
        if (t.tsym.isAnonymous()) {
sadayapalam@4688
   897
            log.error(pos, "cant.inherit.from.anon");
pgovereau@3927
   898
            return types.createErrorType(t);
pgovereau@3927
   899
        }
jjg@1060
   900
        if (t.isErroneous())
jjg@1060
   901
            return t;
emc@3214
   902
        if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
duke@0
   903
            // check that type variable is already visible
duke@0
   904
            if (t.getUpperBound() == null) {
sadayapalam@4688
   905
                log.error(pos, "illegal.forward.ref");
jjg@289
   906
                return types.createErrorType(t);
duke@0
   907
            }
emc@3214
   908
        } else {
sadayapalam@4688
   909
            t = chk.checkClassType(pos, t, checkExtensible);
duke@0
   910
        }
emc@3214
   911
        if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) {
sadayapalam@4688
   912
            log.error(pos, "intf.expected.here");
emc@3126
   913
            // return errType is necessary since otherwise there might
emc@3126
   914
            // be undetected cycles which cause attribution to loop
emc@3126
   915
            return types.createErrorType(t);
duke@0
   916
        } else if (checkExtensible &&
duke@0
   917
                   classExpected &&
emc@3214
   918
                   (t.tsym.flags() & INTERFACE) != 0) {
sadayapalam@4688
   919
            log.error(pos, "no.intf.expected.here");
jjg@289
   920
            return types.createErrorType(t);
duke@0
   921
        }
duke@0
   922
        if (checkExtensible &&
duke@0
   923
            ((t.tsym.flags() & FINAL) != 0)) {
sadayapalam@4688
   924
            log.error(pos,
duke@0
   925
                      "cant.inherit.from.final", t.tsym);
duke@0
   926
        }
sadayapalam@4688
   927
        chk.checkNonCyclic(pos, t);
duke@0
   928
        return t;
duke@0
   929
    }
duke@0
   930
mcimadamore@2113
   931
    Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) {
dbalek@2555
   932
        Assert.check((env.enclClass.sym.flags() & ENUM) != 0 || env.enclClass.sym.kind == ERR);
mcimadamore@4333
   933
        id.type = env.info.scope.owner.enclClass().type;
mcimadamore@4333
   934
        id.sym = env.info.scope.owner.enclClass();
mcimadamore@2113
   935
        return id.type;
mcimadamore@2113
   936
    }
mcimadamore@2113
   937
duke@0
   938
    public void visitClassDef(JCClassDecl tree) {
mcimadamore@4935
   939
        Optional<ArgumentAttr.LocalCacheContext> localCacheContext =
mcimadamore@4935
   940
                Optional.ofNullable(env.info.isSpeculative ?
mcimadamore@4935
   941
                        argumentAttr.withLocalCacheContext() : null);
mcimadamore@4935
   942
        try {
mcimadamore@4935
   943
            // Local and anonymous classes have not been entered yet, so we need to
mcimadamore@4935
   944
            // do it now.
dbalek@5244
   945
            if (env.info.scope.owner.kind.matches(KindSelector.VAL_MTH)
dbalek@5244
   946
                    && (env.info.scope.owner.kind != ERR || tree.sym == null)) {
alundblad@3820
   947
                enter.classEnter(tree, env);
mcimadamore@4935
   948
            } else {
mcimadamore@4935
   949
                // If this class declaration is part of a class level annotation,
mcimadamore@4935
   950
                // as in @MyAnno(new Object() {}) class MyClass {}, enter it in
mcimadamore@4935
   951
                // order to simplify later steps and allow for sensible error
mcimadamore@4935
   952
                // messages.
mcimadamore@4935
   953
                if (env.tree.hasTag(NEWCLASS) && TreeInfo.isInAnnotation(env, tree))
mcimadamore@4935
   954
                    enter.classEnter(tree, env);
duke@0
   955
            }
mcimadamore@4935
   956
mcimadamore@4935
   957
            ClassSymbol c = tree.sym;
mcimadamore@4935
   958
            if (c == null) {
mcimadamore@4935
   959
                // exit in case something drastic went wrong during enter.
mcimadamore@4935
   960
                result = null;
mcimadamore@4935
   961
            } else {
mcimadamore@4935
   962
                // make sure class has been completed:
mcimadamore@4935
   963
                c.complete();
mcimadamore@4935
   964
mcimadamore@4935
   965
                // If this class appears as an anonymous class
sadayapalam@5400
   966
                // in a superclass constructor call
mcimadamore@4935
   967
                // disable implicit outer instance from being passed.
mcimadamore@4935
   968
                // (This would be an illegal access to "this before super").
mcimadamore@4935
   969
                if (env.info.isSelfCall &&
sadayapalam@5400
   970
                        env.tree.hasTag(NEWCLASS)) {
mcimadamore@4935
   971
                    c.flags_field |= NOOUTERTHIS;
mcimadamore@4935
   972
                }
mcimadamore@4935
   973
                attribClass(tree.pos(), c);
mcimadamore@4935
   974
                result = tree.type = c.type;
mcimadamore@4935
   975
            }
mcimadamore@4935
   976
        } finally {
mcimadamore@4935
   977
            localCacheContext.ifPresent(LocalCacheContext::leave);
duke@0
   978
        }
duke@0
   979
    }
duke@0
   980
duke@0
   981
    public void visitMethodDef(JCMethodDecl tree) {
duke@0
   982
        MethodSymbol m = tree.sym;
dbalek@26
   983
        if (m == null) {
dbalek@26
   984
            // exit in case something drastic went wrong during enter.
dbalek@26
   985
            result = null;
dbalek@26
   986
            return;
dbalek@26
   987
        }
mcimadamore@2210
   988
        boolean isDefaultMethod = (m.flags() & DEFAULT) != 0;
duke@0
   989
jjg@2786
   990
        Lint lint = env.info.lint.augment(m);
duke@0
   991
        Lint prevLint = chk.setLint(lint);
mcimadamore@1244
   992
        MethodSymbol prevMethod = chk.setMethod(m);
duke@0
   993
        try {
mcimadamore@1317
   994
            deferredLintHandler.flush(tree.pos());
duke@0
   995
            chk.checkDeprecatedAnnotation(tree.pos(), m);
duke@0
   996
jjg@2372
   997
mcimadamore@2276
   998
            // Create a new environment with local scope
mcimadamore@2276
   999
            // for attributing the method.
mcimadamore@2276
  1000
            Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
mcimadamore@2276
  1001
            localEnv.info.lint = lint;
mcimadamore@2276
  1002
mcimadamore@2276
  1003
            attribStats(tree.typarams, localEnv);
duke@0
  1004
duke@0
  1005
            // If we override any other methods, check that we do so properly.
duke@0
  1006
            // JLS ???
mcimadamore@1348
  1007
            if (m.isStatic()) {
mcimadamore@1348
  1008
                chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
mcimadamore@1348
  1009
            } else {
mcimadamore@1348
  1010
                chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
mcimadamore@1348
  1011
            }
sadayapalam@4445
  1012
            chk.checkOverride(env, tree, m);
duke@0
  1013
mcimadamore@2260
  1014
            if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) {
mcimadamore@2234
  1015
                log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
mcimadamore@2234
  1016
            }
mcimadamore@2234
  1017
duke@0
  1018
            // Enter all type parameters into the local method scope.
duke@0
  1019
            for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
duke@0
  1020
                localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
duke@0
  1021
duke@0
  1022
            ClassSymbol owner = env.enclClass.sym;
duke@0
  1023
            if ((owner.flags() & ANNOTATION) != 0 &&
vromero@5823
  1024
                    (tree.params.nonEmpty() ||
vromero@5823
  1025
                    tree.recvparam != null))
vromero@5823
  1026
                log.error(tree.params.nonEmpty() ?
vromero@5823
  1027
                        tree.params.head.pos() :
vromero@5823
  1028
                        tree.recvparam.pos(),
jfranck@4203
  1029
                        "intf.annotation.members.cant.have.params");
duke@0
  1030
duke@0
  1031
            // Attribute all value parameters.
duke@0
  1032
            for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
duke@0
  1033
                attribStat(l.head, localEnv);
duke@0
  1034
            }
duke@0
  1035
mcimadamore@1244
  1036
            chk.checkVarargsMethodDecl(localEnv, tree);
mcimadamore@970
  1037
duke@0
  1038
            // Check that type parameters are well-formed.
mcimadamore@300
  1039
            chk.validate(tree.typarams, localEnv);
duke@0
  1040
duke@0
  1041
            // Check that result type is well-formed.
jlahoda@3233
  1042
            if (tree.restype != null && !tree.restype.type.hasTag(VOID))
jlahoda@3233
  1043
                chk.validate(tree.restype, localEnv);
mcimadamore@1029
  1044
jjg@2372
  1045
            // Check that receiver type is well-formed.
jjg@2372
  1046
            if (tree.recvparam != null) {
jjg@2372
  1047
                // Use a new environment to check the receiver parameter.
jjg@2372
  1048
                // Otherwise I get "might not have been initialized" errors.
jjg@2372
  1049
                // Is there a better way?
jjg@2372
  1050
                Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
jjg@2372
  1051
                attribType(tree.recvparam, newEnv);
jjg@2372
  1052
                chk.validate(tree.recvparam, newEnv);
jjg@2372
  1053
            }
jjg@2372
  1054
mcimadamore@1029
  1055
            // annotation method checks
mcimadamore@1029
  1056
            if ((owner.flags() & ANNOTATION) != 0) {
mcimadamore@1029
  1057
                // annotation method cannot have throws clause
mcimadamore@1029
  1058
                if (tree.thrown.nonEmpty()) {
mcimadamore@1029
  1059
                    log.error(tree.thrown.head.pos(),
mcimadamore@1029
  1060
                            "throws.not.allowed.in.intf.annotation");
mcimadamore@1029
  1061
                }
mcimadamore@1029
  1062
                // annotation method cannot declare type-parameters
mcimadamore@1029
  1063
                if (tree.typarams.nonEmpty()) {
mcimadamore@1029
  1064
                    log.error(tree.typarams.head.pos(),
mcimadamore@1029
  1065
                            "intf.annotation.members.cant.have.type.params");
mcimadamore@1029
  1066
                }
mcimadamore@1029
  1067
                // validate annotation method's return type (could be an annotation type)
duke@0
  1068
                chk.validateAnnotationType(tree.restype);
mcimadamore@1029
  1069
                // ensure that annotation method does not clash with members of Object/Annotation
duke@0
  1070
                chk.validateAnnotationMethod(tree.pos(), m);
mcimadamore@1029
  1071
            }
mcimadamore@1029
  1072
duke@0
  1073
            for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail)
duke@0
  1074
                chk.checkType(l.head.pos(), l.head.type, syms.throwableType);
duke@0
  1075
duke@0
  1076
            if (tree.body == null) {
duke@0
  1077
                // Empty bodies are only allowed for
duke@0
  1078
                // abstract, native, or interface methods, or for methods
duke@0
  1079
                // in a retrofit signature class.
duke@0
  1080
                if (tree.defaultValue != null) {
duke@0
  1081
                    if ((owner.flags() & ANNOTATION) == 0)
duke@0
  1082
                        log.error(tree.pos(),
duke@0
  1083
                                  "default.allowed.in.intf.annotation.member");
duke@0
  1084
                }
vromero@4979
  1085
                if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
pgovereau@4167
  1086
                    log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
mcimadamore@18
  1087
            } else {
dbalek@4654
  1088
                if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
dbalek@2330
  1089
                    if ((owner.flags() & INTERFACE) != 0) {
dbalek@2330
  1090
                        log.error(tree.body.pos(), "intf.meth.cant.have.body");
dbalek@2330
  1091
                    } else {
dbalek@2330
  1092
                        log.error(tree.pos(), "abstract.meth.cant.have.body");
dbalek@2330
  1093
                    }
dbalek@91
  1094
                } else if ((tree.mods.flags & NATIVE) != 0) {
dbalek@91
  1095
                    log.error(tree.pos(), "native.meth.cant.have.body");
mcimadamore@2234
  1096
                }
duke@0
  1097
                // Add an implicit super() call unless an explicit call to
duke@0
  1098
                // super(...) or this(...) is given
duke@0
  1099
                // or we are compiling class java.lang.Object.
dbalek@176
  1100
                if (tree.name == names.init && !owner.type.isErroneous() && owner.type != syms.objectType) {
duke@0
  1101
                    JCBlock body = tree.body;
duke@0
  1102
                    if (body.stats.isEmpty() ||
jfranck@4203
  1103
                            !TreeInfo.isSelfCall(body.stats.head)) {
duke@0
  1104
                        body.stats = body.stats.
jlahoda@4314
  1105
                                prepend(typeEnter.SuperCall(make.at(body.pos),
mcimadamore@5586
  1106
                                        List.nil(),
mcimadamore@5586
  1107
                                        List.nil(),
jfranck@4203
  1108
                                        false));
duke@0
  1109
                    } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
jfranck@4203
  1110
                            (tree.mods.flags & GENERATEDCONSTR) == 0 &&
jfranck@4203
  1111
                            TreeInfo.isSuperCall(body.stats.head)) {
duke@0
  1112
                        // enum constructors are not allowed to call super
duke@0
  1113
                        // directly, so make sure there aren't any super calls
duke@0
  1114
                        // in enum constructors, except in the compiler
duke@0
  1115
                        // generated one.
duke@0
  1116
                        log.error(tree.body.stats.head.pos(),
jfranck@4203
  1117
                                "call.to.super.not.allowed.in.enum.ctor",
jfranck@4203
  1118
                                env.enclClass.sym);
duke@0
  1119
                    }
duke@0
  1120
                }
duke@0
  1121
jlahoda@5
  1122
                if (!isBackgroundCompilation) {
jlahoda@5
  1123
                    tree.localEnv = dupLocalEnv(localEnv);
jlahoda@5
  1124
                }
dbalek@2374
  1125
jfranck@4203
  1126
                // Attribute all type annotations in the body
jjg@4454
  1127
                annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
jfranck@4203
  1128
                annotate.flush();
jfranck@4203
  1129
duke@0
  1130
                // Attribute method body.
duke@0
  1131
                attribStat(tree.body, localEnv);
duke@0
  1132
            }
jjg@2372
  1133
duke@0
  1134
            localEnv.info.scope.leave();
duke@0
  1135
            result = tree.type = m.type;
jfranck@4203
  1136
        } finally {
duke@0
  1137
            chk.setLint(prevLint);
mcimadamore@1244
  1138
            chk.setMethod(prevMethod);
duke@0
  1139
        }
duke@0
  1140
    }
duke@0
  1141
jfranck@4203
  1142
    public void visitVarDef(JCVariableDecl tree) {
duke@0
  1143
        // Local variables have not been entered yet, so we need to do it now:
duke@0
  1144
        if (env.info.scope.owner.kind == MTH) {
duke@0
  1145
            if (tree.sym != null) {
duke@0
  1146
                // parameters have already been entered
duke@0
  1147
                env.info.scope.enter(tree.sym);
duke@0
  1148
            } else {
jfranck@4255
  1149
                try {
jjg@4454
  1150
                    annotate.blockAnnotations();
jfranck@4255
  1151
                    memberEnter.memberEnter(tree, env);
jfranck@4255
  1152
                } finally {
jjg@4454
  1153
                    annotate.unblockAnnotations();
jfranck@4255
  1154
                }
jfranck@4203
  1155
            }
jfranck@4203
  1156
        } else {
jfranck@4203
  1157
            if (tree.init != null) {
jfranck@4203
  1158
                // Field initializer expression need to be entered.
jjg@4454
  1159
                annotate.queueScanTreeAndTypeAnnotate(tree.init, env, tree.sym, tree.pos());
jfranck@4203
  1160
                annotate.flush();
jjg@2372
  1161
            }
duke@0
  1162
        }
duke@0
  1163
duke@0
  1164
        VarSymbol v = tree.sym;
dbalek@26
  1165
        if (v == null) {
dbalek@26
  1166
            // exit in case something drastic went wrong during enter.
dbalek@26
  1167
            result = null;
dbalek@26
  1168
            return;
dbalek@26
  1169
        }
jjg@2786
  1170
        Lint lint = env.info.lint.augment(v);
duke@0
  1171
        Lint prevLint = chk.setLint(lint);
duke@0
  1172
mcimadamore@346
  1173
        // Check that the variable's declared type is well-formed.
mcimadamore@2710
  1174
        boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
mcimadamore@2710
  1175
                ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
mcimadamore@2710
  1176
                (tree.sym.flags() & PARAMETER) != 0;
mcimadamore@2710
  1177
        chk.validate(tree.vartype, env, !isImplicitLambdaParameter);
mcimadamore@346
  1178
duke@0
  1179
        try {
jlahoda@3044
  1180
            v.getConstValue(); // ensure compile-time constant initializer is evaluated
jlahoda@3044
  1181
            deferredLintHandler.flush(tree.pos());
duke@0
  1182
            chk.checkDeprecatedAnnotation(tree.pos(), v);
duke@0
  1183
duke@0
  1184
            if (tree.init != null) {
jlahoda@3044
  1185
                if ((v.flags_field & FINAL) == 0 ||
jlahoda@3044
  1186
                    !memberEnter.needsLazyConstValue(tree.init)) {
jlahoda@3044
  1187
                    // Not a compile-time constant
duke@0
  1188
                    // Attribute initializer in a new environment
duke@0
  1189
                    // with the declared variable as owner.
duke@0
  1190
                    // Check that initializer conforms to variable's declared type.
duke@0
  1191
                    Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
duke@0
  1192
                    initEnv.info.lint = lint;
duke@0
  1193
                    // In order to catch self-references, we set the variable's
duke@0
  1194
                    // declaration position to maximal possible value, effectively
duke@0
  1195
                    // marking the variable as undefined.
mcimadamore@272
  1196
                    initEnv.info.enclVar = v;
duke@0
  1197
                    attribExpr(tree.init, initEnv, v.type);
duke@0
  1198
                }
duke@0
  1199
            }
duke@0
  1200
            result = tree.type = v.type;
duke@0
  1201
        }
duke@0
  1202
        finally {
duke@0
  1203
            chk.setLint(prevLint);
duke@0
  1204
        }
duke@0
  1205
    }
duke@0
  1206
duke@0
  1207
    public void visitSkip(JCSkip tree) {
duke@0
  1208
        result = null;
duke@0
  1209
    }
duke@0
  1210
duke@0
  1211
    public void visitBlock(JCBlock tree) {
dbalek@3756
  1212
        if (env.info.scope != null && env.info.scope.owner != null && (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR)) {
duke@0
  1213
            // Block is a static or instance initializer;
duke@0
  1214
            // let the owner of the environment be a freshly
duke@0
  1215
            // created BLOCK-method.
jlahoda@4103
  1216
            Symbol fakeOwner =
vromero@2436
  1217
                new MethodSymbol(tree.flags | BLOCK |
vromero@2436
  1218
                    env.info.scope.owner.flags() & STRICTFP, names.empty, null,
vromero@2436
  1219
                    env.info.scope.owner);
jlahoda@4103
  1220
            final Env<AttrContext> localEnv =
jlahoda@4103
  1221
                env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
emc@4028
  1222
duke@0
  1223
            if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
jfranck@4203
  1224
            // Attribute all type annotations in the block
jjg@4454
  1225
            annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
jfranck@4203
  1226
            annotate.flush();
emc@4028
  1227
            attribStats(tree.stats, localEnv);
jjg@2372
  1228
jjg@2704
  1229
            {
jjg@2704
  1230
                // Store init and clinit type annotations with the ClassSymbol
jjg@2704
  1231
                // to allow output in Gen.normalizeDefs.
jjg@2704
  1232
                ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
jjg@2704
  1233
                List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
jjg@2704
  1234
                if ((tree.flags & STATIC) != 0) {
jjg@2786
  1235
                    cs.appendClassInitTypeAttributes(tas);
jjg@2704
  1236
                } else {
jjg@2786
  1237
                    cs.appendInitTypeAttributes(tas);
jjg@2704
  1238
                }
jjg@2704
  1239
            }
duke@0
  1240
        } else {
duke@0
  1241
            // Create a new local environment with a local scope.
duke@0
  1242
            Env<AttrContext> localEnv =
dbalek@4659
  1243
                env.dup(tree, env.info.dup((env.info.scope != null ? env.info.scope : WriteableScope.create(syms.noSymbol)).dup()));
mcimadamore@2190
  1244
            try {
mcimadamore@2190
  1245
                attribStats(tree.stats, localEnv);
mcimadamore@2190
  1246
            } finally {
mcimadamore@2190
  1247
                localEnv.info.scope.leave();
mcimadamore@2190
  1248
            }
duke@0
  1249
        }
duke@0
  1250
        result = null;
duke@0
  1251
    }
duke@0
  1252
duke@0
  1253
    public void visitDoLoop(JCDoWhileLoop tree) {
duke@0
  1254
        attribStat(tree.body, env.dup(tree));
duke@0
  1255
        attribExpr(tree.cond, env, syms.booleanType);
duke@0
  1256
        result = null;
duke@0
  1257
    }
duke@0
  1258
duke@0
  1259
    public void visitWhileLoop(JCWhileLoop tree) {
duke@0
  1260
        attribExpr(tree.cond, env, syms.booleanType);
duke@0
  1261
        attribStat(tree.body, env.dup(tree));
duke@0
  1262
        result = null;
duke@0
  1263
    }
duke@0
  1264
duke@0
  1265
    public void visitForLoop(JCForLoop tree) {
duke@0
  1266
        Env<AttrContext> loopEnv =
duke@0
  1267
            env.dup(env.tree, env.info.dup(env.info.scope.dup()));
mcimadamore@2190
  1268
        try {
mcimadamore@2190
  1269
            attribStats(tree.init, loopEnv);
mcimadamore@2190
  1270
            if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
mcimadamore@2190
  1271
            loopEnv.tree = tree; // before, we were not in loop!
mcimadamore@2190
  1272
            attribStats(tree.step, loopEnv);
mcimadamore@2190
  1273
            attribStat(tree.body, loopEnv);
mcimadamore@2190
  1274
            result = null;
mcimadamore@2190
  1275
        }
mcimadamore@2190
  1276
        finally {
mcimadamore@2190
  1277
            loopEnv.info.scope.leave();
mcimadamore@2190
  1278
        }
duke@0
  1279
    }
duke@0
  1280
duke@0
  1281
    public void visitForeachLoop(JCEnhancedForLoop tree) {
duke@0
  1282
        Env<AttrContext> loopEnv =
duke@0
  1283
            env.dup(env.tree, env.info.dup(env.info.scope.dup()));
mcimadamore@2190
  1284
        try {
mcimadamore@2794
  1285
            //the Formal Parameter of a for-each loop is not in the scope when
mcimadamore@2794
  1286
            //attributing the for-each expression; we mimick this by attributing
mcimadamore@2794
  1287
            //the for-each expression first (against original scope).
dlsmith@4010
  1288
            Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
mcimadamore@2190
  1289
            attribStat(tree.var, loopEnv);
mcimadamore@2190
  1290
            chk.checkNonVoid(tree.pos(), exprType);
mcimadamore@2190
  1291
            Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
mcimadamore@2190
  1292
            if (elemtype == null) {
mcimadamore@2190
  1293
                // or perhaps expr implements Iterable<T>?
mcimadamore@2190
  1294
                Type base = types.asSuper(exprType, syms.iterableType.tsym);
mcimadamore@2190
  1295
                if (base == null) {
mcimadamore@2190
  1296
                    log.error(tree.expr.pos(),
mcimadamore@2190
  1297
                            "foreach.not.applicable.to.type",
mcimadamore@2190
  1298
                            exprType,
mcimadamore@2190
  1299
                            diags.fragment("type.req.array.or.iterable"));
mcimadamore@2190
  1300
                    elemtype = types.createErrorType(exprType);
mcimadamore@2190
  1301
                } else {
mcimadamore@2190
  1302
                    List<Type> iterableParams = base.allparams();
mcimadamore@2190
  1303
                    elemtype = iterableParams.isEmpty()
mcimadamore@2190
  1304
                        ? syms.objectType
dlsmith@4010
  1305
                        : types.wildUpperBound(iterableParams.head);
mcimadamore@2190
  1306
                }
duke@0
  1307
            }
dbalek@2330
  1308
            if (tree.var.sym != null)
dbalek@2330
  1309
                chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
mcimadamore@2190
  1310
            loopEnv.tree = tree; // before, we were not in loop!
mcimadamore@2190
  1311
            attribStat(tree.body, loopEnv);
mcimadamore@2190
  1312
            result = null;
duke@0
  1313
        }
mcimadamore@2190
  1314
        finally {
mcimadamore@2190
  1315
            loopEnv.info.scope.leave();
mcimadamore@2190
  1316
        }
duke@0
  1317
    }
duke@0
  1318
duke@0
  1319
    public void visitLabelled(JCLabeledStatement tree) {
duke@0
  1320
        // Check that label is not used in an enclosing statement
duke@0
  1321
        Env<AttrContext> env1 = env;
jjg@1972
  1322
        while (env1 != null && !env1.tree.hasTag(CLASSDEF)) {
jjg@1972
  1323
            if (env1.tree.hasTag(LABELLED) &&
duke@0
  1324
                ((JCLabeledStatement) env1.tree).label == tree.label) {
duke@0
  1325
                log.error(tree.pos(), "label.already.in.use",
duke@0
  1326
                          tree.label);
duke@0
  1327
                break;
duke@0
  1328
            }
duke@0
  1329
            env1 = env1.next;
duke@0
  1330
        }
duke@0
  1331
duke@0
  1332
        attribStat(tree.body, env.dup(tree));
duke@0
  1333
        result = null;
duke@0
  1334
    }
duke@0
  1335
duke@0
  1336
    public void visitSwitch(JCSwitch tree) {
duke@0
  1337
        Type seltype = attribExpr(tree.selector, env);
duke@0
  1338
duke@0
  1339
        Env<AttrContext> switchEnv =
duke@0
  1340
            env.dup(tree, env.info.dup(env.info.scope.dup()));
duke@0
  1341
mcimadamore@2190
  1342
        try {
mcimadamore@2190
  1343
dbalek@4426
  1344
            boolean enumSwitch = seltype.tsym != null && (seltype.tsym.flags() & Flags.ENUM) != 0;
jlahoda@5330
  1345
            boolean stringSwitch = types.isSameType(seltype, syms.stringType);
jlahoda@5330
  1346
            if (stringSwitch && !allowStringsInSwitch) {
jlahoda@5330
  1347
                log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
darcy@720
  1348
            }
mcimadamore@2190
  1349
            if (!enumSwitch && !stringSwitch)
mcimadamore@2190
  1350
                seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
mcimadamore@2190
  1351
mcimadamore@2190
  1352
            // Attribute all cases and
mcimadamore@2190
  1353
            // check that there are no duplicate case labels or default clauses.
briangoetz@3808
  1354
            Set<Object> labels = new HashSet<>(); // The set of case labels.
mcimadamore@2190
  1355
            boolean hasDefault = false;      // Is there a default label?
mcimadamore@2190
  1356
            for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
mcimadamore@2190
  1357
                JCCase c = l.head;
jlahoda@4292
  1358
                if (c.pat != null) {
jlahoda@4292
  1359
                    if (enumSwitch) {
jlahoda@4292
  1360
                        Symbol sym = enumConstant(c.pat, seltype);
jlahoda@4292
  1361
                        if (sym == null) {
jlahoda@4292
  1362
                            log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
jlahoda@4292
  1363
                        } else if (!labels.add(sym)) {
jlahoda@4292
  1364
                            log.error(c.pos(), "duplicate.case.label");
jlahoda@4292
  1365
                        }
jlahoda@4292
  1366
                    } else {
jlahoda@4292
  1367
                        Type pattype = attribExpr(c.pat, switchEnv, seltype);
jlahoda@4292
  1368
                        if (!pattype.hasTag(ERROR)) {
jlahoda@4292
  1369
                            if (pattype.constValue() == null) {
jlahoda@4292
  1370
                                log.error(c.pat.pos(),
jlahoda@4292
  1371
                                          (stringSwitch ? "string.const.req" : "const.expr.req"));
sadayapalam@4424
  1372
                            } else if (!labels.add(pattype.constValue())) {
jlahoda@4292
  1373
                                log.error(c.pos(), "duplicate.case.label");
jlahoda@4292
  1374
                            }
jlahoda@4292
  1375
                        }
jlahoda@4292
  1376
                    }
jlahoda@4292
  1377
                } else if (hasDefault) {
jlahoda@4292
  1378
                    log.error(c.pos(), "duplicate.default.label");
jlahoda@4292
  1379
                } else {
jlahoda@4292
  1380
                    hasDefault = true;
jlahoda@4292
  1381
                }
dbalek@2447
  1382
                if (c == breakTree &&
dbalek@2447
  1383
                        resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK)
dbalek@4835
  1384
                    throw new BreakAttr(env, null);
mcimadamore@2190
  1385
                Env<AttrContext> caseEnv =
mcimadamore@2190
  1386
                    switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
dbalek@2554
  1387
                boolean baCatched = false;
mcimadamore@2190
  1388
                try {
mcimadamore@2190
  1389
                    attribStats(c.stats, caseEnv);
dbalek@2554
  1390
                } catch (BreakAttr ba) {
dbalek@2554
  1391
                    baCatched = true;
dbalek@2554
  1392
                    throw ba;
mcimadamore@2190
  1393
                } finally {
mcimadamore@2190
  1394
                    caseEnv.info.scope.leave();
dbalek@2554
  1395
                    if (!baCatched) {
dbalek@2554
  1396
                        addVars(c.stats, switchEnv.info.scope);
dbalek@2554
  1397
                    }
mcimadamore@2190
  1398
                }
mcimadamore@2190
  1399
            }
mcimadamore@2190
  1400
mcimadamore@2190
  1401
            result = null;
darcy@720
  1402
        }
mcimadamore@2190
  1403
        finally {
mcimadamore@2190
  1404
            switchEnv.info.scope.leave();
duke@0
  1405
        }
duke@0
  1406
    }
duke@0
  1407
    // where
duke@0
  1408
        /** Add any variables defined in stats to the switch scope. */
jlahoda@4103
  1409
        private static void addVars(List<JCStatement> stats, WriteableScope switchScope) {
duke@0
  1410
            for (;stats.nonEmpty(); stats = stats.tail) {
duke@0
  1411
                JCTree stat = stats.head;
dbalek@2650
  1412
                if (stat.hasTag(VARDEF) && ((JCVariableDecl) stat).sym != null)
duke@0
  1413
                    switchScope.enter(((JCVariableDecl) stat).sym);
duke@0
  1414
            }
duke@0
  1415
        }
duke@0
  1416
    // where
duke@0
  1417
    /** Return the selected enumeration constant symbol, or null. */
duke@0
  1418
    private Symbol enumConstant(JCTree tree, Type enumType) {
sadayapalam@4424
  1419
        if (tree.hasTag(IDENT)) {
sadayapalam@4424
  1420
            JCIdent ident = (JCIdent)tree;
sadayapalam@4424
  1421
            Name name = ident.name;
sadayapalam@4424
  1422
            for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
sadayapalam@4424
  1423
                if (sym.kind == VAR) {
sadayapalam@4424
  1424
                    Symbol s = ident.sym = sym;
sadayapalam@4424
  1425
                    ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
sadayapalam@4424
  1426
                    ident.type = s.type;
sadayapalam@4424
  1427
                    return ((s.flags_field & Flags.ENUM) == 0)
sadayapalam@4424
  1428
                        ? null : s;
sadayapalam@4424
  1429
                }
duke@0
  1430
            }
duke@0
  1431
        }
duke@0
  1432
        return null;
duke@0
  1433
    }
duke@0
  1434
duke@0
  1435
    public void visitSynchronized(JCSynchronized tree) {
duke@0
  1436
        chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
duke@0
  1437
        attribStat(tree.body, env);
duke@0
  1438
        result = null;
duke@0
  1439
    }
duke@0
  1440
duke@0
  1441
    public void visitTry(JCTry tree) {
darcy@1000
  1442
        // Create a new local environment with a local
darcy@1000
  1443
        Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
mcimadamore@2190
  1444
        try {
mcimadamore@2190
  1445
            boolean isTryWithResource = tree.resources.nonEmpty();
mcimadamore@2190
  1446
            // Create a nested environment for attributing the try block if needed
mcimadamore@2190
  1447
            Env<AttrContext> tryEnv = isTryWithResource ?
mcimadamore@2190
  1448
                env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
mcimadamore@2190
  1449
                localEnv;
mcimadamore@2190
  1450
            try {
mcimadamore@2190
  1451
                // Attribute resource declarations
mcimadamore@2190
  1452
                for (JCTree resource : tree.resources) {
mcimadamore@2190
  1453
                    CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
mcimadamore@2190
  1454
                        @Override
mcimadamore@2190
  1455
                        public void report(DiagnosticPosition pos, JCDiagnostic details) {
mcimadamore@2190
  1456
                            chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
mcimadamore@2190
  1457
                        }
mcimadamore@2190
  1458
                    };
emc@4248
  1459
                    ResultInfo twrResult =
jlahoda@4301
  1460
                        new ResultInfo(KindSelector.VAR,
emc@4248
  1461
                                       syms.autoCloseableType,
emc@4248
  1462
                                       twrContext);
mcimadamore@2190
  1463
                    if (resource.hasTag(VARDEF)) {
mcimadamore@2190
  1464
                        attribStat(resource, tryEnv);
mcimadamore@2190
  1465
                        twrResult.check(resource, resource.type);
mcimadamore@2190
  1466
mcimadamore@2190
  1467
                        //check that resource type cannot throw InterruptedException
mcimadamore@2190
  1468
                        checkAutoCloseable(resource.pos(), localEnv, resource.type);
mcimadamore@2190
  1469
jlahoda@2683
  1470
                        VarSymbol var = ((JCVariableDecl) resource).sym;
mcimadamore@2190
  1471
                        var.setData(ElementKind.RESOURCE_VARIABLE);
mcimadamore@2190
  1472
                    } else {
mcimadamore@2190
  1473
                        attribTree(resource, tryEnv, twrResult);
mcimadamore@2190
  1474
                    }
mcimadamore@2078
  1475
                }
mcimadamore@2190
  1476
                // Attribute body
mcimadamore@2190
  1477
                attribStat(tree.body, tryEnv);
mcimadamore@2190
  1478
            } finally {
mcimadamore@2190
  1479
                if (isTryWithResource)
mcimadamore@2190
  1480
                    tryEnv.info.scope.leave();
darcy@1000
  1481
            }
mcimadamore@2190
  1482
mcimadamore@2190
  1483
            // Attribute catch clauses
mcimadamore@2190
  1484
            for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
mcimadamore@2190
  1485
                JCCatch c = l.head;
mcimadamore@2190
  1486
                Env<AttrContext> catchEnv =
mcimadamore@2190
  1487
                    localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
mcimadamore@2190
  1488
                try {
mcimadamore@2190
  1489
                    Type ctype = attribStat(c.param, catchEnv);
mcimadamore@2190
  1490
                    if (TreeInfo.isMultiCatch(c)) {
mcimadamore@2190
  1491
                        //multi-catch parameter is implicitly marked as final
mcimadamore@2190
  1492
                        c.param.sym.flags_field |= FINAL | UNION;
mcimadamore@2190
  1493
                    }
emc@4248
  1494
                    if (c.param.sym.kind == VAR) {
mcimadamore@2190
  1495
                        c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
mcimadamore@2190
  1496
                    }
mcimadamore@2190
  1497
                    chk.checkType(c.param.vartype.pos(),
mcimadamore@2190
  1498
                                  chk.checkClassType(c.param.vartype.pos(), ctype),
mcimadamore@2190
  1499
                                  syms.throwableType);
mcimadamore@2190
  1500
                    attribStat(c.body, catchEnv);
mcimadamore@2190
  1501
                } finally {
mcimadamore@2190
  1502
                    catchEnv.info.scope.leave();
mcimadamore@2190
  1503
                }
mcimadamore@2190
  1504
            }
mcimadamore@2190
  1505
mcimadamore@2190
  1506
            // Attribute finalizer
mcimadamore@2190
  1507
            if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
mcimadamore@2190
  1508
            result = null;
darcy@1000
  1509
        }
mcimadamore@2190
  1510
        finally {
mcimadamore@2190
  1511
            localEnv.info.scope.leave();
duke@0
  1512
        }
duke@0
  1513
    }
duke@0
  1514
mcimadamore@1438
  1515
    void checkAutoCloseable(DiagnosticPosition pos, Env<AttrContext> env, Type resource) {
mcimadamore@1438
  1516
        if (!resource.isErroneous() &&
darcy@2047
  1517
            types.asSuper(resource, syms.autoCloseableType.tsym) != null &&
darcy@2047
  1518
            !types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself
mcimadamore@1438
  1519
            Symbol close = syms.noSymbol;
jjg@2249
  1520
            Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log);
mcimadamore@1438
  1521
            try {
mcimadamore@1438
  1522
                close = rs.resolveQualifiedMethod(pos,
mcimadamore@1438
  1523
                        env,
sadayapalam@5402
  1524
                        types.skipTypeVars(resource, false),
mcimadamore@1438
  1525
                        names.close,
mcimadamore@5586
  1526
                        List.nil(),
mcimadamore@5586
  1527
                        List.nil());
mcimadamore@1438
  1528
            }
mcimadamore@1438
  1529
            finally {
jjg@2249
  1530
                log.popDiagnosticHandler(discardHandler);
mcimadamore@1438
  1531
            }
mcimadamore@1438
  1532
            if (close.kind == MTH &&
mcimadamore@1438
  1533
                    close.overrides(syms.autoCloseableClose, resource.tsym, types, true) &&
mcimadamore@1438
  1534
                    chk.isHandled(syms.interruptedExceptionType, types.memberType(resource, close).getThrownTypes()) &&
mcimadamore@1438
  1535
                    env.info.lint.isEnabled(LintCategory.TRY)) {
mcimadamore@1438
  1536
                log.warning(LintCategory.TRY, pos, "try.resource.throws.interrupted.exc", resource);
mcimadamore@1438
  1537
            }
mcimadamore@1438
  1538
        }
mcimadamore@1438
  1539
    }
mcimadamore@1438
  1540
duke@0
  1541
    public void visitConditional(JCConditional tree) {
mcimadamore@2190
  1542
        Type condtype = attribExpr(tree.cond, env, syms.booleanType);
mcimadamore@2190
  1543
mcimadamore@2361
  1544
        tree.polyKind = (!allowPoly ||
mcimadamore@4608
  1545
                pt().hasTag(NONE) && pt() != Type.recoveryType && pt() != Infer.anyPoly ||
mcimadamore@2361
  1546
                isBooleanOrNumeric(env, tree)) ?
mcimadamore@2361
  1547
                PolyKind.STANDALONE : PolyKind.POLY;
mcimadamore@2361
  1548
mcimadamore@2361
  1549
        if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
mcimadamore@4608
  1550
            //this means we are returning a poly conditional from void-compatible lambda expression
mcimadamore@2260
  1551
            resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void"));
dbalek@3781
  1552
            tree.polyKind = PolyKind.STANDALONE;
mcimadamore@2190
  1553
        }
mcimadamore@2190
  1554
mcimadamore@2361
  1555
        ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
mcimadamore@2190
  1556
                unknownExprInfo :
mcimadamore@4608
  1557
                resultInfo.dup(conditionalContext(resultInfo.checkContext));
mcimadamore@2190
  1558
mcimadamore@2190
  1559
        Type truetype = attribTree(tree.truepart, env, condInfo);
mcimadamore@2190
  1560
        Type falsetype = attribTree(tree.falsepart, env, condInfo);
mcimadamore@2190
  1561
mcimadamore@2361
  1562
        Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(tree, truetype, falsetype) : pt();
mcimadamore@2190
  1563
        if (condtype.constValue() != null &&
mcimadamore@2190
  1564
                truetype.constValue() != null &&
mcimadamore@2297
  1565
                falsetype.constValue() != null &&
mcimadamore@2297
  1566
                !owntype.hasTag(NONE)) {
mcimadamore@2190
  1567
            //constant folding
mcimadamore@2190
  1568
            owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
mcimadamore@2190
  1569
        }
emc@4248
  1570
        result = check(tree, owntype, KindSelector.VAL, resultInfo);
duke@0
  1571
    }
duke@0
  1572
    //where
mcimadamore@2190
  1573
        private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
mcimadamore@2190
  1574
            switch (tree.getTag()) {
jjg@2213
  1575
                case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
mcimadamore@2260
  1576
                              ((JCLiteral)tree).typetag == BOOLEAN ||
mcimadamore@2260
  1577
                              ((JCLiteral)tree).typetag == BOT;
mcimadamore@2190
  1578
                case LAMBDA: case REFERENCE: return false;
mcimadamore@2190
  1579
                case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
mcimadamore@2190
  1580
                case CONDEXPR:
mcimadamore@2190
  1581
                    JCConditional condTree = (JCConditional)tree;
mcimadamore@2190
  1582
                    return isBooleanOrNumeric(env, condTree.truepart) &&
mcimadamore@2190
  1583
                            isBooleanOrNumeric(env, condTree.falsepart);
mcimadamore@2361
  1584
                case APPLY:
mcimadamore@2361
  1585
                    JCMethodInvocation speculativeMethodTree =
vromero@5854
  1586
                            (JCMethodInvocation)deferredAttr.attribSpeculative(
vromero@5854
  1587
                                    tree, env, unknownExprInfo,
vromero@5854
  1588
                                    argumentAttr.withLocalCacheContext());
mcimadamore@4290
  1589
                    Symbol msym = TreeInfo.symbol(speculativeMethodTree.meth);
mcimadamore@4290
  1590
                    Type receiverType = speculativeMethodTree.meth.hasTag(IDENT) ?
mcimadamore@4290
  1591
                            env.enclClass.type :
mcimadamore@4290
  1592
                            ((JCFieldAccess)speculativeMethodTree.meth).selected.type;
mcimadamore@4290
  1593
                    Type owntype = types.memberType(receiverType, msym).getReturnType();
mcimadamore@4290
  1594
                    return primitiveOrBoxed(owntype);
mcimadamore@2361
  1595
                case NEWCLASS:
mcimadamore@2361
  1596
                    JCExpression className =
mcimadamore@2361
  1597
                            removeClassParams.translate(((JCNewClass)tree).clazz);
mcimadamore@2361
  1598
                    JCExpression speculativeNewClassTree =
vromero@5854
  1599
                            (JCExpression)deferredAttr.attribSpeculative(
vromero@5854
  1600
                                    className, env, unknownTypeInfo,
vromero@5854
  1601
                                    argumentAttr.withLocalCacheContext());
mcimadamore@4290
  1602
                    return primitiveOrBoxed(speculativeNewClassTree.type);
mcimadamore@2190
  1603
                default:
vromero@5854
  1604
                    Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
vromero@5854
  1605
                            argumentAttr.withLocalCacheContext()).type;
mcimadamore@4290
  1606
                    return primitiveOrBoxed(speculativeType);
mcimadamore@2190
  1607
            }
mcimadamore@2190
  1608
        }
mcimadamore@2361
  1609
        //where
mcimadamore@4290
  1610
            boolean primitiveOrBoxed(Type t) {
mcimadamore@4290
  1611
                return (!t.hasTag(TYPEVAR) && types.unboxedTypeOrType(t).isPrimitive());
mcimadamore@4290
  1612
            }
mcimadamore@4290
  1613
mcimadamore@2361
  1614
            TreeTranslator removeClassParams = new TreeTranslator() {
mcimadamore@2361
  1615
                @Override
mcimadamore@2361
  1616
                public void visitTypeApply(JCTypeApply tree) {
mcimadamore@2361
  1617
                    result = translate(tree.clazz);
mcimadamore@2361
  1618
                }
mcimadamore@2361
  1619
            };
mcimadamore@2190
  1620
mcimadamore@4608
  1621
        CheckContext conditionalContext(CheckContext checkContext) {
mcimadamore@4608
  1622
            return new Check.NestedCheckContext(checkContext) {
mcimadamore@4608
  1623
                //this will use enclosing check context to check compatibility of
mcimadamore@4608
  1624
                //subexpression against target type; if we are in a method check context,
mcimadamore@4608
  1625
                //depending on whether boxing is allowed, we could have incompatibilities
mcimadamore@4608
  1626
                @Override
mcimadamore@4608
  1627
                public void report(DiagnosticPosition pos, JCDiagnostic details) {
mcimadamore@4608
  1628
                    enclosingContext.report(pos, diags.fragment("incompatible.type.in.conditional", details));
mcimadamore@4608
  1629
                }
mcimadamore@4608
  1630
            };
mcimadamore@4608
  1631
        }
mcimadamore@4608
  1632
duke@0
  1633
        /** Compute the type of a conditional expression, after
mcimadamore@2190
  1634
         *  checking that it exists.  See JLS 15.25. Does not take into
duke@0
  1635
         *  account the special case where condition and both arms
duke@0
  1636
         *  are constants.
duke@0
  1637
         *
duke@0
  1638
         *  @param pos      The source position to be used for error
duke@0
  1639
         *                  diagnostics.
duke@0
  1640
         *  @param thentype The type of the expression's then-part.
duke@0
  1641
         *  @param elsetype The type of the expression's else-part.
duke@0
  1642
         */
mcimadamore@4399
  1643
        Type condType(DiagnosticPosition pos,
duke@0
  1644
                               Type thentype, Type elsetype) {
duke@0
  1645
            // If same type, that is the result
duke@0
  1646
            if (types.isSameType(thentype, elsetype))
duke@0
  1647
                return thentype.baseType();
duke@0
  1648
ntoda@4105
  1649
            Type thenUnboxed = (thentype.isPrimitive())
duke@0
  1650
                ? thentype : types.unboxedType(thentype);
ntoda@4105
  1651
            Type elseUnboxed = (elsetype.isPrimitive())
duke@0
  1652
                ? elsetype : types.unboxedType(elsetype);
duke@0
  1653
duke@0
  1654
            // Otherwise, if both arms can be converted to a numeric
duke@0
  1655
            // type, return the least numeric type that fits both arms
duke@0
  1656
            // (i.e. return larger of the two, or return int if one
duke@0
  1657
            // arm is short, the other is char).
duke@0
  1658
            if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) {
duke@0
  1659
                // If one arm has an integer subrange type (i.e., byte,
duke@0
  1660
                // short, or char), and the other is an integer constant
duke@0
  1661
                // that fits into the subrange, return the subrange type.
vromero@2810
  1662
                if (thenUnboxed.getTag().isStrictSubRangeOf(INT) &&
vromero@2810
  1663
                    elseUnboxed.hasTag(INT) &&
vromero@2810
  1664
                    types.isAssignable(elseUnboxed, thenUnboxed)) {
duke@0
  1665
                    return thenUnboxed.baseType();
vromero@2810
  1666
                }
vromero@2810
  1667
                if (elseUnboxed.getTag().isStrictSubRangeOf(INT) &&
vromero@2810
  1668
                    thenUnboxed.hasTag(INT) &&
vromero@2810
  1669
                    types.isAssignable(thenUnboxed, elseUnboxed)) {
duke@0
  1670
                    return elseUnboxed.baseType();
vromero@2810
  1671
                }
vromero@2810
  1672
vromero@2810
  1673
                for (TypeTag tag : primitiveTags) {
jjg@2213
  1674
                    Type candidate = syms.typeOfTag[tag.ordinal()];
vromero@2810
  1675
                    if (types.isSubtype(thenUnboxed, candidate) &&
vromero@2810
  1676
                        types.isSubtype(elseUnboxed, candidate)) {
duke@0
  1677
                        return candidate;
vromero@2810
  1678
                    }
duke@0
  1679
                }
duke@0
  1680
            }
duke@0
  1681
duke@0
  1682
            // Those were all the cases that could result in a primitive
ntoda@4105
  1683
            if (thentype.isPrimitive())
ntoda@4105
  1684
                thentype = types.boxedClass(thentype).type;
ntoda@4105
  1685
            if (elsetype.isPrimitive())
ntoda@4105
  1686
                elsetype = types.boxedClass(elsetype).type;
duke@0
  1687
duke@0
  1688
            if (types.isSubtype(thentype, elsetype))
duke@0
  1689
                return elsetype.baseType();
duke@0
  1690
            if (types.isSubtype(elsetype, thentype))
duke@0
  1691
                return thentype.baseType();
duke@0
  1692
ntoda@4105
  1693
            if (thentype.hasTag(VOID) || elsetype.hasTag(VOID)) {
duke@0
  1694
                log.error(pos, "neither.conditional.subtype",
duke@0
  1695
                          thentype, elsetype);
duke@0
  1696
                return thentype.baseType();
duke@0
  1697
            }
duke@0
  1698
duke@0
  1699
            // both are known to be reference types.  The result is
duke@0
  1700
            // lub(thentype,elsetype). This cannot fail, as it will
duke@0
  1701
            // always be possible to infer "Object" if nothing better.
duke@0
  1702
            return types.lub(thentype.baseType(), elsetype.baseType());
duke@0
  1703
        }
duke@0
  1704
vromero@2810
  1705
    final static TypeTag[] primitiveTags = new TypeTag[]{
vromero@2810
  1706
        BYTE,
vromero@2810
  1707
        CHAR,
vromero@2810
  1708
        SHORT,
vromero@2810
  1709
        INT,
vromero@2810
  1710
        LONG,
vromero@2810
  1711
        FLOAT,
vromero@2810
  1712
        DOUBLE,
vromero@2810
  1713
        BOOLEAN,
vromero@2810
  1714
    };
vromero@2810
  1715
duke@0
  1716
    public void visitIf(JCIf tree) {
duke@0
  1717
        attribExpr(tree.cond, env, syms.booleanType);
duke@0
  1718
        attribStat(tree.thenpart, env);
duke@0
  1719
        if (tree.elsepart != null)
duke@0
  1720
            attribStat(tree.elsepart, env);
duke@0
  1721
        chk.checkEmptyIf(tree);
duke@0
  1722
        result = null;
duke@0
  1723
    }
duke@0
  1724
duke@0
  1725
    public void visitExec(JCExpressionStatement tree) {
mcimadamore@1077
  1726
        //a fresh environment is required for 292 inference to work properly ---
mcimadamore@1077
  1727
        //see Infer.instantiatePolymorphicSignatureInstance()
mcimadamore@1077
  1728
        Env<AttrContext> localEnv = env.dup(tree);
mcimadamore@1077
  1729
        attribExpr(tree.expr, localEnv);
duke@0
  1730
        result = null;
duke@0
  1731
    }
duke@0
  1732
duke@0
  1733
    public void visitBreak(JCBreak tree) {
duke@0
  1734
        tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
duke@0
  1735
        result = null;
duke@0
  1736
    }
duke@0
  1737
duke@0
  1738
    public void visitContinue(JCContinue tree) {
duke@0
  1739
        tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
duke@0
  1740
        result = null;
duke@0
  1741
    }
duke@0
  1742
    //where
duke@0
  1743
        /** Return the target of a break or continue statement, if it exists,
duke@0
  1744
         *  report an error if not.
duke@0
  1745
         *  Note: The target of a labelled break or continue is the
duke@0
  1746
         *  (non-labelled) statement tree referred to by the label,
duke@0
  1747
         *  not the tree representing the labelled statement itself.
duke@0
  1748
         *
duke@0
  1749
         *  @param pos     The position to be used for error diagnostics
duke@0
  1750
         *  @param tag     The tag of the jump statement. This is either
duke@0
  1751
         *                 Tree.BREAK or Tree.CONTINUE.
duke@0
  1752
         *  @param label   The label of the jump statement, or null if no
duke@0
  1753
         *                 label is given.
duke@0
  1754
         *  @param env     The environment current at the jump statement.
duke@0
  1755
         */
duke@0
  1756
        private JCTree findJumpTarget(DiagnosticPosition pos,
jjg@1972
  1757
                                    JCTree.Tag tag,
duke@0
  1758
                                    Name label,
duke@0
  1759
                                    Env<AttrContext> env) {
duke@0
  1760
            // Search environments outwards from the point of jump.
duke@0
  1761
            Env<AttrContext> env1 = env;
duke@0
  1762
            LOOP:
duke@0
  1763
            while (env1 != null) {
duke@0
  1764
                switch (env1.tree.getTag()) {
mcimadamore@2191
  1765
                    case LABELLED:
mcimadamore@2191
  1766
                        JCLabeledStatement labelled = (JCLabeledStatement)env1.tree;
mcimadamore@2191
  1767
                        if (label == labelled.label) {
mcimadamore@2191
  1768
                            // If jump is a continue, check that target is a loop.
mcimadamore@2191
  1769
                            if (tag == CONTINUE) {
mcimadamore@2191
  1770
                                if (!labelled.body.hasTag(DOLOOP) &&
mcimadamore@2191
  1771
                                        !labelled.body.hasTag(WHILELOOP) &&
mcimadamore@2191
  1772
                                        !labelled.body.hasTag(FORLOOP) &&
mcimadamore@2191
  1773
                                        !labelled.body.hasTag(FOREACHLOOP))
mcimadamore@2191
  1774
                                    log.error(pos, "not.loop.label", label);
mcimadamore@2191
  1775
                                // Found labelled statement target, now go inwards
mcimadamore@2191
  1776
                                // to next non-labelled tree.
mcimadamore@2191
  1777
                                return TreeInfo.referencedStatement(labelled);
mcimadamore@2191
  1778
                            } else {
mcimadamore@2191
  1779
                                return labelled;
mcimadamore@2191
  1780
                            }
duke@0
  1781
                        }
mcimadamore@2191
  1782
                        break;
mcimadamore@2191
  1783
                    case DOLOOP:
mcimadamore@2191
  1784
                    case WHILELOOP:
mcimadamore@2191
  1785
                    case FORLOOP:
mcimadamore@2191
  1786
                    case FOREACHLOOP:
mcimadamore@2191
  1787
                        if (label == null) return env1.tree;
mcimadamore@2191
  1788
                        break;
mcimadamore@2191
  1789
                    case SWITCH:
mcimadamore@2191
  1790
                        if (label == null && tag == BREAK) return env1.tree;
mcimadamore@2191
  1791
                        break;
mcimadamore@2191
  1792
                    case LAMBDA:
mcimadamore@2191
  1793
                    case METHODDEF:
mcimadamore@2191
  1794
                    case CLASSDEF:
mcimadamore@2191
  1795
                        break LOOP;
mcimadamore@2191
  1796
                    default:
duke@0
  1797
                }
duke@0
  1798
                env1 = env1.next;
duke@0
  1799
            }
duke@0
  1800
            if (label != null)
duke@0
  1801
                log.error(pos, "undef.label", label);
jjg@1972
  1802
            else if (tag == CONTINUE)
duke@0
  1803
                log.error(pos, "cont.outside.loop");
duke@0
  1804
            else
duke@0
  1805
                log.error(pos, "break.outside.switch.loop");
duke@0
  1806
            return null;
duke@0
  1807
        }
duke@0
  1808
duke@0
  1809
    public void visitReturn(JCReturn tree) {
duke@0
  1810
        // Check that there is an enclosing method which is
duke@0
  1811
        // nested within than the enclosing class.
mcimadamore@2190
  1812
        if (env.info.returnResult == null) {
duke@0
  1813
            log.error(tree.pos(), "ret.outside.meth");
duke@0
  1814
        } else {
duke@0
  1815
            // Attribute return expression, if it exists, and check that
duke@0
  1816
            // it conforms to result type of enclosing method.
mcimadamore@2190
  1817
            if (tree.expr != null) {
jjg@2213
  1818
                if (env.info.returnResult.pt.hasTag(VOID)) {
mcimadamore@2260
  1819
                    env.info.returnResult.checkContext.report(tree.expr.pos(),
mcimadamore@2260
  1820
                              diags.fragment("unexpected.ret.val"));
mcimadamore@2190
  1821
                }
mcimadamore@2190
  1822
                attribTree(tree.expr, env, env.info.returnResult);
mcimadamore@2880
  1823
            } else if (!env.info.returnResult.pt.hasTag(VOID) &&
mcimadamore@2880
  1824
                    !env.info.returnResult.pt.hasTag(NONE)) {
mcimadamore@2260
  1825
                env.info.returnResult.checkContext.report(tree.pos(),
mcimadamore@2260
  1826
                              diags.fragment("missing.ret.val"));
duke@0
  1827
            }
duke@0
  1828
        }
duke@0
  1829
        result = null;
duke@0
  1830
    }
duke@0
  1831
duke@0
  1832
    public void visitThrow(JCThrow tree) {
mcimadamore@2260
  1833
        Type owntype = attribExpr(tree.expr, env, allowPoly ? Type.noType : syms.throwableType);
mcimadamore@2260
  1834
        if (allowPoly) {
mcimadamore@2260
  1835
            chk.checkType(tree, owntype, syms.throwableType);
mcimadamore@2260
  1836
        }
duke@0
  1837
        result = null;
duke@0
  1838
    }
duke@0
  1839
duke@0
  1840
    public void visitAssert(JCAssert tree) {
duke@0
  1841
        attribExpr(tree.cond, env, syms.booleanType);
duke@0
  1842
        if (tree.detail != null) {
duke@0
  1843
            chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail, env));
duke@0
  1844
        }
duke@0
  1845
        result = null;
duke@0
  1846
    }
duke@0
  1847
duke@0
  1848
     /** Visitor method for method invocations.
duke@0
  1849
     *  NOTE: The method part of an application will have in its type field
duke@0
  1850
     *        the return type of the method, not the method's type itself!
duke@0
  1851
     */
duke@0
  1852
    public void visitApply(JCMethodInvocation tree) {
duke@0
  1853
        // The local environment of a method application is
duke@0
  1854
        // a new environment nested in the current one.
duke@0
  1855
        Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
duke@0
  1856
duke@0
  1857
        // The types of the actual method arguments.
dbalek@4654
  1858
        List<Type> argtypes = null;
duke@0
  1859
duke@0
  1860
        // The types of the actual method type arguments.
duke@0
  1861
        List<Type> typeargtypes = null;
duke@0
  1862
duke@0
  1863
        Name methName = TreeInfo.name(tree.meth);
duke@0
  1864
duke@0
  1865
        boolean isConstructorCall =
duke@0
  1866
            methName == names._this || methName == names._super;
duke@0
  1867
alundblad@3063
  1868
        ListBuffer<Type> argtypesBuf = new ListBuffer<>();
duke@0
  1869
        if (isConstructorCall) {
duke@0
  1870
            // We are seeing a ...this(...) or ...super(...) call.
duke@0
  1871
            // Check that this is the first statement in a constructor.
dbalek@111
  1872
            checkFirstConstructorStat(tree, env);
dbalek@4426
  1873
dbalek@111
  1874
            // Record the fact
dbalek@111
  1875
            // that this is a constructor call (using isSelfCall).
dbalek@111
  1876
            localEnv.info.isSelfCall = true;
mcimadamore@18
  1877
dbalek@111
  1878
            // Attribute arguments, yielding list of argument types.
dbalek@4426
  1879
            KindSelector kind = attribArgs(KindSelector.MTH, tree.args, localEnv, argtypesBuf);
dbalek@2866
  1880
            argtypes = argtypesBuf.toList();
dbalek@111
  1881
            typeargtypes = attribTypes(tree.typeargs, localEnv);
mcimadamore@18
  1882
dbalek@111
  1883
            // Variable `site' points to the class in which the called
dbalek@111
  1884
            // constructor is defined.
dbalek@111
  1885
            Type site = env.enclClass.sym.type;
dbalek@111
  1886
            if (methName == names._super) {
dbalek@111
  1887
                if (site == syms.objectType) {
dbalek@111
  1888
                    log.error(tree.meth.pos(), "no.superclass", site);
dbalek@391
  1889
                    site = types.createErrorType(syms.objectType);
dbalek@111
  1890
                } else {
dbalek@111
  1891
                    site = types.supertype(site);
dbalek@111
  1892
                }
dbalek@111
  1893
            }
dbalek@111
  1894
dbalek@2330
  1895
            if (site.hasTag(CLASS) || site.hasTag(ERROR)) {
dbalek@721
  1896
                Type encl = site.getEnclosingType();
dbalek@2330
  1897
                while (encl != null && encl.hasTag(TYPEVAR))
dbalek@721
  1898
                    encl = encl.getUpperBound();
dbalek@2330
  1899
                if (encl.hasTag(CLASS)) {
dbalek@111
  1900
                    // we are calling a nested class
dbalek@111
  1901
dbalek@2330
  1902
                    if (tree.meth.hasTag(SELECT)) {
dbalek@111
  1903
                        JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
dbalek@111
  1904
dbalek@111
  1905
                        // We are seeing a prefixed call, of the form
dbalek@111
  1906
                        //     <expr>.super(...).
dbalek@111
  1907
                        // Check that the prefix expression conforms
dbalek@111
  1908
                        // to the outer instance type of the class.
dbalek@111
  1909
                        chk.checkRefType(qualifier.pos(),
dbalek@111
  1910
                                         attribExpr(qualifier, localEnv,
dbalek@4426
  1911
                                                    encl));
dbalek@111
  1912
                    } else if (methName == names._super) {
dbalek@111
  1913
                        // qualifier omitted; check for existence
dbalek@111
  1914
                        // of an appropriate implicit qualifier.
dbalek@111
  1915
                        rs.resolveImplicitThis(tree.meth.pos(),
dbalek@1451
  1916
                                               localEnv, site, true);
duke@0
  1917
                    }
dbalek@2330
  1918
                } else if (tree.meth.hasTag(SELECT)) {
dbalek@111
  1919
                    log.error(tree.meth.pos(), "illegal.qual.not.icls",
dbalek@111
  1920
                              site.tsym);
duke@0
  1921
                }
duke@0
  1922
dbalek@111
  1923
                // if we're calling a java.lang.Enum constructor,
dbalek@111
  1924
                // prefix the implicit String and int parameters
dbalek@4426
  1925
                if (site.tsym == syms.enumSym)
dbalek@111
  1926
                    argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
mcimadamore@18
  1927
dbalek@111
  1928
                // Resolve the called constructor under the assumption
dbalek@111
  1929
                // that we are referring to a superclass instance of the
dbalek@111
  1930
                // current instance (JLS ???).
dbalek@111
  1931
                boolean selectSuperPrev = localEnv.info.selectSuper;
dbalek@111
  1932
                localEnv.info.selectSuper = true;
dbalek@2330
  1933
                localEnv.info.pendingResolutionPhase = null;
dbalek@111
  1934
                Symbol sym = rs.resolveConstructor(
dbalek@111
  1935
                    tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
dbalek@111
  1936
                localEnv.info.selectSuper = selectSuperPrev;
mcimadamore@18
  1937
dbalek@111
  1938
                // Set method symbol to resolved constructor...
dbalek@111
  1939
                TreeInfo.setSymbol(tree.meth, sym);
mcimadamore@18
  1940
dbalek@111
  1941
                // ...and check that it is legal in the current context.
dbalek@111
  1942
                // (this will also set the tree's type)
dbalek@2330
  1943
                Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
dbalek@4426
  1944
                checkId(tree.meth, site, sym, localEnv,
dbalek@4426
  1945
                        new ResultInfo(kind, mpt));
duke@0
  1946
            }
duke@0
  1947
            result = tree.type = syms.voidType;
duke@0
  1948
        } else {
duke@0
  1949
            // Otherwise, we are seeing a regular method call.
duke@0
  1950
            // Attribute the arguments, yielding list of argument types, ...
dbalek@4426
  1951
            KindSelector kind;
jlahoda@5
  1952
            try {
dbalek@4426
  1953
                kind = attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf);
dbalek@4654
  1954
            } catch (BreakAttr bae) {
dbalek@2866
  1955
                argtypes = argtypesBuf.toList();
dbalek@721
  1956
                typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
dbalek@4654
  1957
                Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
dbalek@4654
  1958
                localEnv.info.pendingResolutionPhase = null;
dbalek@4654
  1959
                attribTree(tree.meth, localEnv, new ResultInfo(KindSelector.VAL_POLY, mpt, resultInfo.checkContext));
jlahoda@5
  1960
                throw bae;
jlahoda@5
  1961
            }
sadayapalam@4424
  1962
            argtypes = argtypesBuf.toList();
sadayapalam@4424
  1963
            typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
duke@0
  1964
duke@0
  1965
            // ... and attribute the method using as a prototype a methodtype
duke@0
  1966
            // whose formal argument types is exactly the list of actual
duke@0
  1967
            // arguments (this will also set the method symbol).
mcimadamore@2112
  1968
            Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
mcimadamore@2190
  1969
            localEnv.info.pendingResolutionPhase = null;
vromero@2834
  1970
            Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(kind, mpt, resultInfo.checkContext));
duke@0
  1971
duke@0
  1972
            // Compute the result type.
duke@0
  1973
            Type restype = mtype.getReturnType();
jjg@2213
  1974
            if (restype.hasTag(WILDCARD))
mcimadamore@1121
  1975
                throw new AssertionError(mtype);
duke@0
  1976
mcimadamore@2195
  1977
            Type qualifier = (tree.meth.hasTag(SELECT))
duke@0
  1978
                    ? ((JCFieldAccess) tree.meth).selected.type
duke@0
  1979
                    : env.enclClass.sym.type;
mcimadamore@5279
  1980
            Symbol msym = TreeInfo.symbol(tree.meth);
mcimadamore@5279
  1981
            restype = adjustMethodReturnType(msym, qualifier, methName, argtypes, restype);
duke@0
  1982
mcimadamore@1285
  1983
            chk.checkRefTypes(tree.typeargs, typeargtypes);
jrose@557
  1984
duke@0
  1985
            // Check that value of resulting type is admissible in the
duke@0
  1986
            // current context.  Also, capture the return type
mcimadamore@4676
  1987
            Type capturedRes = resultInfo.checkContext.inferenceContext().cachedCapture(tree, restype, true);
mcimadamore@4676
  1988
            result = check(tree, capturedRes, KindSelector.VAL, resultInfo);
duke@0
  1989
        }
mcimadamore@300
  1990
        chk.validate(tree.typeargs, localEnv);
duke@0
  1991
    }
duke@0
  1992
    //where
mcimadamore@5279
  1993
        Type adjustMethodReturnType(Symbol msym, Type qualifierType, Name methodName, List<Type> argtypes, Type restype) {
mcimadamore@5279
  1994
            if (msym != null &&
mcimadamore@5279
  1995
                    msym.owner == syms.objectType.tsym &&
mcimadamore@5279
  1996
                    methodName == names.getClass &&
mcimadamore@5279
  1997
                    argtypes.isEmpty()) {
mcimadamore@5279
  1998
                // as a special case, x.getClass() has type Class<? extends |X|>
mcimadamore@5279
  1999
                return new ClassType(restype.getEnclosingType(),
mcimadamore@5586
  2000
                        List.of(new WildcardType(types.erasure(qualifierType),
mcimadamore@5279
  2001
                                BoundKind.EXTENDS,
mcimadamore@5279
  2002
                                syms.boundClass)),
mcimadamore@5279
  2003
                        restype.tsym,
mcimadamore@5279
  2004
                        restype.getMetadata());
mcimadamore@5279
  2005
            } else if (msym != null &&
mcimadamore@5279
  2006
                    msym.owner == syms.arrayClass &&
mcimadamore@5279
  2007
                    methodName == names.clone &&
mcimadamore@5279
  2008
                    types.isArray(qualifierType)) {
mcimadamore@2195
  2009
                // as a special case, array.clone() has a result that is
mcimadamore@2195
  2010
                // the same as static type of the array being cloned
mcimadamore@2195
  2011
                return qualifierType;
mcimadamore@2195
  2012
            } else {
mcimadamore@2195
  2013
                return restype;
mcimadamore@2195
  2014
            }
mcimadamore@2195
  2015
        }
mcimadamore@2195
  2016
duke@0
  2017
        /** Check that given application node appears as first statement
duke@0
  2018
         *  in a constructor call.
duke@0
  2019
         *  @param tree   The application node
duke@0
  2020
         *  @param env    The environment current at the application.
duke@0
  2021
         */
duke@0
  2022
        boolean checkFirstConstructorStat(JCMethodInvocation tree, Env<AttrContext> env) {
duke@0
  2023
            JCMethodDecl enclMethod = env.enclMethod;
duke@0
  2024
            if (enclMethod != null && enclMethod.name == names.init) {
duke@0
  2025
                JCBlock body = enclMethod.body;
jjg@1972
  2026
                if (body.stats.head.hasTag(EXEC) &&
duke@0
  2027
                    ((JCExpressionStatement) body.stats.head).expr == tree)
duke@0
  2028
                    return true;
duke@0
  2029
            }
duke@0
  2030
            log.error(tree.pos(),"call.must.be.first.stmt.in.ctor",
duke@0
  2031
                      TreeInfo.name(tree.meth));
duke@0
  2032
            return false;
duke@0
  2033
        }
duke@0
  2034
duke@0
  2035
        /** Obtain a method type with given argument types.
duke@0
  2036
         */
mcimadamore@2112
  2037
        Type newMethodTemplate(Type restype, List<Type> argtypes, List<Type> typeargtypes) {
mcimadamore@5586
  2038
            MethodType mt = new MethodType(argtypes, restype, List.nil(), syms.methodClass);
duke@0
  2039
            return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt);
duke@0
  2040
        }
duke@0
  2041
mcimadamore@2190
  2042
    public void visitNewClass(final JCNewClass tree) {
jjg@289
  2043
        Type owntype = types.createErrorType(tree.type);
duke@0
  2044
duke@0
  2045
        // The local environment of a class creation is
duke@0
  2046
        // a new environment nested in the current one.
duke@0
  2047
        Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
duke@0
  2048
duke@0
  2049
        // The anonymous inner class definition of the new expression,
duke@0
  2050
        // if one is defined by it.
duke@0
  2051
        JCClassDecl cdef = tree.def;
duke@0
  2052
duke@0
  2053
        // If enclosing class is given, attribute it, and
duke@0
  2054
        // complete class name to be fully qualified
duke@0
  2055
        JCExpression clazz = tree.clazz; // Class field following new
jjg@2372
  2056
        JCExpression clazzid;            // Identifier in class field
jjg@2372
  2057
        JCAnnotatedType annoclazzid;     // Annotated type enclosing clazzid
jjg@2372
  2058
        annoclazzid = null;
jjg@2372
  2059
jjg@2372
  2060
        if (clazz.hasTag(TYPEAPPLY)) {
jjg@2372
  2061
            clazzid = ((JCTypeApply) clazz).clazz;
jjg@2372
  2062
            if (clazzid.hasTag(ANNOTATED_TYPE)) {
jjg@2372
  2063
                annoclazzid = (JCAnnotatedType) clazzid;
jjg@2372
  2064
                clazzid = annoclazzid.underlyingType;
jjg@2372
  2065
            }
jfranck@4203
  2066
        } else {
jfranck@4203
  2067
            if (clazz.hasTag(ANNOTATED_TYPE)) {
jjg@2372
  2068
                annoclazzid = (JCAnnotatedType) clazz;
jjg@2372
  2069
                clazzid = annoclazzid.underlyingType;
jjg@2372
  2070
            } else {
jjg@2372
  2071
                clazzid = clazz;
jjg@2372
  2072
            }
jfranck@4203
  2073
        }
duke@0
  2074
duke@0
  2075
        JCExpression clazzid1 = clazzid; // The same in fully qualified form
duke@0
  2076
duke@0
  2077
        if (tree.encl != null) {
duke@0
  2078
            // We are seeing a qualified new, of the form
duke@0
  2079
            //    <expr>.new C <...> (...) ...
duke@0
  2080
            // In this case, we let clazz stand for the name of the
duke@0
  2081
            // allocated class C prefixed with the type of the qualifier
duke@0
  2082
            // expression, so that we can
duke@0
  2083
            // resolve it with standard techniques later. I.e., if
duke@0
  2084
            // <expr> has type T, then <expr>.new C <...> (...)
duke@0
  2085
            // yields a clazz T.C.
duke@0
  2086
            Type encltype = chk.checkRefType(tree.encl.pos(),
duke@0
  2087
                                             attribExpr(tree.encl, env));
jjg@2372
  2088
            // TODO 308: in <expr>.new C, do we also want to add the type annotations
jjg@2372
  2089
            // from expr to the combined type, or not? Yes, do this.
duke@0
  2090
            clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
duke@0
  2091
                                                 ((JCIdent) clazzid).name);
jjg@2372
  2092
ksrini@2930
  2093
            EndPosTable endPosTable = this.env.toplevel.endPositions;
ksrini@2930
  2094
            endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
jfranck@4203
  2095
            if (clazz.hasTag(ANNOTATED_TYPE)) {
jfranck@4203
  2096
                JCAnnotatedType annoType = (JCAnnotatedType) clazz;
jfranck@4203
  2097
                List<JCAnnotation> annos = annoType.annotations;
jfranck@4203
  2098
jfranck@4203
  2099
                if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
jjg@2372
  2100
                    clazzid1 = make.at(tree.pos).
jjg@2372
  2101
                        TypeApply(clazzid1,
jjg@2372
  2102
                                  ((JCTypeApply) clazz).arguments);
jjg@2372
  2103
                }
jjg@2372
  2104
jjg@2372
  2105
                clazzid1 = make.at(tree.pos).
jjg@2372
  2106
                    AnnotatedType(annos, clazzid1);
jjg@2372
  2107
            } else if (clazz.hasTag(TYPEAPPLY)) {
jjg@2372
  2108
                clazzid1 = make.at(tree.pos).
duke@0
  2109
                    TypeApply(clazzid1,
duke@0
  2110
                              ((JCTypeApply) clazz).arguments);
jjg@2372
  2111
            }
jjg@2372
  2112
jjg@2372
  2113
            clazz = clazzid1;
duke@0
  2114
        }
duke@0
  2115
duke@0
  2116
        // Attribute clazz expression and store
duke@0
  2117
        // symbol + type back into the attributed tree.
jjg@4454
  2118
        Type clazztype;
jjg@4454
  2119
jjg@4454
  2120
        try {
jjg@4454
  2121
            env.info.isNewClass = true;
jjg@4454
  2122
            clazztype = TreeInfo.isEnumInit(env.tree) ?
jjg@4454
  2123
                attribIdentAsEnumType(env, (JCIdent)clazz) :
jjg@4454
  2124
                attribType(clazz, env);
jjg@4454
  2125
        } finally {
jjg@4454
  2126
            env.info.isNewClass = false;
jjg@4454
  2127
        }
mcimadamore@2113
  2128
mcimadamore@1398
  2129
        clazztype = chk.checkDiamond(tree, clazztype);
mcimadamore@300
  2130
        chk.validate(clazz, localEnv);
duke@0
  2131
        if (tree.encl != null) {
duke@0
  2132
            // We have to work in this case to store
duke@0
  2133
            // symbol + type back into the attributed tree.
duke@0
  2134
            tree.clazz.type = clazztype;
duke@0
  2135
            TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
duke@0
  2136
            clazzid.type = ((JCIdent) clazzid).sym.type;
jjg@2372
  2137
            if (annoclazzid != null) {
jjg@2372
  2138
                annoclazzid.type = clazzid.type;
jjg@2372
  2139
            }
duke@0
  2140
            if (!clazztype.isErroneous()) {
duke@0
  2141
                if (cdef != null && clazztype.tsym.isInterface()) {
duke@0
  2142
                    log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new");
duke@0
  2143
                } else if (clazztype.tsym.isStatic()) {
duke@0
  2144
                    log.error(tree.encl.pos(), "qualified.new.of.static.class", clazztype.tsym);
duke@0
  2145
                }
duke@0
  2146
            }
duke@0
  2147
        } else if (!clazztype.tsym.isInterface() &&
jjg@2213
  2148
                   clazztype.getEnclosingType().hasTag(CLASS)) {
duke@0
  2149
            // Check for the existence of an apropos outer instance
duke@0
  2150
            rs.resolveImplicitThis(tree.pos(), env, clazztype);
duke@0
  2151
        }
duke@0
  2152
duke@0
  2153
        // Attribute constructor arguments.
alundblad@3063
  2154
        ListBuffer<Type> argtypesBuf = new ListBuffer<>();
emc@4248
  2155
        final KindSelector pkind =
mcimadamore@4313
  2156
            attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf);
vromero@2834
  2157
        List<Type> argtypes = argtypesBuf.toList();
jfranck@4203
  2158
        List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
duke@0
  2159
duke@0
  2160
        // If we have made no mistakes in the class type...
dbalek@2330
  2161
        boolean wasError = clazztype.hasTag(ERROR);
dbalek@2330
  2162
        if (clazztype.hasTag(CLASS) || wasError) {
duke@0
  2163
            // Enums may not be instantiated except implicitly
ntoda@4105
  2164
            if ((clazztype.tsym.flags_field & Flags.ENUM) != 0 &&
jjg@1972
  2165
                (!env.tree.hasTag(VARDEF) ||
ntoda@4105
  2166
                 (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 ||
duke@0
  2167
                 ((JCVariableDecl) env.tree).init != tree))
duke@0
  2168
                log.error(tree.pos(), "enum.cant.be.instantiated");
sadayapalam@4445
  2169
sadayapalam@4445
  2170
            boolean isSpeculativeDiamondInferenceRound = TreeInfo.isDiamond(tree) &&
sadayapalam@4445
  2171
                    resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
sadayapalam@4445
  2172
            boolean skipNonDiamondPath = false;
duke@0
  2173
            // Check that class is not abstract
sadayapalam@4445
  2174
            if (cdef == null && !isSpeculativeDiamondInferenceRound && // class body may be nulled out in speculative tree copy
duke@0
  2175
                (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
duke@0
  2176
                log.error(tree.pos(), "abstract.cant.be.instantiated",
duke@0
  2177
                          clazztype.tsym);
sadayapalam@4445
  2178
                skipNonDiamondPath = true;
duke@0
  2179
            } else if (cdef != null && clazztype.tsym.isInterface()) {
duke@0
  2180
                // Check that no constructor arguments are given to
duke@0
  2181
                // anonymous classes implementing an interface
duke@0
  2182
                if (!argtypes.isEmpty())
duke@0
  2183
                    log.error(tree.args.head.pos(), "anon.class.impl.intf.no.args");
duke@0
  2184
duke@0
  2185
                if (!typeargtypes.isEmpty())
duke@0
  2186
                    log.error(tree.typeargs.head.pos(), "anon.class.impl.intf.no.typeargs");
duke@0
  2187
duke@0
  2188
                // Error recovery: pretend no arguments were supplied.
duke@0
  2189
                argtypes = List.nil();
duke@0
  2190
                typeargtypes = List.nil();
sadayapalam@4445
  2191
                skipNonDiamondPath = true;
dbalek@4657
  2192
            }
dbalek@4657
  2193
            if (TreeInfo.isDiamond(tree) && !wasError) {
mcimadamore@2190
  2194
                ClassType site = new ClassType(clazztype.getEnclosingType(),
mcimadamore@2190
  2195
                            clazztype.tsym.type.getTypeArguments(),
emc@3988
  2196
                                               clazztype.tsym,
emc@4221
  2197
                                               clazztype.getMetadata());
mcimadamore@2190
  2198
mcimadamore@2190
  2199
                Env<AttrContext> diamondEnv = localEnv.dup(tree);
mcimadamore@2190
  2200
                diamondEnv.info.selectSuper = cdef != null;
mcimadamore@2190
  2201
                diamondEnv.info.pendingResolutionPhase = null;
mcimadamore@2190
  2202
mcimadamore@2190
  2203
                //if the type of the instance creation expression is a class type
mcimadamore@2190
  2204
                //apply method resolution inference (JLS 15.12.2.7). The return type
mcimadamore@2190
  2205
                //of the resolved constructor will be a partially instantiated type
mcimadamore@2190
  2206
                Symbol constructor = rs.resolveDiamond(tree.pos(),
mcimadamore@2190
  2207
                            diamondEnv,
mcimadamore@2190
  2208
                            site,
mcimadamore@2190
  2209
                            argtypes,
mcimadamore@2190
  2210
                            typeargtypes);
mcimadamore@2190
  2211
                tree.constructor = constructor.baseSymbol();
mcimadamore@2190
  2212
mcimadamore@2190
  2213
                final TypeSymbol csym = clazztype.tsym;
mcimadamore@4608
  2214
                ResultInfo diamondResult = new ResultInfo(pkind, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes),
mcimadamore@4608
  2215
                        diamondContext(tree, csym, resultInfo.checkContext), CheckMode.NO_TREE_UPDATE);
mcimadamore@2190
  2216
                Type constructorType = tree.constructorType = types.createErrorType(clazztype);
sadayapalam@4483
  2217
                constructorType = checkId(tree, site,
mcimadamore@2190
  2218
                        constructor,
mcimadamore@2190
  2219
                        diamondEnv,
mcimadamore@2190
  2220
                        diamondResult);
mcimadamore@2190
  2221
mcimadamore@2190
  2222
                tree.clazz.type = types.createErrorType(clazztype);
mcimadamore@2190
  2223
                if (!constructorType.isErroneous()) {
sadayapalam@4445
  2224
                    tree.clazz.type = clazz.type = constructorType.getReturnType();
mcimadamore@2190
  2225
                    tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
dbalek@2924
  2226
                } else if (errArgs(tree.args)) {
dbalek@2924
  2227
                    Symbol s = null;
dbalek@4426
  2228
                    for (Symbol sym : site.tsym.members().getSymbolsByName(names.init)) {
dbalek@4426
  2229
                        if (s == null || sym.asType().getParameterTypes().isEmpty())
dbalek@4426
  2230
                            s = sym;
dbalek@2924
  2231
                    }
dbalek@2924
  2232
                    if (s != null) {
dbalek@2924
  2233
                        List<Type> atypes = s.asType().getParameterTypes();
dbalek@2924
  2234
                        constructor = rs.resolveDiamond(tree.pos(),
dbalek@2924
  2235
                            diamondEnv,
dbalek@2924
  2236
                            site,
dbalek@2924
  2237
                            atypes,
dbalek@2924
  2238
                            typeargtypes);
dbalek@4426
  2239
                        diamondResult = new ResultInfo(KindSelector.MTH, newMethodTemplate(resultInfo.pt, atypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) {
dbalek@2924
  2240
                            @Override
dbalek@2924
  2241
                            public void report(DiagnosticPosition _unused, JCDiagnostic details) {
dbalek@2924
  2242
                            }
dbalek@2924
  2243
                        });
dbalek@2924
  2244
                        constructorType = checkId(tree, site,
dbalek@2924
  2245
                                constructor,
dbalek@2924
  2246
                                diamondEnv,
dbalek@2924
  2247
                                diamondResult);
dbalek@2924
  2248
                        if (!constructorType.isErroneous())
dbalek@2924
  2249
                            tree.clazz.type = constructorType.getReturnType();
dbalek@2924
  2250
                    }
mcimadamore@2190
  2251
                }
mcimadamore@2190
  2252
                clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
duke@0
  2253
            }
duke@0
  2254
duke@0
  2255
            // Resolve the called constructor under the assumption
duke@0
  2256
            // that we are referring to a superclass instance of the
duke@0
  2257
            // current instance (JLS ???).
sadayapalam@4445
  2258
            else if (!skipNonDiamondPath) {
mcimadamore@1518
  2259
                //the following code alters some of the fields in the current
mcimadamore@1518
  2260
                //AttrContext - hence, the current context must be dup'ed in
mcimadamore@1518
  2261
                //order to avoid downstream failures
mcimadamore@1518
  2262
                Env<AttrContext> rsEnv = localEnv.dup(tree);
mcimadamore@1518
  2263
                rsEnv.info.selectSuper = cdef != null;
mcimadamore@2190
  2264
                rsEnv.info.pendingResolutionPhase = null;
duke@0
  2265
                tree.constructor = rs.resolveConstructor(
mcimadamore@1518
  2266
                    tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
mcimadamore@2180
  2267
                if (cdef == null) { //do not check twice!
sadayapalam@4483
  2268
                    tree.constructorType = checkId(tree,
mcimadamore@2180
  2269
                            clazztype,
mcimadamore@2180
  2270
                            tree.constructor,
mcimadamore@2180
  2271
                            rsEnv,
sadayapalam@4483
  2272
                            new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
mcimadamore@2190
  2273
                    if (rsEnv.info.lastResolveVarargs())
dbalek@2330
  2274
                        Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);                    
dbalek@2330
  2275
                    Env<AttrContext> enclosing;
dbalek@2330
  2276
                    if (tree.constructor.kind == MTH && tree.constructor.type.isErroneous() && ((enclosing = enter.getEnv(tree.constructor.enclClass())) == null || enclosing.toplevel != env.toplevel)) {
dbalek@2330
  2277
                        log.error(tree, "type.error", tree.constructor);
dbalek@2330
  2278
                    }
mcimadamore@2180
  2279
                }
duke@0
  2280
            }
duke@0
  2281
duke@0
  2282
            if (cdef != null) {
sadayapalam@4445
  2283
                visitAnonymousClassDefinition(tree, clazz, clazztype, cdef, localEnv, argtypes, typeargtypes, pkind);
sadayapalam@4445
  2284
                return;
sadayapalam@4424
  2285
            }
sadayapalam@4424
  2286
sadayapalam@4424
  2287
            if (tree.constructor != null && tree.constructor.kind == MTH)
dbalek@4654
  2288
                owntype = wasError ? types.createErrorType(clazztype) : clazztype;
sadayapalam@4424
  2289
        }
sadayapalam@4424
  2290
        result = check(tree, owntype, KindSelector.VAL, resultInfo);
sadayapalam@4424
  2291
        InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
sadayapalam@4424
  2292
        if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) {
sadayapalam@4424
  2293
            //we need to wait for inference to finish and then replace inference vars in the constructor type
sadayapalam@4424
  2294
            inferenceContext.addFreeTypeListener(List.of(tree.constructorType),
sadayapalam@4424
  2295
                    instantiatedContext -> {
sadayapalam@4424
  2296
                        tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
sadayapalam@4424
  2297
                    });
sadayapalam@4424
  2298
        }
sadayapalam@4424
  2299
        chk.validate(tree.typeargs, localEnv);
sadayapalam@4424
  2300
    }
dbalek@4654
  2301
    //where
dbalek@4654
  2302
    private boolean errArgs(List<JCExpression> args) {
dbalek@4654
  2303
        for (JCExpression arg : args) {
dbalek@4654
  2304
            if (arg.hasTag(Tag.ERRONEOUS))
dbalek@4654
  2305
                return true;
dbalek@4654
  2306
        }
dbalek@4654
  2307
        return false;
dbalek@4654
  2308
    }
sadayapalam@4424
  2309
sadayapalam@4445
  2310
        // where
sadayapalam@4445
  2311
        private void visitAnonymousClassDefinition(JCNewClass tree, JCExpression clazz, Type clazztype,
sadayapalam@4445
  2312
                                                   JCClassDecl cdef, Env<AttrContext> localEnv,
sadayapalam@4445
  2313
                                                   List<Type> argtypes, List<Type> typeargtypes,
sadayapalam@4445
  2314
                                                   KindSelector pkind) {
sadayapalam@4445
  2315
            // We are seeing an anonymous class instance creation.
sadayapalam@4445
  2316
            // In this case, the class instance creation
sadayapalam@4445
  2317
            // expression
sadayapalam@4445
  2318
            //
sadayapalam@4445
  2319
            //    E.new <typeargs1>C<typargs2>(args) { ... }
sadayapalam@4445
  2320
            //
sadayapalam@4445
  2321
            // is represented internally as
sadayapalam@4445
  2322
            //
sadayapalam@4445
  2323
            //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
sadayapalam@4445
  2324
            //
sadayapalam@4445
  2325
            // This expression is then *transformed* as follows:
sadayapalam@4445
  2326
            //
sadayapalam@4445
  2327
            // (1) add an extends or implements clause
sadayapalam@4445
  2328
            // (2) add a constructor.
sadayapalam@4445
  2329
            //
sadayapalam@4445
  2330
            // For instance, if C is a class, and ET is the type of E,
sadayapalam@4445
  2331
            // the expression
sadayapalam@4445
  2332
            //
sadayapalam@4445
  2333
            //    E.new <typeargs1>C<typargs2>(args) { ... }
sadayapalam@4445
  2334
            //
sadayapalam@4445
  2335
            // is translated to (where X is a fresh name and typarams is the
sadayapalam@4445
  2336
            // parameter list of the super constructor):
sadayapalam@4445
  2337
            //
sadayapalam@4445
  2338
            //   new <typeargs1>X(<*nullchk*>E, args) where
sadayapalam@4445
  2339
            //     X extends C<typargs2> {
sadayapalam@4445
  2340
            //       <typarams> X(ET e, args) {
sadayapalam@4445
  2341
            //         e.<typeargs1>super(args)
sadayapalam@4445
  2342
            //       }
sadayapalam@4445
  2343
            //       ...
sadayapalam@4445
  2344
            //     }
sadayapalam@4445
  2345
            InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
sadayapalam@4445
  2346
            final boolean isDiamond = TreeInfo.isDiamond(tree);
sadayapalam@4445
  2347
            if (isDiamond
sadayapalam@4445
  2348
                    && ((tree.constructorType != null && inferenceContext.free(tree.constructorType))
sadayapalam@4445
  2349
                    || (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) {
sadayapalam@4533
  2350
                final ResultInfo resultInfoForClassDefinition = this.resultInfo;
sadayapalam@4445
  2351
                inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type),
sadayapalam@4445
  2352
                        instantiatedContext -> {
sadayapalam@4445
  2353
                            tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
sadayapalam@4619
  2354
                            tree.clazz.type = clazz.type = instantiatedContext.asInstType(clazz.type);
sadayapalam@4533
  2355
                            ResultInfo prevResult = this.resultInfo;
sadayapalam@4533
  2356
                            try {
sadayapalam@4533
  2357
                                this.resultInfo = resultInfoForClassDefinition;
sadayapalam@4533
  2358
                                visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef,
sadayapalam@4533
  2359
                                                            localEnv, argtypes, typeargtypes, pkind);
sadayapalam@4533
  2360
                            } finally {
sadayapalam@4533
  2361
                                this.resultInfo = prevResult;
sadayapalam@4533
  2362
                            }
sadayapalam@4445
  2363
                        });
sadayapalam@4445
  2364
            } else {
sadayapalam@4445
  2365
                if (isDiamond && clazztype.hasTag(CLASS)) {
sadayapalam@4445
  2366
                    List<Type> invalidDiamondArgs = chk.checkDiamondDenotable((ClassType)clazztype);
sadayapalam@4445
  2367
                    if (!clazztype.isErroneous() && invalidDiamondArgs.nonEmpty()) {
sadayapalam@4445
  2368
                        // One or more types inferred in the previous steps is non-denotable.
sadayapalam@4445
  2369
                        Fragment fragment = Diamond(clazztype.tsym);
sadayapalam@4445
  2370
                        log.error(tree.clazz.pos(),
sadayapalam@4445
  2371
                                Errors.CantApplyDiamond1(
sadayapalam@4445
  2372
                                        fragment,
sadayapalam@4445
  2373
                                        invalidDiamondArgs.size() > 1 ?
sadayapalam@4445
  2374
                                                DiamondInvalidArgs(invalidDiamondArgs, fragment) :
sadayapalam@4445
  2375
                                                DiamondInvalidArg(invalidDiamondArgs, fragment)));
sadayapalam@4445
  2376
                    }
sadayapalam@4445
  2377
                    // For <>(){}, inferred types must also be accessible.
sadayapalam@4445
  2378
                    for (Type t : clazztype.getTypeArguments()) {
sadayapalam@4445
  2379
                        rs.checkAccessibleType(env, t);
sadayapalam@4445
  2380
                    }
sadayapalam@4445
  2381
                }
sadayapalam@4445
  2382
sadayapalam@4445
  2383
                // If we already errored, be careful to avoid a further avalanche. ErrorType answers
sadayapalam@4445
  2384
                // false for isInterface call even when the original type is an interface.
sadayapalam@4445
  2385
                boolean implementing = clazztype.tsym.isInterface() ||
dbalek@4662
  2386
                        clazztype.isErroneous() && !clazztype.getOriginalType().hasTag(NONE) && clazztype.getOriginalType().tsym.isInterface();
sadayapalam@4445
  2387
sadayapalam@4445
  2388
                if (implementing) {
duke@0
  2389
                    cdef.implementing = List.of(clazz);
duke@0
  2390
                } else {
duke@0
  2391
                    cdef.extending = clazz;
duke@0
  2392
                }
duke@0
  2393
vromero@3964
  2394
                if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
vromero@3964
  2395
                    isSerializable(clazztype)) {
vromero@3964
  2396
                    localEnv.info.isSerializable = true;
vromero@3964
  2397
                }
vromero@3964
  2398
duke@0
  2399
                attribStat(cdef, localEnv);
duke@0
  2400
dbalek@1180
  2401
                JCExpression clazzCopy = new TreeCopier<JCTree>(make) {
dbalek@1180
  2402
                    @Override
dbalek@1180
  2403
                    public <T extends JCTree> T copy(T tree, JCTree p) {
dbalek@1180
  2404
                        T t = super.copy(tree, p);
jlahoda@1182
  2405
                        if (t != null) {
jlahoda@1182
  2406
                            t.pos = Position.NOPOS;
jlahoda@1182
  2407
                            t.type = tree.type;
jlahoda@1182
  2408
                        }
dbalek@1180
  2409
                        return t;
jlahoda@1181
  2410
                    }
jlahoda@1181
  2411
jlahoda@1181
  2412
                    @Override public JCTree visitIdentifier(IdentifierTree node, JCTree p) {
jlahoda@1181
  2413
                        JCIdent result = (JCIdent) super.visitIdentifier(node, p);
jlahoda@1181
  2414
jlahoda@1181
  2415
                        result.sym = ((JCIdent) node).sym;
jlahoda@1181
  2416
jlahoda@1181
  2417
                        return result;
jlahoda@1181
  2418
                    }
jlahoda@1181
  2419
jlahoda@1181
  2420
                    @Override public JCTree visitMemberSelect(MemberSelectTree node, JCTree p) {
jlahoda@1181
  2421
                        JCFieldAccess result = (JCFieldAccess) super.visitMemberSelect(node, p);
jlahoda@1181
  2422
jlahoda@1181
  2423
                        result.sym = ((JCFieldAccess) node).sym;
jlahoda@1181
  2424
jlahoda@1181
  2425
                        return result;
jlahoda@1181
  2426
                    }
dbalek@1180
  2427
                }.copy(clazz);
mcimadamore@18
  2428
                if (clazztype.tsym.isInterface()) {
dbalek@1180
  2429
                    cdef.implementing = List.of(clazzCopy);
mcimadamore@18
  2430
                } else {
dbalek@1180
  2431
                    cdef.extending = clazzCopy;
mcimadamore@18
  2432
                }
mcimadamore@18
  2433
sadayapalam@4445
  2434
                List<Type> finalargtypes;
duke@0
  2435
                // If an outer instance is given,
duke@0
  2436
                // prefix it to the constructor arguments
jlahoda@2403
  2437
                // "encl" will be cleared in TransTypes
duke@0
  2438
                if (tree.encl != null && !clazztype.tsym.isInterface()) {
duke@0
  2439
                    tree.args = tree.args.prepend(makeNullCheck(tree.encl));
sadayapalam@4445
  2440
                    finalargtypes = argtypes.prepend(tree.encl.type);
sadayapalam@4445
  2441
                } else {
sadayapalam@4445
  2442
                    finalargtypes = argtypes;
duke@0
  2443
                }
duke@0
  2444
sadayapalam@4445
  2445
                // Reassign clazztype and recompute constructor. As this necessarily involves
sadayapalam@4445
  2446
                // another attribution pass for deferred types in the case of <>, replicate
sadayapalam@4445
  2447
                // them. Original arguments have right decorations already.
sadayapalam@4445
  2448
                if (isDiamond && pkind.contains(KindSelector.POLY)) {
sadayapalam@4445
  2449
                    finalargtypes = finalargtypes.map(deferredAttr.deferredCopier);
sadayapalam@4445
  2450
                }
sadayapalam@4445
  2451
duke@0
  2452
                clazztype = cdef.sym.type;
mcimadamore@2180
  2453
                Symbol sym = tree.constructor = rs.resolveConstructor(
sadayapalam@4445
  2454
                        tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes);
sadayapalam@4445
  2455
                Assert.check(!sym.kind.isResolutionError());
duke@0
  2456
                tree.constructor = sym;
sadayapalam@4483
  2457
                tree.constructorType = checkId(tree,
sadayapalam@4445
  2458
                        clazztype,
sadayapalam@4445
  2459
                        tree.constructor,
sadayapalam@4445
  2460
                        localEnv,
sadayapalam@4483
  2461
                        new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
duke@0
  2462
            }
sadayapalam@4445
  2463
            Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ?
sadayapalam@4445
  2464
                                clazztype : types.createErrorType(tree.type);
sadayapalam@4483
  2465
            result = check(tree, owntype, KindSelector.VAL, resultInfo.dup(CheckMode.NO_INFERENCE_HOOK));
sadayapalam@4445
  2466
            chk.validate(tree.typeargs, localEnv);
sadayapalam@4445
  2467
        }
sadayapalam@4445
  2468
mcimadamore@4608
  2469
        CheckContext diamondContext(JCNewClass clazz, TypeSymbol tsym, CheckContext checkContext) {
mcimadamore@4608
  2470
            return new Check.NestedCheckContext(checkContext) {
mcimadamore@4608
  2471
                @Override
mcimadamore@4608
  2472
                public void report(DiagnosticPosition _unused, JCDiagnostic details) {
mcimadamore@4608
  2473
                    enclosingContext.report(clazz.clazz,
mcimadamore@4608
  2474
                            diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", tsym), details));
mcimadamore@4608
  2475
                }
mcimadamore@4608
  2476
            };
mcimadamore@4608
  2477
        }
mcimadamore@2191
  2478
duke@0
  2479
    /** Make an attributed null check tree.
duke@0
  2480
     */
duke@0
  2481
    public JCExpression makeNullCheck(JCExpression arg) {
sadayapalam@5400
  2482
        // optimization: new Outer() can never be null; skip null check
sadayapalam@5400
  2483
        if (arg.getTag() == NEWCLASS)
sadayapalam@5400
  2484
            return arg;
duke@0
  2485
        // optimization: X.this is never null; skip null check
duke@0
  2486
        Name name = TreeInfo.name(arg);
duke@0
  2487
        if (name == names._this || name == names._super) return arg;
duke@0
  2488
jjg@1972
  2489
        JCTree.Tag optag = NULLCHK;
dbalek@2919
  2490
        JCUnary tree = make.at(Position.NOPOS).Unary(optag, arg);
mcimadamore@4399
  2491
        tree.operator = operators.resolveUnary(arg, optag, arg.type);
duke@0
  2492
        tree.type = arg.type;
duke@0
  2493
        return tree;
duke@0
  2494
    }
duke@0
  2495
duke@0
  2496
    public void visitNewArray(JCNewArray tree) {
jjg@289
  2497
        Type owntype = types.createErrorType(tree.type);
mcimadamore@2190
  2498
        Env<AttrContext> localEnv = env.dup(tree);
duke@0
  2499
        Type elemtype;
duke@0
  2500
        if (tree.elemtype != null) {
mcimadamore@2190
  2501
            elemtype = attribType(tree.elemtype, localEnv);
mcimadamore@2190
  2502
            chk.validate(tree.elemtype, localEnv);
duke@0
  2503
            owntype = elemtype;
duke@0
  2504
            for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
mcimadamore@2190
  2505
                attribExpr(l.head, localEnv, syms.intType);
emc@4221
  2506
                owntype = new ArrayType(owntype, syms.arrayClass);
duke@0
  2507
            }
duke@0
  2508
        } else {
duke@0
  2509
            // we are seeing an untyped aggregate { ... }
duke@0
  2510
            // this is allowed only if the prototype is an array
jjg@2213
  2511
            if (pt().hasTag(ARRAY)) {
mcimadamore@2063
  2512
                elemtype = types.elemtype(pt());
duke@0
  2513
            } else {
jjg@2213
  2514
                if (!pt().hasTag(ERROR)) {
duke@0
  2515
                    log.error(tree.pos(), "illegal.initializer.for.type",
mcimadamore@2063
  2516
                              pt());
duke@0
  2517
                }
mcimadamore@2063
  2518
                elemtype = types.createErrorType(pt());
duke@0
  2519
            }
duke@0
  2520
        }
duke@0
  2521
        if (tree.elems != null) {
mcimadamore@2190
  2522
            attribExprs(tree.elems, localEnv, elemtype);
emc@4221
  2523
            owntype = new ArrayType(elemtype, syms.arrayClass);
duke@0
  2524
        }
duke@0
  2525
        if (!types.isReifiable(elemtype))
duke@0
  2526
            log.error(tree.pos(), "generic.array.creation");
emc@4248
  2527
        result = check(tree, owntype, KindSelector.VAL, resultInfo);
duke@0
  2528
    }
duke@0
  2529
mcimadamore@2191
  2530
    /*
mcimadamore@2191
  2531
     * A lambda expression can only be attributed when a target-type is available.
mcimadamore@2191
  2532
     * In addition, if the target-type is that of a functional interface whose
mcimadamore@2191
  2533
     * descriptor contains inference variables in argument position the lambda expression
mcimadamore@2191
  2534
     * is 'stuck' (see DeferredAttr).
mcimadamore@2191
  2535
     */
mcimadamore@1989
  2536
    @Override
mcimadamore@2191
  2537
    public void visitLambda(final JCLambda that) {
jjg@2213
  2538
        if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
jjg@2213
  2539
            if (pt().hasTag(NONE)) {
mcimadamore@2191
  2540
                //lambda only allowed in assignment or method invocation/cast context
mcimadamore@2191
  2541
                log.error(that.pos(), "unexpected.lambda");
mcimadamore@2191
  2542
            }
mcimadamore@2191
  2543
        }
mcimadamore@2191
  2544
        //create an environment for attribution of the lambda expression
mcimadamore@2191
  2545
        final Env<AttrContext> localEnv = lambdaEnv(that, env);
dbalek@2912
  2546
        boolean needsRecovery = resultInfo != recoveryInfo &&
mcimadamore@2191
  2547
                resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
dbalek@3084
  2548
        Type currentTarget = null;
mcimadamore@2191
  2549
        try {
mcimadamore@4608
  2550
            if (needsRecovery && isSerializable(pt())) {
vromero@3964
  2551
                localEnv.info.isSerializable = true;
vromero@5460
  2552
                localEnv.info.isLambda = true;
vromero@3964
  2553
            }
mcimadamore@2191
  2554
            List<Type> explicitParamTypes = null;
mcimadamore@2361
  2555
            if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
mcimadamore@2191
  2556
                //attribute lambda parameters
mcimadamore@2191
  2557
                attribStats(that.params, localEnv);
mcimadamore@2191
  2558
                explicitParamTypes = TreeInfo.types(that.params);
mcimadamore@2191
  2559
            }
mcimadamore@2191
  2560
dbalek@2907
  2561
            if (pt().hasTag(NONE) && pt() != Type.recoveryType) {
dbalek@2907
  2562
                resultInfo = recoveryInfo;
dbalek@2907
  2563
            }
mcimadamore@4608
  2564
            TargetInfo targetInfo = getTargetInfo(that, resultInfo, explicitParamTypes);
dbalek@4654
  2565
            currentTarget = targetInfo.target;
mcimadamore@4608
  2566
            Type lambdaType = targetInfo.descriptor;
mcimadamore@4608
  2567
mcimadamore@4608
  2568
            if (currentTarget.isErroneous()) {
mcimadamore@4608
  2569
                result = that.type = currentTarget;
mcimadamore@4608
  2570
                return;
mcimadamore@2260
  2571
            }
mcimadamore@2191
  2572
vromero@3018
  2573
            setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
mcimadamore@2361
  2574
mcimadamore@2274
  2575
            if (lambdaType.hasTag(FORALL)) {
mcimadamore@2274
  2576
                //lambda expression target desc cannot be a generic method
mcimadamore@2274
  2577
                resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
vromero@3018
  2578
                        lambdaType, kindName(currentTarget.tsym), currentTarget.tsym));
mcimadamore@2274
  2579
                result = that.type = types.createErrorType(pt());
mcimadamore@2274
  2580
                return;
mcimadamore@2274
  2581
            }
mcimadamore@2274
  2582
mcimadamore@2361
  2583
            if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
mcimadamore@2191
  2584
                //add param type info in the AST
mcimadamore@2191
  2585
                List<Type> actuals = lambdaType.getParameterTypes();
mcimadamore@2191
  2586
                List<JCVariableDecl> params = that.params;
mcimadamore@2191
  2587
mcimadamore@2191
  2588
                boolean arityMismatch = false;
mcimadamore@2191
  2589
mcimadamore@2191
  2590
                while (params.nonEmpty()) {
mcimadamore@2191
  2591
                    if (actuals.isEmpty()) {
mcimadamore@2191
  2592
                        //not enough actuals to perform lambda parameter inference
mcimadamore@2191
  2593
                        arityMismatch = true;
mcimadamore@2191
  2594
                    }
mcimadamore@2191
  2595
                    //reset previously set info
mcimadamore@2191
  2596
                    Type argType = arityMismatch ?
mcimadamore@2191
  2597
                            syms.errType :
mcimadamore@2191
  2598
                            actuals.head;
dbalek@2447
  2599
                    params.head.vartype = make.at(Position.NOPOS).Type(argType);
mcimadamore@2191
  2600
                    params.head.sym = null;
mcimadamore@2191
  2601
                    actuals = actuals.isEmpty() ?
mcimadamore@2191
  2602
                            actuals :
mcimadamore@2191
  2603
                            actuals.tail;
mcimadamore@2191
  2604
                    params = params.tail;
mcimadamore@2191
  2605
                }
mcimadamore@2191
  2606
mcimadamore@2191
  2607
                //attribute lambda parameters
mcimadamore@2191
  2608
                attribStats(that.params, localEnv);
mcimadamore@2191
  2609
mcimadamore@2191
  2610
                if (arityMismatch) {
mcimadamore@2191
  2611
                    resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
vromero@3018
  2612
                        result = that.type = types.createErrorType(currentTarget);
mcimadamore@2191
  2613
                        return;
mcimadamore@2191
  2614
                }
mcimadamore@2191
  2615
            }
mcimadamore@2191
  2616
mcimadamore@2191
  2617
            //from this point on, no recovery is needed; if we are in assignment context
mcimadamore@2191
  2618
            //we will be able to attribute the whole lambda body, regardless of errors;
mcimadamore@2191
  2619
            //if we are in a 'check' method context, and the lambda is not compatible
mcimadamore@2191
  2620
            //with the target-type, it will be recovered anyway in Attr.checkId
mcimadamore@2191
  2621
            needsRecovery = false;
mcimadamore@2191
  2622
mcimadamore@4608
  2623
            ResultInfo bodyResultInfo = localEnv.info.returnResult =
mcimadamore@4608
  2624
                    lambdaBodyResult(that, lambdaType, resultInfo);
mcimadamore@2191
  2625
vromero@3016
  2626
            if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
vromero@3016
  2627
                attribTree(that.getBody(), localEnv, bodyResultInfo);
vromero@3016
  2628
            } else {
vromero@3016
  2629
                JCBlock body = (JCBlock)that.body;
dbalek@3084
  2630
                if (body == breakTree &&
dbalek@3084
  2631
                        resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
dbalek@4835
  2632
                    throw new BreakAttr(copyEnv(localEnv), null);
dbalek@2447
  2633
                }
vromero@3016
  2634
                attribStats(body.stats, localEnv);
mcimadamore@2191
  2635
            }
mcimadamore@2191
  2636
emc@4248
  2637
            result = check(that, currentTarget, KindSelector.VAL, resultInfo);
mcimadamore@2191
  2638
mcimadamore@2191
  2639
            boolean isSpeculativeRound =
mcimadamore@2191
  2640
                    resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
mcimadamore@2191
  2641
mcimadamore@2890
  2642
            preFlow(that);
mcimadamore@2191
  2643
            flow.analyzeLambda(env, that, make, isSpeculativeRound);
mcimadamore@2191
  2644
mcimadamore@4339
  2645
            that.type = currentTarget; //avoids recovery at this stage
jlahoda@3035
  2646
            checkLambdaCompatible(that, lambdaType, resultInfo.checkContext);
mcimadamore@2191
  2647
mcimadamore@2191
  2648
            if (!isSpeculativeRound) {
jlahoda@3035
  2649
                //add thrown types as bounds to the thrown types free variables if needed:
jlahoda@3035
  2650
                if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) {
jlahoda@3035
  2651
                    List<Type> inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make);
vromero@3885
  2652
                    List<Type> thrownTypes = resultInfo.checkContext.inferenceContext().asUndetVars(lambdaType.getThrownTypes());
jlahoda@3035
  2653
jlahoda@3035
  2654
                    chk.unhandled(inferredThrownTypes, thrownTypes);
mcimadamore@5559
  2655
mcimadamore@5559
  2656
                    //18.2.5: "In addition, for all j (1 <= j <= n), the constraint reduces to the bound throws Ej"
mcimadamore@5559
  2657
                    thrownTypes.stream()
mcimadamore@5559
  2658
                            .filter(t -> t.hasTag(UNDETVAR))
mcimadamore@5559
  2659
                            .forEach(t -> ((UndetVar)t).setThrow());
jlahoda@3035
  2660
                }
jlahoda@3035
  2661
vromero@3018
  2662
                checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
mcimadamore@2191
  2663
            }
emc@4248
  2664
            result = check(that, currentTarget, KindSelector.VAL, resultInfo);
mcimadamore@2191
  2665
        } catch (Types.FunctionDescriptorLookupError ex) {
mcimadamore@2191
  2666
            JCDiagnostic cause = ex.getDiagnostic();
mcimadamore@2191
  2667
            resultInfo.checkContext.report(that, cause);
mcimadamore@2191
  2668
            result = that.type = types.createErrorType(pt());
mcimadamore@2191
  2669
            return;
dbalek@2332
  2670
        } catch (BreakAttr ba) {
dbalek@5425
  2671
            if (currentTarget != null) {
dbalek@5425
  2672
                check(that, currentTarget, KindSelector.VAL, resultInfo);
dbalek@5425
  2673
            }
dbalek@2332
  2674
            needsRecovery = false;
dbalek@2332
  2675
            throw ba;
jlahoda@4472
  2676
        } catch (Throwable t) {
jlahoda@4472
  2677
            //when an unexpected exception happens, avoid attempts to attribute the same tree again
jlahoda@4472
  2678
            //as that would likely cause the same exception again.
jlahoda@4472
  2679
            needsRecovery = false;
jlahoda@4472
  2680
            throw t;
mcimadamore@2191
  2681
        } finally {
mcimadamore@2191
  2682
            localEnv.info.scope.leave();
mcimadamore@2191
  2683
            if (needsRecovery) {
mcimadamore@2191
  2684
                attribTree(that, env, recoveryInfo);
mcimadamore@2191
  2685
            }
mcimadamore@2191
  2686
        }
mcimadamore@1989
  2687
    }
mcimadamore@2607
  2688
    //where
mcimadamore@4608
  2689
        class TargetInfo {
mcimadamore@4608
  2690
            Type target;
mcimadamore@4608
  2691
            Type descriptor;
mcimadamore@4608
  2692
mcimadamore@4608
  2693
            public TargetInfo(Type target, Type descriptor) {
mcimadamore@4608
  2694
                this.target = target;
mcimadamore@4608
  2695
                this.descriptor = descriptor;
mcimadamore@4608
  2696
            }
mcimadamore@4608
  2697
        }
mcimadamore@4608
  2698
mcimadamore@4608
  2699
        TargetInfo getTargetInfo(JCPolyExpression that, ResultInfo resultInfo, List<Type> explicitParamTypes) {
mcimadamore@4608
  2700
            Type lambdaType;
mcimadamore@4608
  2701
            Type currentTarget = resultInfo.pt;
mcimadamore@4608
  2702
            if (resultInfo.pt != Type.recoveryType) {
mcimadamore@4608
  2703
                /* We need to adjust the target. If the target is an
mcimadamore@4608
  2704
                 * intersection type, for example: SAM & I1 & I2 ...
mcimadamore@4608
  2705
                 * the target will be updated to SAM
mcimadamore@4608
  2706
                 */
mcimadamore@4608
  2707
                currentTarget = targetChecker.visit(currentTarget, that);
mcimadamore@4608
  2708
                if (explicitParamTypes != null) {
mcimadamore@4608
  2709
                    currentTarget = infer.instantiateFunctionalInterface(that,
mcimadamore@4608
  2710
                            currentTarget, explicitParamTypes, resultInfo.checkContext);
mcimadamore@4608
  2711
                }
mcimadamore@4608
  2712
                currentTarget = types.removeWildcards(currentTarget);
mcimadamore@4608
  2713
                lambdaType = types.findDescriptorType(currentTarget);
mcimadamore@4608
  2714
            } else {
mcimadamore@4608
  2715
                currentTarget = Type.recoveryType;
mcimadamore@4608
  2716
                lambdaType = fallbackDescriptorType(that);
mcimadamore@4608
  2717
            }
mcimadamore@4608
  2718
            if (that.hasTag(LAMBDA) && lambdaType.hasTag(FORALL)) {
mcimadamore@4608
  2719
                //lambda expression target desc cannot be a generic method
mcimadamore@4608
  2720
                resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
mcimadamore@4608
  2721
                        lambdaType, kindName(currentTarget.tsym), currentTarget.tsym));
mcimadamore@4608
  2722
                currentTarget = types.createErrorType(pt());
mcimadamore@4608
  2723
            }
mcimadamore@4608
  2724
            return new TargetInfo(currentTarget, lambdaType);
mcimadamore@4608
  2725
        }
mcimadamore@4608
  2726
mcimadamore@2890
  2727
        void preFlow(JCLambda tree) {
mcimadamore@2890
  2728
            new PostAttrAnalyzer() {
mcimadamore@2890
  2729
                @Override
mcimadamore@2890
  2730
                public void scan(JCTree tree) {
mcimadamore@2890
  2731
                    if (tree == null ||
mcimadamore@2890
  2732
                            (tree.type != null &&
mcimadamore@2890
  2733
                            tree.type == Type.stuckType)) {
mcimadamore@2890
  2734
                        //don't touch stuck expressions!
mcimadamore@2890
  2735
                        return;
mcimadamore@2890
  2736
                    }
mcimadamore@2890
  2737
                    super.scan(tree);
mcimadamore@2890
  2738
                }
mcimadamore@2890
  2739
            }.scan(tree);
mcimadamore@2890
  2740
        }
mcimadamore@2890
  2741
mcimadamore@2607
  2742
        Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
mcimadamore@2607
  2743
mcimadamore@2607
  2744
            @Override
mcimadamore@2607
  2745
            public Type visitClassType(ClassType t, DiagnosticPosition pos) {
mcimadamore@4406
  2746
                return t.isIntersection() ?
mcimadamore@2607
  2747
                        visitIntersectionClassType((IntersectionClassType)t, pos) : t;
mcimadamore@2607
  2748
            }
mcimadamore@2607
  2749
mcimadamore@2607
  2750
            public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
mcimadamore@2607
  2751
                Symbol desc = types.findDescriptorSymbol(makeNotionalInterface(ict));
mcimadamore@2607
  2752
                Type target = null;
mcimadamore@2607
  2753
                for (Type bound : ict.getExplicitComponents()) {
mcimadamore@2607
  2754
                    TypeSymbol boundSym = bound.tsym;
mcimadamore@2607
  2755
                    if (types.isFunctionalInterface(boundSym) &&
mcimadamore@2607
  2756
                            types.findDescriptorSymbol(boundSym) == desc) {
mcimadamore@2607
  2757
                        target = bound;
mcimadamore@2607
  2758
                    } else if (!boundSym.isInterface() || (boundSym.flags() & ANNOTATION) != 0) {
mcimadamore@2607
  2759
                        //bound must be an interface
mcimadamore@2607
  2760
                        reportIntersectionError(pos, "not.an.intf.component", boundSym);
mcimadamore@2607
  2761
                    }
mcimadamore@2276
  2762
                }
mcimadamore@2607
  2763
                return target != null ?
mcimadamore@2607
  2764
                        target :
mcimadamore@2607
  2765
                        ict.getExplicitComponents().head; //error recovery
mcimadamore@2276
  2766
            }
mcimadamore@2607
  2767
mcimadamore@2607
  2768
            private TypeSymbol makeNotionalInterface(IntersectionClassType ict) {
alundblad@3063
  2769
                ListBuffer<Type> targs = new ListBuffer<>();
alundblad@3063
  2770
                ListBuffer<Type> supertypes = new ListBuffer<>();
mcimadamore@2607
  2771
                for (Type i : ict.interfaces_field) {
mcimadamore@2607
  2772
                    if (i.isParameterized()) {
mcimadamore@2607
  2773
                        targs.appendList(i.tsym.type.allparams());
mcimadamore@2607
  2774
                    }
mcimadamore@2607
  2775
                    supertypes.append(i.tsym.type);
mcimadamore@2607
  2776
                }
mcimadamore@4406
  2777
                IntersectionClassType notionalIntf = types.makeIntersectionType(supertypes.toList());
mcimadamore@2607
  2778
                notionalIntf.allparams_field = targs.toList();
mcimadamore@2607
  2779
                notionalIntf.tsym.flags_field |= INTERFACE;
mcimadamore@2607
  2780
                return notionalIntf.tsym;
mcimadamore@2607
  2781
            }
mcimadamore@2607
  2782
mcimadamore@2607
  2783
            private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) {
mcimadamore@2607
  2784
                resultInfo.checkContext.report(pos, diags.fragment("bad.intersection.target.for.functional.expr",
mcimadamore@2607
  2785
                        diags.fragment(key, args)));
mcimadamore@2607
  2786
            }
mcimadamore@2607
  2787
        };
mcimadamore@2607
  2788
mcimadamore@2191
  2789
        private Type fallbackDescriptorType(JCExpression tree) {
mcimadamore@2191
  2790
            switch (tree.getTag()) {
mcimadamore@2191
  2791
                case LAMBDA:
mcimadamore@2191
  2792
                    JCLambda lambda = (JCLambda)tree;
mcimadamore@2191
  2793
                    List<Type> argtypes = List.nil();
mcimadamore@2191
  2794
                    for (JCVariableDecl param : lambda.params) {
mcimadamore@2191
  2795
                        argtypes = param.vartype != null ?
mcimadamore@2191
  2796
                                argtypes.append(param.vartype.type) :
mcimadamore@2191
  2797
                                argtypes.append(syms.errType);
mcimadamore@2191
  2798
                    }
mcimadamore@2623
  2799
                    return new MethodType(argtypes, Type.recoveryType,
mcimadamore@2623
  2800
                            List.of(syms.throwableType), syms.methodClass);
mcimadamore@2191
  2801
                case REFERENCE:
mcimadamore@5586
  2802
                    return new MethodType(List.nil(), Type.recoveryType,
mcimadamore@2623
  2803
                            List.of(syms.throwableType), syms.methodClass);
mcimadamore@2191
  2804
                default:
mcimadamore@2191
  2805
                    Assert.error("Cannot get here!");
mcimadamore@2191
  2806
            }
mcimadamore@2191
  2807
            return null;
mcimadamore@2191
  2808
        }
mcimadamore@2191
  2809
mcimadamore@2623
  2810
        private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env,
mcimadamore@2623
  2811
                final InferenceContext inferenceContext, final Type... ts) {
mcimadamore@2260
  2812
            checkAccessibleTypes(pos, env, inferenceContext, List.from(ts));
mcimadamore@2260
  2813
        }
mcimadamore@2260
  2814
mcimadamore@2623
  2815
        private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env,
mcimadamore@2623
  2816
                final InferenceContext inferenceContext, final List<Type> ts) {
mcimadamore@2260
  2817
            if (inferenceContext.free(ts)) {
mcimadamore@5585
  2818
                inferenceContext.addFreeTypeListener(ts,
mcimadamore@5585
  2819
                        solvedContext -> checkAccessibleTypes(pos, env, solvedContext, solvedContext.asInstTypes(ts)));
mcimadamore@2191
  2820
            } else {
mcimadamore@2260
  2821
                for (Type t : ts) {
mcimadamore@2260
  2822
                    rs.checkAccessibleType(env, t);
mcimadamore@2260
  2823
                }
mcimadamore@2191
  2824
            }
mcimadamore@2191
  2825
        }
mcimadamore@2191
  2826
mcimadamore@2191
  2827
        /**
mcimadamore@2191
  2828
         * Lambda/method reference have a special check context that ensures
mcimadamore@2191
  2829
         * that i.e. a lambda return type is compatible with the expected
mcimadamore@2191
  2830
         * type according to both the inherited context and the assignment
mcimadamore@2191
  2831
         * context.
mcimadamore@2191
  2832
         */
mcimadamore@2273
  2833
        class FunctionalReturnContext extends Check.NestedCheckContext {
mcimadamore@2273
  2834
mcimadamore@2273
  2835
            FunctionalReturnContext(CheckContext enclosingContext) {
mcimadamore@2191
  2836
                super(enclosingContext);
mcimadamore@2191
  2837
            }
mcimadamore@2191
  2838
mcimadamore@2191
  2839
            @Override
mcimadamore@2191
  2840
            public boolean compatible(Type found, Type req, Warner warn) {
mcimadamore@2191
  2841
                //return type must be compatible in both current context and assignment context
mcimadamore@5149
  2842
                return chk.basicHandler.compatible(inferenceContext().asUndetVar(found), inferenceContext().asUndetVar(req), warn);
mcimadamore@2191
  2843
            }
mcimadamore@2361
  2844
mcimadamore@2191
  2845
            @Override
mcimadamore@2191
  2846
            public void report(DiagnosticPosition pos, JCDiagnostic details) {
mcimadamore@2191
  2847
                enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details));
mcimadamore@2191
  2848
            }
mcimadamore@2191
  2849
        }
mcimadamore@2191
  2850
mcimadamore@2273
  2851
        class ExpressionLambdaReturnContext extends FunctionalReturnContext {
mcimadamore@2273
  2852
mcimadamore@2273
  2853
            JCExpression expr;
mcimadamore@5119
  2854
            boolean expStmtExpected;
mcimadamore@2273
  2855
mcimadamore@2273
  2856
            ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
mcimadamore@2273
  2857
                super(enclosingContext);
mcimadamore@2273
  2858
                this.expr = expr;
mcimadamore@2273
  2859
            }
mcimadamore@2273
  2860
mcimadamore@2273
  2861
            @Override
mcimadamore@5119
  2862
            public void report(DiagnosticPosition pos, JCDiagnostic details) {
mcimadamore@5119
  2863
                if (expStmtExpected) {
mcimadamore@5119
  2864
                    enclosingContext.report(pos, diags.fragment(Fragments.StatExprExpected));
mcimadamore@5119
  2865
                } else {
mcimadamore@5119
  2866
                    super.report(pos, details);
mcimadamore@5119
  2867
                }
mcimadamore@5119
  2868
            }
mcimadamore@5119
  2869
mcimadamore@5119
  2870
            @Override
mcimadamore@2273
  2871
            public boolean compatible(Type found, Type req, Warner warn) {
mcimadamore@2273
  2872
                //a void return is compatible with an expression statement lambda
mcimadamore@5119
  2873
                if (req.hasTag(VOID)) {
mcimadamore@5119
  2874
                    expStmtExpected = true;
dbalek@5244
  2875
                    return TreeInfo.isExpressionStatement(expr, names);
mcimadamore@5119
  2876
                } else {
mcimadamore@5119
  2877
                    return super.compatible(found, req, warn);
mcimadamore@5119
  2878
                }
mcimadamore@2273
  2879
            }
mcimadamore@2273
  2880
        }
mcimadamore@2273
  2881
mcimadamore@4608
  2882
        ResultInfo lambdaBodyResult(JCLambda that, Type descriptor, ResultInfo resultInfo) {
mcimadamore@4608
  2883
            FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
mcimadamore@4608
  2884
                    new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) :
mcimadamore@4608
  2885
                    new FunctionalReturnContext(resultInfo.checkContext);
mcimadamore@4608
  2886
mcimadamore@4608
  2887
            return descriptor.getReturnType() == Type.recoveryType ?
mcimadamore@4608
  2888
                    recoveryInfo :
mcimadamore@4608
  2889
                    new ResultInfo(KindSelector.VAL,
mcimadamore@4608
  2890
                            descriptor.getReturnType(), funcContext);
mcimadamore@4608
  2891
        }
mcimadamore@4608
  2892
mcimadamore@2191
  2893
        /**
mcimadamore@2191
  2894
        * Lambda compatibility. Check that given return types, thrown types, parameter types
mcimadamore@2191
  2895
        * are compatible with the expected functional interface descriptor. This means that:
mcimadamore@2191
  2896
        * (i) parameter types must be identical to those of the target descriptor; (ii) return
jlahoda@3035
  2897
        * types must be compatible with the return type of the expected descriptor.
mcimadamore@2191
  2898
        */
mcimadamore@4608
  2899
        void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) {
vromero@3885
  2900
            Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType());
mcimadamore@2191
  2901
mcimadamore@2191
  2902
            //return values have already been checked - but if lambda has no return
mcimadamore@2191
  2903
            //values, we must ensure that void/value compatibility is correct;
mcimadamore@2191
  2904
            //this amounts at checking that, if a lambda body can complete normally,
mcimadamore@2191
  2905
            //the descriptor's return type must be void
mcimadamore@2191
  2906
            if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && tree.canCompleteNormally &&
jjg@2213
  2907
                    !returnType.hasTag(VOID) && returnType != Type.recoveryType) {
mcimadamore@2191
  2908
                checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda",
mcimadamore@2191
  2909
                        diags.fragment("missing.ret.val", returnType)));
mcimadamore@2191
  2910
            }
mcimadamore@2191
  2911
vromero@3885
  2912
            List<Type> argTypes = checkContext.inferenceContext().asUndetVars(descriptor.getParameterTypes());
mcimadamore@2191
  2913
            if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) {
mcimadamore@2191
  2914
                checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
mcimadamore@2191
  2915
            }
mcimadamore@2191
  2916
        }
mcimadamore@2191
  2917
vromero@3251
  2918
        /* Map to hold 'fake' clinit methods. If a lambda is used to initialize a
vromero@3251
  2919
         * static field and that lambda has type annotations, these annotations will
vromero@3251
  2920
         * also be stored at these fake clinit methods.
vromero@3251
  2921
         *
vromero@3251
  2922
         * LambdaToMethod also use fake clinit methods so they can be reused.
vromero@3251
  2923
         * Also as LTM is a phase subsequent to attribution, the methods from
vromero@3251
  2924
         * clinits can be safely removed by LTM to save memory.
vromero@3251
  2925
         */
vromero@3251
  2926
        private Map<ClassSymbol, MethodSymbol> clinits = new HashMap<>();
vromero@3251
  2927
vromero@3251
  2928
        public MethodSymbol removeClinit(ClassSymbol sym) {
vromero@3251
  2929
            return clinits.remove(sym);
vromero@3251
  2930
        }
vromero@3251
  2931
vromero@3251
  2932
        /* This method returns an environment to be used to attribute a lambda
vromero@3251
  2933
         * expression.
vromero@3251
  2934
         *
vromero@3251
  2935
         * The owner of this environment is a method symbol. If the current owner
vromero@3251
  2936
         * is not a method, for example if the lambda is used to initialize
vromero@3251
  2937
         * a field, then if the field is:
vromero@3251
  2938
         *
vromero@3251
  2939
         * - an instance field, we use the first constructor.
vromero@3251
  2940
         * - a static field, we create a fake clinit method.
vromero@3251
  2941
         */
vromero@3951
  2942
        public Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
mcimadamore@2191
  2943
            Env<AttrContext> lambdaEnv;
mcimadamore@2191
  2944
            Symbol owner = env.info.scope.owner;
mcimadamore@2191
  2945
            if (owner.kind == VAR && owner.owner.kind == TYP) {
mcimadamore@2191
  2946
                //field initializer
vromero@3251
  2947
                ClassSymbol enclClass = owner.enclClass();
jlahoda@4103
  2948
                Symbol newScopeOwner = env.info.scope.owner;
vromero@3251
  2949
                /* if the field isn't static, then we can get the first constructor
vromero@3251
  2950
                 * and use it as the owner of the environment. This is what
vromero@3251
  2951
                 * LTM code is doing to look for type annotations so we are fine.
vromero@3251
  2952
                 */
vromero@3251
  2953
                if ((owner.flags() & STATIC) == 0) {
jlahoda@4103
  2954
                    for (Symbol s : enclClass.members_field.getSymbolsByName(names.init)) {
jlahoda@4103
  2955
                        newScopeOwner = s;
vromero@3251
  2956
                        break;
vromero@3251
  2957
                    }
vromero@3251
  2958
                } else {
vromero@3251
  2959
                    /* if the field is static then we need to create a fake clinit
vromero@3251
  2960
                     * method, this method can later be reused by LTM.
vromero@3251
  2961
                     */
vromero@3251
  2962
                    MethodSymbol clinit = clinits.get(enclClass);
vromero@3251
  2963
                    if (clinit == null) {
mcimadamore@5586
  2964
                        Type clinitType = new MethodType(List.nil(),
mcimadamore@5586
  2965
                                syms.voidType, List.nil(), syms.methodClass);
vromero@3251
  2966
                        clinit = new MethodSymbol(STATIC | SYNTHETIC | PRIVATE,
vromero@3251
  2967
                                names.clinit, clinitType, enclClass);
mcimadamore@5586
  2968
                        clinit.params = List.nil();
vromero@3251
  2969
                        clinits.put(enclClass, clinit);
vromero@3251
  2970
                    }
jlahoda@4103
  2971
                    newScopeOwner = clinit;
vromero@3251
  2972
                }
jlahoda@4103
  2973
                lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(newScopeOwner)));
mcimadamore@2191
  2974
            } else {
mcimadamore@2191
  2975
                lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
mcimadamore@2191
  2976
            }
mcimadamore@2191
  2977
            return lambdaEnv;
mcimadamore@2191
  2978
        }
mcimadamore@1990
  2979
mcimadamore@2195
  2980
    @Override
mcimadamore@2195
  2981
    public void visitReference(final JCMemberReference that) {
jjg@2213
  2982
        if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
jjg@2213
  2983
            if (pt().hasTag(NONE)) {
mcimadamore@2195
  2984
                //method reference only allowed in assignment or method invocation/cast context
mcimadamore@2195
  2985
                log.error(that.pos(), "unexpected.mref");
mcimadamore@2195
  2986
            }
mcimadamore@2195
  2987
            result = that.type = types.createErrorType(pt());
mcimadamore@2195
  2988
            return;
mcimadamore@2195
  2989
        }
mcimadamore@2195
  2990
        final Env<AttrContext> localEnv = env.dup(that);
mcimadamore@2195
  2991
        try {
mcimadamore@2195
  2992
            //attribute member reference qualifier - if this is a constructor
mcimadamore@2195
  2993
            //reference, the expected kind must be a type
jfranck@4203
  2994
            Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that));
mcimadamore@2195
  2995
mcimadamore@2195
  2996
            if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
mcimadamore@2195
  2997
                exprType = chk.checkConstructorRefType(that.expr, exprType);
vromero@3020
  2998
                if (!exprType.isErroneous() &&
vromero@3020
  2999
                    exprType.isRaw() &&
vromero@3020
  3000
                    that.typeargs != null) {
vromero@3020
  3001
                    log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
vromero@3020
  3002
                        diags.fragment("mref.infer.and.explicit.params"));
vromero@3020
  3003
                    exprType = types.createErrorType(exprType);
vromero@3020
  3004
                }
mcimadamore@2195
  3005
            }
mcimadamore@2195
  3006
mcimadamore@2195
  3007
            if (exprType.isErroneous()) {
mcimadamore@2195
  3008
                //if the qualifier expression contains problems,
jjg@2444
  3009
                //give up attribution of method reference
mcimadamore@2195
  3010
                result = that.type = exprType;
mcimadamore@2195
  3011
                return;
mcimadamore@2195
  3012
            }
mcimadamore@2195
  3013
mcimadamore@2709
  3014
            if (TreeInfo.isStaticSelector(that.expr, names)) {
mcimadamore@2709
  3015
                //if the qualifier is a type, validate it; raw warning check is
mcimadamore@2709
  3016
                //omitted as we don't know at this stage as to whether this is a
mcimadamore@2709
  3017
                //raw selector (because of inference)
mcimadamore@2709
  3018
                chk.validate(that.expr, env, false);
sadayapalam@4640
  3019
            } else {
sadayapalam@4640
  3020
                Symbol lhsSym = TreeInfo.symbol(that.expr);
sadayapalam@4640
  3021
                localEnv.info.selectSuper = lhsSym != null && lhsSym.name == names._super;
mcimadamore@2195
  3022
            }
mcimadamore@2195
  3023
            //attrib type-arguments
mcimadamore@2275
  3024
            List<Type> typeargtypes = List.nil();
mcimadamore@2195
  3025
            if (that.typeargs != null) {
mcimadamore@2195
  3026
                typeargtypes = attribTypes(that.typeargs, localEnv);
mcimadamore@2195
  3027
            }
mcimadamore@2195
  3028
vromero@3964
  3029
            boolean isTargetSerializable =
vromero@3964
  3030
                    resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
mcimadamore@4608
  3031
                    isSerializable(pt());
mcimadamore@4608
  3032
            TargetInfo targetInfo = getTargetInfo(that, resultInfo, null);
mcimadamore@4608
  3033
            Type currentTarget = targetInfo.target;
mcimadamore@4608
  3034
            Type desc = targetInfo.descriptor;
mcimadamore@2195
  3035
vromero@3964
  3036
            setFunctionalInfo(localEnv, that, pt(), desc, currentTarget, resultInfo.checkContext);
mcimadamore@2195
  3037
            List<Type> argtypes = desc.getParameterTypes();
mcimadamore@2888
  3038
            Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck;
mcimadamore@2888
  3039
mcimadamore@2888
  3040
            if (resultInfo.checkContext.inferenceContext().free(argtypes)) {
mcimadamore@2888
  3041
                referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
mcimadamore@2888
  3042
            }
mcimadamore@2888
  3043
mcimadamore@2888
  3044
            Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null;
mcimadamore@2888
  3045
            List<Type> saved_undet = resultInfo.checkContext.inferenceContext().save();
mcimadamore@2888
  3046
            try {
vromero@3220
  3047
                refResult = rs.resolveMemberReference(localEnv, that, that.expr.type,
vromero@3220
  3048
                        that.name, argtypes, typeargtypes, referenceCheck,
mcimadamore@4366
  3049
                        resultInfo.checkContext.inferenceContext(), rs.basicReferenceChooser);
mcimadamore@2888
  3050
            } finally {
mcimadamore@2888
  3051
                resultInfo.checkContext.inferenceContext().rollback(saved_undet);
mcimadamore@2888
  3052
            }
mcimadamore@2195
  3053
mcimadamore@2195
  3054
            Symbol refSym = refResult.fst;
mcimadamore@2195
  3055
            Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
mcimadamore@2195
  3056
vromero@4443
  3057
            /** this switch will need to go away and be replaced by the new RESOLUTION_TARGET testing
vromero@4443
  3058
             *  JDK-8075541
vromero@4443
  3059
             */
mcimadamore@2195
  3060
            if (refSym.kind != MTH) {
mcimadamore@2195
  3061
                boolean targetError;
mcimadamore@2195
  3062
                switch (refSym.kind) {
mcimadamore@2195
  3063
                    case ABSENT_MTH:
vromero@4443
  3064
                    case MISSING_ENCL:
mcimadamore@2195
  3065
                        targetError = false;
mcimadamore@2195
  3066
                        break;
mcimadamore@2195
  3067
                    case WRONG_MTH:
mcimadamore@2195
  3068
                    case WRONG_MTHS:
mcimadamore@2195
  3069
                    case AMBIGUOUS:
mcimadamore@2195
  3070
                    case HIDDEN:
mcimadamore@2195
  3071
                    case STATICERR:
mcimadamore@2195
  3072
                        targetError = true;
mcimadamore@2195
  3073
                        break;
mcimadamore@2195
  3074
                    default:
mcimadamore@2195
  3075
                        Assert.error("unexpected result kind " + refSym.kind);
mcimadamore@2195
  3076
                        targetError = false;
mcimadamore@2195
  3077
                }
mcimadamore@2195
  3078
vromero@3992
  3079
                JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol()).getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT,
mcimadamore@2195
  3080
                                that, exprType.tsym, exprType, that.name, argtypes, typeargtypes);
mcimadamore@2195
  3081
mcimadamore@2195
  3082
                JCDiagnostic.DiagnosticType diagKind = targetError ?
mcimadamore@2195
  3083
                        JCDiagnostic.DiagnosticType.FRAGMENT : JCDiagnostic.DiagnosticType.ERROR;
mcimadamore@2195
  3084
mcimadamore@2195
  3085
                JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that,
mcimadamore@2195
  3086
                        "invalid.mref", Kinds.kindName(that.getMode()), detailsDiag);
mcimadamore@2195
  3087
vromero@3964
  3088
                if (targetError && currentTarget == Type.recoveryType) {
mcimadamore@2260
  3089
                    //a target error doesn't make sense during recovery stage
mcimadamore@2260
  3090
                    //as we don't know what actual parameter types are
vromero@3964
  3091
                    result = that.type = currentTarget;
mcimadamore@2260
  3092
                    return;
mcimadamore@2195
  3093
                } else {
mcimadamore@2260
  3094
                    if (targetError) {
mcimadamore@2260
  3095
                        resultInfo.checkContext.report(that, diag);
mcimadamore@2260
  3096
                    } else {
mcimadamore@2260
  3097
                        log.report(diag);
mcimadamore@2260
  3098
                    }
vromero@3964
  3099
                    result = that.type = types.createErrorType(currentTarget);
mcimadamore@2260
  3100
                    return;
mcimadamore@2195
  3101
                }
mcimadamore@2195
  3102
            }
mcimadamore@2195
  3103
mcimadamore@2489
  3104
            that.sym = refSym.baseSymbol();
mcimadamore@2489
  3105
            that.kind = lookupHelper.referenceKind(that.sym);
mcimadamore@2524
  3106
            that.ownerAccessible = rs.isAccessible(localEnv, that.sym.enclClass());
mcimadamore@2489
  3107
mcimadamore@2519
  3108
            if (desc.getReturnType() == Type.recoveryType) {
mcimadamore@2519
  3109
                // stop here
vromero@3964
  3110
                result = that.type = currentTarget;
mcimadamore@2519
  3111
                return;
mcimadamore@2519
  3112
            }
mcimadamore@2519
  3113
sadayapalam@5722
  3114
            if (!env.info.isSpeculative && that.getMode() == JCMemberReference.ReferenceMode.NEW) {
sadayapalam@5722
  3115
                Type enclosingType = exprType.getEnclosingType();
sadayapalam@5722
  3116
                if (enclosingType != null && enclosingType.hasTag(CLASS)) {
sadayapalam@5722
  3117
                    // Check for the existence of an apropriate outer instance
sadayapalam@5722
  3118
                    rs.resolveImplicitThis(that.pos(), env, exprType);
sadayapalam@5722
  3119
                }
sadayapalam@5722
  3120
            }
sadayapalam@5722
  3121
mcimadamore@2275
  3122
            if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
mcimadamore@2519
  3123
mcimadamore@2709
  3124
                if (that.getMode() == ReferenceMode.INVOKE &&
mcimadamore@2709
  3125
                        TreeInfo.isStaticSelector(that.expr, names) &&
mcimadamore@2709
  3126
                        that.kind.isUnbound() &&
mcimadamore@2709
  3127
                        !desc.getParameterTypes().head.isParameterized()) {
mcimadamore@2709
  3128
                    chk.checkRaw(that.expr, localEnv);
mcimadamore@2709
  3129
                }
mcimadamore@2709
  3130
mcimadamore@2489
  3131
                if (that.sym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) &&
mcimadamore@2275
  3132
                        exprType.getTypeArguments().nonEmpty()) {
mcimadamore@2275
  3133
                    //static ref with class type-args
mcimadamore@2275
  3134
                    log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
mcimadamore@2275
  3135
                            diags.fragment("static.mref.with.targs"));
vromero@3964
  3136
                    result = that.type = types.createErrorType(currentTarget);
mcimadamore@2275
  3137
                    return;
mcimadamore@2275
  3138
                }
mcimadamore@2275
  3139
mcimadamore@2489
  3140
                if (!refSym.isStatic() && that.kind == JCMemberReference.ReferenceKind.SUPER) {
mcimadamore@2489
  3141
                    // Check that super-qualified symbols are not abstract (JLS)
mcimadamore@2489
  3142
                    rs.checkNonAbstract(that.pos(), that.sym);
mcimadamore@2489
  3143
                }
vromero@3964
  3144
vromero@3964
  3145
                if (isTargetSerializable) {
vromero@5460
  3146
                    chk.checkAccessFromSerializableElement(that, true);
vromero@3964
  3147
                }
mcimadamore@2275
  3148
            }
mcimadamore@2275
  3149
mcimadamore@2195
  3150
            ResultInfo checkInfo =
mcimadamore@2195
  3151
                    resultInfo.dup(newMethodTemplate(
jjg@2213
  3152
                        desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
vromero@3993
  3153
                        that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes),
sadayapalam@4483
  3154
                        new FunctionalReturnContext(resultInfo.checkContext), CheckMode.NO_TREE_UPDATE);
sadayapalam@4483
  3155
sadayapalam@4483
  3156
            Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo);
mcimadamore@2195
  3157
mcimadamore@2888
  3158
            if (that.kind.isUnbound() &&
mcimadamore@2888
  3159
                    resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
mcimadamore@2888
  3160
                //re-generate inference constraints for unbound receiver
vromero@3885
  3161
                if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asUndetVar(argtypes.head), exprType)) {
mcimadamore@2888
  3162
                    //cannot happen as this has already been checked - we just need
mcimadamore@2888
  3163
                    //to regenerate the inference constraints, as that has been lost
mcimadamore@2888
  3164
                    //as a result of the call to inferenceContext.save()
mcimadamore@2888
  3165
                    Assert.error("Can't get here");
mcimadamore@2888
  3166
                }
mcimadamore@2888
  3167
            }
mcimadamore@2888
  3168
mcimadamore@2195
  3169
            if (!refType.isErroneous()) {
mcimadamore@2195
  3170
                refType = types.createMethodTypeWithReturn(refType,
mcimadamore@5279
  3171
                        adjustMethodReturnType(refSym, lookupHelper.site, that.name, checkInfo.pt.getParameterTypes(), refType.getReturnType()));
mcimadamore@2195
  3172
            }
mcimadamore@2195
  3173
mcimadamore@2195
  3174
            //go ahead with standard method reference compatibility check - note that param check
mcimadamore@2195
  3175
            //is a no-op (as this has been taken care during method applicability)
mcimadamore@2195
  3176
            boolean isSpeculativeRound =
mcimadamore@2195
  3177
                    resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
mcimadamore@4339
  3178
mcimadamore@4339
  3179
            that.type = currentTarget; //avoids recovery at this stage
mcimadamore@2195
  3180
            checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
mcimadamore@2195
  3181
            if (!isSpeculativeRound) {
vromero@3964
  3182
                checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget);
mcimadamore@2195
  3183
            }
emc@4248
  3184
            result = check(that, currentTarget, KindSelector.VAL, resultInfo);
mcimadamore@2195
  3185
        } catch (Types.FunctionDescriptorLookupError ex) {
mcimadamore@2195
  3186
            JCDiagnostic cause = ex.getDiagnostic();
mcimadamore@2195
  3187
            resultInfo.checkContext.report(that, cause);
mcimadamore@2195
  3188
            result = that.type = types.createErrorType(pt());
mcimadamore@2195
  3189
            return;
mcimadamore@2195
  3190
        }
mcimadamore@2195
  3191
    }
mcimadamore@2490
  3192
    //where
mcimadamore@2490
  3193
        ResultInfo memberReferenceQualifierResult(JCMemberReference tree) {
mcimadamore@2490
  3194
            //if this is a constructor reference, the expected kind must be a type
emc@4248
  3195
            return new ResultInfo(tree.getMode() == ReferenceMode.INVOKE ?
emc@4248
  3196
                                  KindSelector.VAL_TYP : KindSelector.TYP,
emc@4248
  3197
                                  Type.noType);
mcimadamore@2490
  3198
        }
mcimadamore@2490
  3199
mcimadamore@2195
  3200
mcimadamore@2195
  3201
    @SuppressWarnings("fallthrough")
mcimadamore@2195
  3202
    void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) {
jfranck@4376
  3203
        InferenceContext inferenceContext = checkContext.inferenceContext();
jfranck@4376
  3204
        Type returnType = inferenceContext.asUndetVar(descriptor.getReturnType());
mcimadamore@2195
  3205
mcimadamore@2195
  3206
        Type resType;
mcimadamore@2195
  3207
        switch (tree.getMode()) {
mcimadamore@2195
  3208
            case NEW:
mcimadamore@2195
  3209
                if (!tree.expr.type.isRaw()) {
mcimadamore@2195
  3210
                    resType = tree.expr.type;
mcimadamore@2195
  3211
                    break;
mcimadamore@2195
  3212
                }
mcimadamore@2195
  3213
            default:
mcimadamore@2195
  3214
                resType = refType.getReturnType();
mcimadamore@2195
  3215
        }
mcimadamore@2195
  3216
mcimadamore@2195
  3217
        Type incompatibleReturnType = resType;
mcimadamore@2195
  3218
jjg@2213
  3219
        if (returnType.hasTag(VOID)) {
mcimadamore@2195
  3220
            incompatibleReturnType = null;
mcimadamore@2195
  3221
        }
mcimadamore@2195
  3222
jjg@2213
  3223
        if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
mcimadamore@2195
  3224
            if (resType.isErroneous() ||
mcimadamore@5813
  3225
                    new FunctionalReturnContext(checkContext).compatible(resType, returnType,
mcimadamore@5813
  3226
                            checkContext.checkWarner(tree, resType, returnType))) {
mcimadamore@2195
  3227
                incompatibleReturnType = null;
mcimadamore@2195
  3228
            }
mcimadamore@2195
  3229
        }
mcimadamore@2195
  3230
mcimadamore@2195
  3231
        if (incompatibleReturnType != null) {
mcimadamore@2195
  3232
            checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref",
mcimadamore@2195
  3233
                    diags.fragment("inconvertible.types", resType, descriptor.getReturnType())));
jfranck@4376
  3234
        } else {
jfranck@4376
  3235
            if (inferenceContext.free(refType)) {
jfranck@4376
  3236
                // we need to wait for inference to finish and then replace inference vars in the referent type
jfranck@4376
  3237
                inferenceContext.addFreeTypeListener(List.of(refType),
jfranck@4376
  3238
                        instantiatedContext -> {
jfranck@4376
  3239
                            tree.referentType = instantiatedContext.asInstType(refType);
jfranck@4376
  3240
                        });
jfranck@4376
  3241
            } else {
jfranck@4376
  3242
                tree.referentType = refType;
jfranck@4376
  3243
            }
mcimadamore@2195
  3244
        }
mcimadamore@2195
  3245
mcimadamore@2195
  3246
        if (!speculativeAttr) {
jfranck@4376
  3247
            List<Type> thrownTypes = inferenceContext.asUndetVars(descriptor.getThrownTypes());
mcimadamore@2195
  3248
            if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) {
mcimadamore@2195
  3249
                log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
mcimadamore@2195
  3250
            }
mcimadamore@5559
  3251
            //18.2.5: "In addition, for all j (1 <= j <= n), the constraint reduces to the bound throws Ej"
mcimadamore@5559
  3252
            thrownTypes.stream()
mcimadamore@5559
  3253
                    .filter(t -> t.hasTag(UNDETVAR))
mcimadamore@5559
  3254
                    .forEach(t -> ((UndetVar)t).setThrow());
mcimadamore@2195
  3255
        }
mcimadamore@2195
  3256
    }
mcimadamore@2195
  3257
mcimadamore@2361
  3258
    /**
mcimadamore@2361
  3259
     * Set functional type info on the underlying AST. Note: as the target descriptor
mcimadamore@2361
  3260
     * might contain inference variables, we might need to register an hook in the
mcimadamore@2361
  3261
     * current inference context.
mcimadamore@2361
  3262
     */
mcimadamore@2873
  3263
    private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr,
mcimadamore@2873
  3264
            final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) {
mcimadamore@2873
  3265
        if (checkContext.inferenceContext().free(descriptorType)) {
mcimadamore@5585
  3266
            checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType),
mcimadamore@5585
  3267
                    inferenceContext -> setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType),
mcimadamore@5585
  3268
                    inferenceContext.asInstType(primaryTarget), checkContext));
mcimadamore@2361
  3269
        } else {
alundblad@3063
  3270
            ListBuffer<Type> targets = new ListBuffer<>();
mcimadamore@2361
  3271
            if (pt.hasTag(CLASS)) {
mcimadamore@2361
  3272
                if (pt.isCompound()) {
mcimadamore@2873
  3273
                    targets.append(types.removeWildcards(primaryTarget)); //this goes first
mcimadamore@2361
  3274
                    for (Type t : ((IntersectionClassType)pt()).interfaces_field) {
mcimadamore@2607
  3275
                        if (t != primaryTarget) {
mcimadamore@2873
  3276
                            targets.append(types.removeWildcards(t));
mcimadamore@2607
  3277
                        }
mcimadamore@2361
  3278
                    }
mcimadamore@2361
  3279
                } else {
mcimadamore@2873
  3280
                    targets.append(types.removeWildcards(primaryTarget));
mcimadamore@2361
  3281
                }
mcimadamore@2361
  3282
            }
mcimadamore@2361
  3283
            fExpr.targets = targets.toList();
mcimadamore@2873
  3284
            if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
mcimadamore@2873
  3285
                    pt != Type.recoveryType) {
mcimadamore@2873
  3286
                //check that functional interface class is well-formed
vromero@4053
  3287
                try {
vromero@4053
  3288
                    /* Types.makeFunctionalInterfaceClass() may throw an exception
vromero@4053
  3289
                     * when it's executed post-inference. See the listener code
vromero@4053
  3290
                     * above.
vromero@4053
  3291
                     */
vromero@4053
  3292
                    ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
vromero@4053
  3293
                            names.empty, List.of(fExpr.targets.head), ABSTRACT);
vromero@4053
  3294
                    if (csym != null) {
vromero@4053
  3295
                        chk.checkImplementations(env.tree, csym, csym);
mcimadamore@4431
  3296
                        try {
mcimadamore@4431
  3297
                            //perform an additional functional interface check on the synthetic class,
mcimadamore@4431
  3298
                            //as there may be spurious errors for raw targets - because of existing issues
mcimadamore@4431
  3299
                            //with membership and inheritance (see JDK-8074570).
mcimadamore@4431
  3300
                            csym.flags_field |= INTERFACE;
mcimadamore@4431
  3301
                            types.findDescriptorType(csym.type);
mcimadamore@4431
  3302
                        } catch (FunctionDescriptorLookupError err) {
mcimadamore@4431
  3303
                            resultInfo.checkContext.report(fExpr,
mcimadamore@4431
  3304
                                    diags.fragment(Fragments.NoSuitableFunctionalIntfInst(fExpr.targets.head)));
mcimadamore@4431
  3305
                        }
vromero@4053
  3306
                    }
vromero@4053
  3307
                } catch (Types.FunctionDescriptorLookupError ex) {
vromero@4053
  3308
                    JCDiagnostic cause = ex.getDiagnostic();
vromero@4053
  3309
                    resultInfo.checkContext.report(env.tree, cause);
mcimadamore@2935
  3310
                }
mcimadamore@2873
  3311
            }
mcimadamore@2361
  3312
        }
mcimadamore@2361
  3313
    }
mcimadamore@2361
  3314
duke@0
  3315
    public void visitParens(JCParens tree) {
mcimadamore@2063
  3316
        Type owntype = attribTree(tree.expr, env, resultInfo);
mcimadamore@2063
  3317
        result = check(tree, owntype, pkind(), resultInfo);
duke@0
  3318
        Symbol sym = TreeInfo.symbol(tree);
emc@4248
  3319
        if (sym != null && sym.kind.matches(KindSelector.TYP_PCK))
duke@0
  3320
            log.error(tree.pos(), "illegal.start.of.type");
duke@0
  3321
    }
duke@0
  3322
duke@0
  3323
    public void visitAssign(JCAssign tree) {
jlahoda@4301
  3324
        Type owntype = attribTree(tree.lhs, env.dup(tree), varAssignmentInfo);
duke@0
  3325
        Type capturedType = capture(owntype);
duke@0
  3326
        attribExpr(tree.rhs, env, owntype);
emc@4248
  3327
        result = check(tree, capturedType, KindSelector.VAL, resultInfo);
duke@0
  3328
    }
duke@0
  3329
duke@0
  3330
    public void visitAssignop(JCAssignOp tree) {
duke@0
  3331
        // Attribute arguments.
jlahoda@4301
  3332
        Type owntype = attribTree(tree.lhs, env, varAssignmentInfo);
duke@0
  3333
        Type operand = attribExpr(tree.rhs, env);
duke@0
  3334
        // Find operator.
mcimadamore@4399
  3335
        Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), owntype, operand);
vromero@5289
  3336
        if (operator != operators.noOpSymbol &&
mcimadamore@1318
  3337
                !owntype.isErroneous() &&
mcimadamore@1318
  3338
                !operand.isErroneous()) {
jjg@191
  3339
            chk.checkDivZero(tree.rhs.pos(), operator, operand);
jjg@191
  3340
            chk.checkCastable(tree.rhs.pos(),
jjg@191
  3341
                              operator.type.getReturnType(),
jjg@191
  3342
                              owntype);
duke@0
  3343
        }
emc@4248
  3344
        result = check(tree, owntype, KindSelector.VAL, resultInfo);
duke@0
  3345
    }
duke@0
  3346
duke@0
  3347
    public void visitUnary(JCUnary tree) {
duke@0
  3348
        // Attribute arguments.
jjg@1972
  3349
        Type argtype = (tree.getTag().isIncOrDecUnaryOp())
jlahoda@4301
  3350
            ? attribTree(tree.arg, env, varAssignmentInfo)
duke@0
  3351
            : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
duke@0
  3352
duke@0
  3353
        // Find operator.
mcimadamore@4399
  3354
        Symbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype);
jjg@289
  3355
        Type owntype = types.createErrorType(tree.type);
vromero@5289
  3356
        if (operator != operators.noOpSymbol &&
mcimadamore@1318
  3357
                !argtype.isErroneous()) {
jjg@1972
  3358
            owntype = (tree.getTag().isIncOrDecUnaryOp())
duke@0
  3359
                ? tree.arg.type
duke@0
  3360
                : operator.type.getReturnType();
duke@0
  3361
            int opc = ((OperatorSymbol)operator).opcode;
duke@0
  3362
duke@0
  3363
            // If the argument is constant, fold it.
duke@0
  3364
            if (argtype.constValue() != null) {
duke@0
  3365
                Type ctype = cfolder.fold1(opc, argtype);
duke@0
  3366
                if (ctype != null) {
duke@0
  3367
                    owntype = cfolder.coerce(ctype, owntype);
duke@0
  3368
                }
duke@0
  3369
            }
duke@0
  3370
        }
emc@4248
  3371
        result = check(tree, owntype, KindSelector.VAL, resultInfo);
duke@0
  3372
    }
duke@0
  3373
duke@0
  3374
    public void visitBinary(JCBinary tree) {
dbalek@2476
  3375
        boolean baCatched = false;
dbalek@2476
  3376
        try {
dbalek@2476
  3377
            // Attribute arguments.
dbalek@3532
  3378
            Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
dbalek@4654
  3379
            Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env));
dbalek@2476
  3380
            // Find operator.
dbalek@4426
  3381
            Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
dbalek@2476
  3382
            Type owntype = types.createErrorType(tree.type);
dbalek@5318
  3383
            if (operator != operators.noOpSymbol &&
dbalek@2476
  3384
                    !left.isErroneous() &&
dbalek@2476
  3385
                    !right.isErroneous()) {
dbalek@2476
  3386
                owntype = operator.type.getReturnType();
dbalek@4426
  3387
                int opc = ((OperatorSymbol)operator).opcode;
dbalek@2476
  3388
                // If both arguments are constants, fold them.
dbalek@2476
  3389
                if (left.constValue() != null && right.constValue() != null) {
dbalek@2476
  3390
                    Type ctype = cfolder.fold2(opc, left, right);
dbalek@2476
  3391
                    if (ctype != null) {
dbalek@2476
  3392
                        owntype = cfolder.coerce(ctype, owntype);
mcimadamore@18
  3393
                    }
mcimadamore@18
  3394
                }
dbalek@2476
  3395
dbalek@2476
  3396
                // Check that argument types of a reference ==, != are
dbalek@2866
  3397
                // castable to each other, (JLS 15.21).  Note: unboxing
dbalek@2866
  3398
                // comparisons will not have an acmp* opc at this point.
dbalek@2476
  3399
                if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
dbalek@4426
  3400
                    if (!types.isCastable(left, right, new Warner(tree.pos()))) {
dbalek@2476
  3401
                        log.error(tree.pos(), "incomparable.types", left, right);
dbalek@2476
  3402
                    }
dbalek@2476
  3403
                }
dbalek@2476
  3404
dbalek@2476
  3405
                chk.checkDivZero(tree.rhs.pos(), operator, right);
mcimadamore@18
  3406
            }
dbalek@4426
  3407
            result = check(tree, owntype, KindSelector.VAL, resultInfo);
dbalek@2476
  3408
        } catch (BreakAttr ba) {
dbalek@2476
  3409
            baCatched = true;
dbalek@2476
  3410
            throw ba;
dbalek@2476
  3411
        } finally {
dbalek@2476
  3412
            if ((baCatched || result.isErroneous()) && tree.hasTag(BITAND)) {
dbalek@2476
  3413
                //error recovery
dbalek@3532
  3414
                TreeScanner treeCleaner = new TreeScanner() {
dbalek@3532
  3415
                    public void scan(JCTree node) {
dbalek@3532
  3416
                        super.scan(node);
dbalek@3532
  3417
                        if (node != null)
dbalek@3532
  3418
                            node.type = null;
dbalek@3532
  3419
                    }
dbalek@3532
  3420
                    public void visitClassDef(JCClassDecl node) {
dbalek@3532
  3421
                        node.sym = null;
dbalek@3532
  3422
                        super.visitClassDef(node);
dbalek@3532
  3423
                    }
dbalek@3532
  3424
                    public void visitMethodDef(JCMethodDecl node) {
dbalek@3532
  3425
                        node.sym = null;
dbalek@3532
  3426
                        super.visitMethodDef(node);
dbalek@3532
  3427
                    }
dbalek@3532
  3428
                    public void visitVarDef(JCVariableDecl node) {
dbalek@3532
  3429
                        node.sym = null;
dbalek@3532
  3430
                        super.visitVarDef(node);
dbalek@3532
  3431
                    }
dbalek@3532
  3432
                    public void visitNewClass(JCNewClass node) {
dbalek@3532
  3433
                        node.constructor = null;
dbalek@3532
  3434
                        super.visitNewClass(node);
dbalek@3532
  3435
                    }
dbalek@3532
  3436
                    public void visitAssignop(JCAssignOp node) {
dbalek@3532
  3437
                        node.operator = null;
dbalek@3532
  3438
                        super.visitAssignop(node);
dbalek@3532
  3439
                    }
dbalek@3532
  3440
                    public void visitUnary(JCUnary node) {
dbalek@3532
  3441
                        node.operator = null;
dbalek@3532
  3442
                        super.visitUnary(node);
dbalek@3532
  3443
                    }
dbalek@3532
  3444
                    public void visitBinary(JCBinary node) {
dbalek@3532
  3445
                        node.operator = null;
dbalek@3532
  3446
                        super.visitBinary(node);
dbalek@3532
  3447
                    }
dbalek@3532
  3448
                    public void visitSelect(JCFieldAccess node) {
dbalek@3532
  3449
                        node.sym = null;
dbalek@3532
  3450
                        super.visitSelect(node);
dbalek@3532
  3451
                    }
dbalek@3532
  3452
                    public void visitIdent(JCIdent node) {
dbalek@3532
  3453
                        node.sym = null;
dbalek@3532
  3454
                        super.visitIdent(node);
dbalek@3532
  3455
                    }
dbalek@3532
  3456
                    public void visitAnnotation(JCAnnotation node) {
dbalek@3532
  3457
                        node.attribute = null;
dbalek@3532
  3458
                        super.visitAnnotation(node);
dbalek@3532
  3459
                    }
dbalek@3532
  3460
                };
sdedic@3533
  3461
                // attribTree will change the 'result', save it:
sdedic@3533
  3462
                Type saveResult = this.result;
dbalek@3532
  3463
                treeCleaner.scan(tree.lhs);
dbalek@4426
  3464
                attribTree(tree.lhs, env, new ResultInfo(KindSelector.VAL_TYP , Type.noType));
dbalek@3532
  3465
                treeCleaner.scan(tree.rhs);
dbalek@4426
  3466
                attribTree(tree.rhs, env, new ResultInfo(KindSelector.VAL_TYP , Type.noType));                
sdedic@3533
  3467
                this.result = saveResult;
dbalek@2476
  3468
                List<JCExpression> bounds = collectIntersectionBounds(tree);
dbalek@2476
  3469
                if (bounds != null) {
dbalek@2477
  3470
                    Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log);
dbalek@2477
  3471
                    try {
dbalek@2477
  3472
                        Type owntype = checkIntersection(tree, bounds);
dbalek@2477
  3473
                        if (!owntype.isErroneous()) {
dbalek@2477
  3474
                            tree.type = result = owntype;
dbalek@2477
  3475
                        }
dbalek@2477
  3476
                    } finally {
dbalek@2477
  3477
                        log.popDiagnosticHandler(discardHandler);
dbalek@2477
  3478
                    }
duke@0
  3479
                }
duke@0
  3480
            }
mcimadamore@18
  3481
        }
dbalek@2476
  3482
    }
dbalek@2476
  3483
    
dbalek@2476
  3484
    private List<JCExpression> collectIntersectionBounds(JCTree tree) {
dbalek@2476
  3485
        if (tree.hasTag(BITAND)) {
dbalek@2476
  3486
            List<JCExpression> left = collectIntersectionBounds(((JCBinary)tree).lhs);
dbalek@2476
  3487
            if (left != null) {
dbalek@2476
  3488
                List<JCExpression> right = collectIntersectionBounds(((JCBinary)tree).rhs);
dbalek@2476
  3489
                if (right != null) {
dbalek@2476
  3490
                    return left.appendList(right);
duke@0
  3491
                }
duke@0
  3492
            }
dbalek@2746
  3493
        } else if (tree instanceof JCExpression && tree.type != null) {
dbalek@2477
  3494
            return List.of((JCExpression)tree);
duke@0
  3495
        }
dbalek@2476
  3496
        return null;
duke@0
  3497
    }
duke@0
  3498
mcimadamore@2190
  3499
    public void visitTypeCast(final JCTypeCast tree) {
jfranck@4203
  3500
        Type clazztype = attribType(tree.clazz, env);
mcimadamore@1042
  3501
        chk.validate(tree.clazz, env, false);
mcimadamore@1077
  3502
        //a fresh environment is required for 292 inference to work properly ---
mcimadamore@1077
  3503
        //see Infer.instantiatePolymorphicSignatureInstance()
mcimadamore@1077
  3504
        Env<AttrContext> localEnv = env.dup(tree);
mcimadamore@2190
  3505
        //should we propagate the target type?
mcimadamore@2190
  3506
        final ResultInfo castInfo;
mcimadamore@2626
  3507
        JCExpression expr = TreeInfo.skipParens(tree.expr);
dbalek@2920
  3508
        boolean isPoly = expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE);
mcimadamore@2190
  3509
        if (isPoly) {
mcimadamore@2190
  3510
            //expression is a poly - we need to propagate target type info
emc@4248
  3511
            castInfo = new ResultInfo(KindSelector.VAL, clazztype,
emc@4248
  3512
                                      new Check.NestedCheckContext(resultInfo.checkContext) {
mcimadamore@2190
  3513
                @Override
mcimadamore@2190
  3514
                public boolean compatible(Type found, Type req, Warner warn) {
mcimadamore@2190
  3515
                    return types.isCastable(found, req, warn);
mcimadamore@2190
  3516
                }
mcimadamore@2190
  3517
            });
mcimadamore@2190
  3518
        } else {
mcimadamore@2190
  3519
            //standalone cast - target-type info is not propagated
mcimadamore@2190
  3520
            castInfo = unknownExprInfo;
mcimadamore@2190
  3521
        }
mcimadamore@2190
  3522
        Type exprtype = attribTree(tree.expr, localEnv, castInfo);
mcimadamore@2190
  3523
        Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
duke@0
  3524
        if (exprtype.constValue() != null)
duke@0
  3525
            owntype = cfolder.coerce(exprtype, owntype);
emc@4248
  3526
        result = check(tree, capture(owntype), KindSelector.VAL, resultInfo);
mcimadamore@2190
  3527
        if (!isPoly)
mcimadamore@2190
  3528
            chk.checkRedundantCast(localEnv, tree);
duke@0
  3529
    }
duke@0
  3530
duke@0
  3531
    public void visitTypeTest(JCInstanceOf tree) {
duke@0
  3532
        Type exprtype = chk.checkNullOrRefType(
emc@4248
  3533
                tree.expr.pos(), attribExpr(tree.expr, env));
jfranck@4203
  3534
        Type clazztype = attribType(tree.clazz, env);
kizune@3065
  3535
        if (!clazztype.hasTag(TYPEVAR)) {
kizune@3065
  3536
            clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype);
kizune@3065
  3537
        }
kizune@3065
  3538
        if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) {
kizune@3065
  3539
            log.error(tree.clazz.pos(), "illegal.generic.type.for.instof");
kizune@3065
  3540
            clazztype = types.createErrorType(clazztype);
kizune@3065
  3541
        }
mcimadamore@1042
  3542
        chk.validate(tree.clazz, env, false);
duke@0
  3543
        chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
emc@4248
  3544
        result = check(tree, syms.booleanType, KindSelector.VAL, resultInfo);
duke@0
  3545
    }
duke@0
  3546
duke@0
  3547
    public void visitIndexed(JCArrayAccess tree) {
jjg@289
  3548
        Type owntype = types.createErrorType(tree.type);
duke@0
  3549
        Type atype = attribExpr(tree.indexed, env);
duke@0
  3550
        attribExpr(tree.index, env, syms.intType);
duke@0
  3551
        if (types.isArray(atype))
duke@0
  3552
            owntype = types.elemtype(atype);
jjg@2213
  3553
        else if (!atype.hasTag(ERROR))
duke@0
  3554
            log.error(tree.pos(), "array.req.but.found", atype);
emc@4248
  3555
        if (!pkind().contains(KindSelector.VAL))
emc@4248
  3556
            owntype = capture(owntype);
emc@4248
  3557
        result = check(tree, owntype, KindSelector.VAR, resultInfo);
duke@0
  3558
    }
duke@0
  3559
duke@0
  3560
    public void visitIdent(JCIdent tree) {
duke@0
  3561
        Symbol sym;
duke@0
  3562
duke@0
  3563
        // Find symbol
jjg@2213
  3564
        if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
duke@0
  3565
            // If we are looking for a method, the prototype `pt' will be a
duke@0
  3566
            // method type with the type of the call's arguments as parameters.
mcimadamore@2190
  3567
            env.info.pendingResolutionPhase = null;
mcimadamore@2063
  3568
            sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments());
duke@0
  3569
        } else if (tree.sym != null && tree.sym.kind != VAR) {
duke@0
  3570
            sym = tree.sym;
duke@0
  3571
        } else {
mcimadamore@2063
  3572
            sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind());
duke@0
  3573
        }
duke@0
  3574
        tree.sym = sym;
duke@0
  3575
duke@0
  3576
        // (1) Also find the environment current for the class where
duke@0
  3577
        //     sym is defined (`symEnv').
duke@0
  3578
        // Only for pre-tiger versions (1.4 and earlier):
duke@0
  3579
        // (2) Also determine whether we access symbol out of an anonymous
duke@0
  3580
        //     class in a this or super call.  This is illegal for instance
duke@0
  3581
        //     members since such classes don't carry a this$n link.
duke@0
  3582
        //     (`noOuterThisPath').
duke@0
  3583
        Env<AttrContext> symEnv = env;
duke@0
  3584
        boolean noOuterThisPath = false;
duke@0
  3585
        if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class
emc@4248
  3586
            sym.kind.matches(KindSelector.VAL_MTH) &&
duke@0
  3587
            sym.owner.kind == TYP &&
duke@0
  3588
            tree.name != names._this && tree.name != names._super) {
duke@0
  3589
duke@0
  3590
            // Find environment in which identifier is defined.
duke@0
  3591
            while (symEnv.outer != null &&
duke@0
  3592
                   !sym.isMemberOf(symEnv.enclClass.sym, types)) {
duke@0
  3593
                if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0)
ntoda@4105
  3594
                    noOuterThisPath = false;
duke@0
  3595
                symEnv = symEnv.outer;
duke@0
  3596
            }
duke@0
  3597
        }
duke@0
  3598
duke@0
  3599
        // If symbol is a variable, ...
duke@0
  3600
        if (sym.kind == VAR) {
duke@0
  3601
            VarSymbol v = (VarSymbol)sym;
duke@0
  3602
duke@0
  3603
            // ..., evaluate its initializer, if it has one, and check for
duke@0
  3604
            // illegal forward reference.
duke@0
  3605
            checkInit(tree, env, v, false);
duke@0
  3606
duke@0
  3607
            // If we are expecting a variable (as opposed to a value), check
duke@0
  3608
            // that the variable is assignable in the current environment.
jlahoda@4301
  3609
            if (KindSelector.ASG.subset(pkind()))
duke@0
  3610
                checkAssignable(tree.pos(), v, null, env);
duke@0
  3611
        }
duke@0
  3612
duke@0
  3613
        // In a constructor body,
duke@0
  3614
        // if symbol is a field or instance method, check that it is
duke@0
  3615
        // not accessed before the supertype constructor is called.
duke@0
  3616
        if ((symEnv.info.isSelfCall || noOuterThisPath) &&
emc@4248
  3617
            sym.kind.matches(KindSelector.VAL_MTH) &&
duke@0
  3618
            sym.owner.kind == TYP &&
duke@0
  3619
            (sym.flags() & STATIC) == 0) {
emc@4248
  3620
            chk.earlyRefError(tree.pos(), sym.kind == VAR ?
emc@4248
  3621
                                          sym : thisSym(tree.pos(), env));
duke@0
  3622
        }
duke@0
  3623
        Env<AttrContext> env1 = env;
emc@4248
  3624
        if (sym.kind != ERR && sym.kind != TYP &&
emc@4248
  3625
            sym.owner != null && sym.owner != env1.enclClass.sym) {
duke@0
  3626
            // If the found symbol is inaccessible, then it is
duke@0
  3627
            // accessed through an enclosing instance.  Locate this
duke@0
  3628
            // enclosing instance:
duke@0
  3629
            while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
duke@0
  3630
                env1 = env1.outer;
duke@0
  3631
        }
vromero@3964
  3632
vromero@3964
  3633
        if (env.info.isSerializable) {
vromero@5460
  3634
            chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
vromero@3964
  3635
        }
vromero@3964
  3636
mcimadamore@2190
  3637
        result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
duke@0
  3638
    }
duke@0
  3639
duke@0
  3640
    public void visitSelect(JCFieldAccess tree) {
duke@0
  3641
        // Determine the expected kind of the qualifier expression.
emc@4248
  3642
        KindSelector skind = KindSelector.NIL;
duke@0
  3643
        if (tree.name == names._this || tree.name == names._super ||
emc@4248
  3644
                tree.name == names._class)
duke@0
  3645
        {
emc@4248
  3646
            skind = KindSelector.TYP;
jlahoda@5
  3647
        } else if (tree.name == names.error) {
dbalek@4426
  3648
            skind = KindSelector.ERR;
duke@0
  3649
        } else {
emc@4248
  3650
            if (pkind().contains(KindSelector.PCK))
emc@4248
  3651
                skind = KindSelector.of(skind, KindSelector.PCK);
emc@4248
  3652
            if (pkind().contains(KindSelector.TYP))
emc@4248
  3653
                skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
emc@4248
  3654
            if (pkind().contains(KindSelector.VAL_MTH))
emc@4248
  3655
                skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
duke@0
  3656
        }
duke@0
  3657
duke@0
  3658
        // Attribute the qualifier expression, and determine its symbol (if any).
mcimadamore@4608
  3659
        Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
emc@4248
  3660
        if (!pkind().contains(KindSelector.TYP_PCK))
duke@0
  3661
            site = capture(site); // Capture field access
duke@0
  3662
jfranck@4203
  3663
        // don't allow T.class T[].class, etc
emc@4248
  3664
        if (skind == KindSelector.TYP) {
emc@4028
  3665
            Type elt = site;
jjg@2213
  3666
            while (elt.hasTag(ARRAY))
emc@3988
  3667
                elt = ((ArrayType)elt).elemtype;
jjg@2213
  3668
            if (elt.hasTag(TYPEVAR)) {
duke@0
  3669
                log.error(tree.pos(), "type.var.cant.be.deref");
jlahoda@4220
  3670
                result = tree.type = types.createErrorType(tree.name, site.tsym, site);
jlahoda@4220
  3671
                tree.sym = tree.type.tsym;
jlahoda@4220
  3672
                return ;
duke@0
  3673
            }
duke@0
  3674
        }
duke@0
  3675
duke@0
  3676
        // If qualifier symbol is a type or `super', assert `selectSuper'
duke@0
  3677
        // for the selection. This is relevant for determining whether
duke@0
  3678
        // protected symbols are accessible.
duke@0
  3679
        Symbol sitesym = TreeInfo.symbol(tree.selected);
duke@0
  3680
        boolean selectSuperPrev = env.info.selectSuper;
duke@0
  3681
        env.info.selectSuper =
duke@0
  3682
            sitesym != null &&
duke@0
  3683
            sitesym.name == names._super;
duke@0
  3684
duke@0
  3685
        // Determine the symbol represented by the selection.
mcimadamore@2190
  3686
        env.info.pendingResolutionPhase = null;
mcimadamore@2063
  3687
        Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
vromero@4302
  3688
        if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) {
vromero@4302
  3689
            log.error(tree.selected.pos(), "not.encl.class", site.tsym);
vromero@4302
  3690
            sym = syms.errSymbol;
vromero@4302
  3691
        }
emc@4248
  3692
        if (sym.exists() && !isType(sym) && pkind().contains(KindSelector.TYP_PCK)) {
duke@0
  3693
            site = capture(site);
mcimadamore@2063
  3694
            sym = selectSym(tree, sitesym, site, env, resultInfo);
duke@0
  3695
        }
mcimadamore@2190
  3696
        boolean varArgs = env.info.lastResolveVarargs();
duke@0
  3697
        tree.sym = sym;
duke@0
  3698
jjg@2213
  3699
        if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
mcimadamore@4413
  3700
            site = types.skipTypeVars(site, true);
mcimadamore@206
  3701
        }
duke@0
  3702
duke@0
  3703
        // If that symbol is a variable, ...
duke@0
  3704
        if (sym.kind == VAR) {
duke@0
  3705
            VarSymbol v = (VarSymbol)sym;
duke@0
  3706
duke@0
  3707
            // ..., evaluate its initializer, if it has one, and check for
duke@0
  3708
            // illegal forward reference.
duke@0
  3709
            checkInit(tree, env, v, true);
duke@0
  3710
duke@0
  3711
            // If we are expecting a variable (as opposed to a value), check
duke@0
  3712
            // that the variable is assignable in the current environment.
jlahoda@4301
  3713
            if (KindSelector.ASG.subset(pkind()))
duke@0
  3714
                checkAssignable(tree.pos(), v, tree.selected, env);
duke@0
  3715
        }
duke@0
  3716
darcy@1000
  3717
        if (sitesym != null &&
darcy@1000
  3718
                sitesym.kind == VAR &&
darcy@1000
  3719
                ((VarSymbol)sitesym).isResourceVariable() &&
darcy@1000
  3720
                sym.kind == MTH &&
mcimadamore@1441
  3721
                sym.name.equals(names.close) &&
darcy@1000
  3722
                sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) &&
mcimadamore@1244
  3723
                env.info.lint.isEnabled(LintCategory.TRY)) {
mcimadamore@1244
  3724
            log.warning(LintCategory.TRY, tree, "try.explicit.close.call");
darcy@1000
  3725
        }
darcy@1000
  3726
duke@0
  3727
        // Disallow selecting a type from an expression
emc@4248
  3728
        if (isType(sym) && (sitesym == null || !sitesym.kind.matches(KindSelector.TYP_PCK))) {
mcimadamore@2063
  3729
            tree.type = check(tree.selected, pt(),
emc@4248
  3730
                              sitesym == null ?
emc@4248
  3731
                                      KindSelector.VAL : sitesym.kind.toSelector(),
emc@4248
  3732
                              new ResultInfo(KindSelector.TYP_PCK, pt()));
duke@0
  3733
        }
duke@0
  3734
duke@0
  3735
        if (isType(sitesym)) {
duke@0
  3736
            if (sym.name == names._this) {
duke@0
  3737
                // If `C' is the currently compiled class, check that
duke@0
  3738
                // C.this' does not appear in a call to a super(...)
duke@0
  3739
                if (env.info.isSelfCall &&
duke@0
  3740
                    site.tsym == env.enclClass.sym) {
duke@0
  3741
                    chk.earlyRefError(tree.pos(), sym);
duke@0
  3742
                }
duke@0
  3743
            } else {
duke@0
  3744
                // Check if type-qualified fields or methods are static (JLS)
duke@0
  3745
                if ((sym.flags() & STATIC) == 0 &&
duke@0
  3746
                    sym.name != names._super &&
duke@0
  3747
                    (sym.kind == VAR || sym.kind == MTH)) {
mcimadamore@2190
  3748
                    rs.accessBase(rs.new StaticError(sym),
duke@0
  3749
                              tree.pos(), site, sym.name, true);
duke@0
  3750
                }
duke@0
  3751
            }
dlsmith@4034
  3752
            if (!allowStaticInterfaceMethods && sitesym.isInterface() &&
dlsmith@4034
  3753
                    sym.isStatic() && sym.kind == MTH) {
jlahoda@5330
  3754
                log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), "static.intf.method.invoke.not.supported.in.source", sourceName);
dlsmith@4034
  3755
            }
emc@4248
  3756
        } else if (sym.kind != ERR &&
emc@4248
  3757
                   (sym.flags() & STATIC) != 0 &&
emc@4248
  3758
                   sym.name != names._class) {
jjg@898
  3759
            // If the qualified item is not a type and the selected item is static, report
jjg@898
  3760
            // a warning. Make allowance for the class of an array type e.g. Object[].class)
emc@4248
  3761
            chk.warnStatic(tree, "static.not.qualified.by.type",
emc@4248
  3762
                           sym.kind.kindName(), sym.owner);
duke@0
  3763
        }
duke@0
  3764
duke@0
  3765
        // If we are selecting an instance member via a `super', ...
duke@0
  3766
        if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
duke@0
  3767
duke@0
  3768
            // Check that super-qualified symbols are not abstract (JLS)
duke@0
  3769
            rs.checkNonAbstract(tree.pos(), sym);
duke@0
  3770
duke@0
  3771
            if (site.isRaw()) {
duke@0
  3772
                // Determine argument types for site.
duke@0
  3773
                Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym);
duke@0
  3774
                if (site1 != null) site = site1;
duke@0
  3775
            }
duke@0
  3776
        }
duke@0
  3777
vromero@3964
  3778
        if (env.info.isSerializable) {
vromero@5460
  3779
            chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
vromero@3964
  3780
        }
vromero@3964
  3781
duke@0
  3782
        env.info.selectSuper = selectSuperPrev;
mcimadamore@2190
  3783
        result = checkId(tree, site, sym, env, resultInfo);
duke@0
  3784
    }
duke@0
  3785
    //where
duke@0
  3786
        /** Determine symbol referenced by a Select expression,
duke@0
  3787
         *
duke@0
  3788
         *  @param tree   The select tree.
duke@0
  3789
         *  @param site   The type of the selected expression,
duke@0
  3790
         *  @param env    The current environment.
mcimadamore@2063
  3791
         *  @param resultInfo The current result.
duke@0
  3792
         */
duke@0
  3793
        private Symbol selectSym(JCFieldAccess tree,
mcimadamore@1298
  3794
                                 Symbol location,
duke@0
  3795
                                 Type site,
duke@0
  3796
                                 Env<AttrContext> env,
mcimadamore@2063
  3797
                                 ResultInfo resultInfo) {
duke@0
  3798
            DiagnosticPosition pos = tree.pos();
duke@0
  3799
            Name name = tree.name;
jjg@2213
  3800
            switch (site.getTag()) {
duke@0
  3801
            case PACKAGE:
mcimadamore@2190
  3802
                return rs.accessBase(
mcimadamore@2063
  3803
                    rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
mcimadamore@1298
  3804
                    pos, location, site, name, true);
duke@0
  3805
            case ARRAY:
duke@0
  3806
            case CLASS:
jjg@2213
  3807
                if (resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL)) {
duke@0
  3808
                    return rs.resolveQualifiedMethod(
mcimadamore@2063
  3809
                        pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments());
duke@0
  3810
                } else if (name == names._this || name == names._super) {
duke@0
  3811
                    return rs.resolveSelf(pos, env, site.tsym, name);
duke@0
  3812
                } else if (name == names._class) {
duke@0
  3813
                    // In this case, we have already made sure in
duke@0
  3814
                    // visitSelect that qualifier expression is a type.
duke@0
  3815
                    Type t = syms.classType;
ntoda@4105
  3816
                    List<Type> typeargs = List.of(types.erasure(site));
duke@0
  3817
                    t = new ClassType(t.getEnclosingType(), typeargs, t.tsym);
duke@0
  3818
                    return new VarSymbol(
duke@0
  3819
                        STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
duke@0
  3820
                } else {
duke@0
  3821
                    // We are seeing a plain identifier as selector.
mcimadamore@2063
  3822
                    Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind);
mcimadamore@2190
  3823
                        sym = rs.accessBase(sym, pos, location, site, name, true);
duke@0
  3824
                    return sym;
duke@0
  3825
                }
duke@0
  3826
            case WILDCARD:
duke@0
  3827
                throw new AssertionError(tree);
duke@0
  3828
            case TYPEVAR:
duke@0
  3829
                // Normally, site.getUpperBound() shouldn't be null.
duke@0
  3830
                // It should only happen during memberEnter/attribBase
mcimadamore@1298
  3831
                // when determining the super type which *must* beac
duke@0
  3832
                // done before attributing the type variables.  In
duke@0
  3833
                // other words, we are seeing this illegal program:
duke@0
  3834
                // class B<T> extends A<T.foo> {}
duke@0
  3835
                Symbol sym = (site.getUpperBound() != null)
mcimadamore@2063
  3836
                    ? selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo)
duke@0
  3837
                    : null;
mcimadamore@651
  3838
                if (sym == null) {
duke@0
  3839
                    log.error(pos, "type.var.cant.be.deref");
duke@0
  3840
                    return syms.errSymbol;
duke@0
  3841
                } else {
mcimadamore@334
  3842
                    Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ?
mcimadamore@334
  3843
                        rs.new AccessError(env, site, sym) :
mcimadamore@334
  3844
                                sym;
mcimadamore@2190
  3845
                    rs.accessBase(sym2, pos, location, site, name, true);
duke@0
  3846
                    return sym;
duke@0
  3847
                }
duke@0
  3848
            case ERROR:
duke@0
  3849
                // preserve identifier names through errors
jjg@289
  3850
                return types.createErrorType(name, site.tsym, site).tsym;
duke@0
  3851
            default:
duke@0
  3852
                // The qualifier expression is of a primitive type -- only
duke@0
  3853
                // .class is allowed for these.
duke@0
  3854
                if (name == names._class) {
duke@0
  3855
                    // In this case, we have already made sure in Select that
duke@0
  3856
                    // qualifier expression is a type.
duke@0
  3857
                    Type t = syms.classType;
duke@0
  3858
                    Type arg = types.boxedClass(site).type;
duke@0
  3859
                    t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym);
duke@0
  3860
                    return new VarSymbol(
duke@0
  3861
                        STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
duke@0
  3862
                } else {
duke@0
  3863
                    log.error(pos, "cant.deref", site);
duke@0
  3864
                    return syms.errSymbol;
duke@0
  3865
                }
duke@0
  3866
            }
duke@0
  3867
        }
duke@0
  3868
duke@0
  3869
        /** Determine type of identifier or select expression and check that
duke@0
  3870
         *  (1) the referenced symbol is not deprecated
duke@0
  3871
         *  (2) the symbol's type is safe (@see checkSafe)
duke@0
  3872
         *  (3) if symbol is a variable, check that its type and kind are
duke@0
  3873
         *      compatible with the prototype and protokind.
duke@0
  3874
         *  (4) if symbol is an instance field of a raw type,
duke@0
  3875
         *      which is being assigned to, issue an unchecked warning if its
duke@0
  3876
         *      type changes under erasure.
duke@0
  3877
         *  (5) if symbol is an instance method of a raw type, issue an
duke@0
  3878
         *      unchecked warning if its argument types change under erasure.
duke@0
  3879
         *  If checks succeed:
duke@0
  3880
         *    If symbol is a constant, return its constant type
duke@0
  3881
         *    else if symbol is a method, return its result type
duke@0
  3882
         *    otherwise return its type.
duke@0
  3883
         *  Otherwise return errType.
duke@0
  3884
         *
duke@0
  3885
         *  @param tree       The syntax tree representing the identifier
duke@0
  3886
         *  @param site       If this is a select, the type of the selected
duke@0
  3887
         *                    expression, otherwise the type of the current class.
duke@0
  3888
         *  @param sym        The symbol representing the identifier.
duke@0
  3889
         *  @param env        The current environment.
mcimadamore@2063
  3890
         *  @param resultInfo    The expected result
duke@0
  3891
         */
duke@0
  3892
        Type checkId(JCTree tree,
duke@0
  3893
                     Type site,
duke@0
  3894
                     Symbol sym,
duke@0
  3895
                     Env<AttrContext> env,
mcimadamore@2190
  3896
                     ResultInfo resultInfo) {
mcimadamore@2260
  3897
            return (resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD)) ?
mcimadamore@2260
  3898
                    checkMethodId(tree, site, sym, env, resultInfo) :
mcimadamore@2260
  3899
                    checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
mcimadamore@2260
  3900
        }
mcimadamore@2260
  3901
mcimadamore@2260
  3902
        Type checkMethodId(JCTree tree,
mcimadamore@2260
  3903
                     Type site,
mcimadamore@2260
  3904
                     Symbol sym,
mcimadamore@2260
  3905
                     Env<AttrContext> env,
mcimadamore@2260
  3906
                     ResultInfo resultInfo) {
mcimadamore@2260
  3907
            boolean isPolymorhicSignature =
vromero@2804
  3908
                (sym.baseSymbol().flags() & SIGNATURE_POLYMORPHIC) != 0;
mcimadamore@2260
  3909
            return isPolymorhicSignature ?
mcimadamore@2260
  3910
                    checkSigPolyMethodId(tree, site, sym, env, resultInfo) :
mcimadamore@2260
  3911
                    checkMethodIdInternal(tree, site, sym, env, resultInfo);
mcimadamore@2260
  3912
        }
mcimadamore@2260
  3913
mcimadamore@2260
  3914
        Type checkSigPolyMethodId(JCTree tree,
mcimadamore@2260
  3915
                     Type site,
mcimadamore@2260
  3916
                     Symbol sym,
mcimadamore@2260
  3917
                     Env<AttrContext> env,
mcimadamore@2260
  3918
                     ResultInfo resultInfo) {
mcimadamore@2260
  3919
            //recover original symbol for signature polymorphic methods
mcimadamore@2260
  3920
            checkMethodIdInternal(tree, site, sym.baseSymbol(), env, resultInfo);
mcimadamore@2260
  3921
            env.info.pendingResolutionPhase = Resolve.MethodResolutionPhase.BASIC;
mcimadamore@2260
  3922
            return sym.type;
mcimadamore@2260
  3923
        }
mcimadamore@2260
  3924
mcimadamore@2260
  3925
        Type checkMethodIdInternal(JCTree tree,
mcimadamore@2260
  3926
                     Type site,
mcimadamore@2260
  3927
                     Symbol sym,
mcimadamore@2260
  3928
                     Env<AttrContext> env,
mcimadamore@2260
  3929
                     ResultInfo resultInfo) {
emc@4248
  3930
            if (resultInfo.pkind.contains(KindSelector.POLY)) {
vromero@2834
  3931
                Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase));
vromero@2834
  3932
                Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo);
vromero@2834
  3933
                resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
vromero@2834
  3934
                return owntype;
vromero@2834
  3935
            } else {
vromero@2834
  3936
                return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
vromero@2834
  3937
            }
mcimadamore@2260
  3938
        }
mcimadamore@2260
  3939
mcimadamore@2260
  3940
        Type checkIdInternal(JCTree tree,
mcimadamore@2260
  3941
                     Type site,
mcimadamore@2260
  3942
                     Symbol sym,
mcimadamore@2260
  3943
                     Type pt,
mcimadamore@2260
  3944
                     Env<AttrContext> env,
mcimadamore@2260
  3945
                     ResultInfo resultInfo) {
mcimadamore@2190
  3946
            if (pt.isErroneous()) {
dbalek@2330
  3947
                return tree.type = types.createErrorType(site);
mcimadamore@2190
  3948
            }
duke@0
  3949
            Type owntype; // The computed type of this identifier occurrence.
duke@0
  3950
            switch (sym.kind) {
duke@0
  3951
            case TYP:
duke@0
  3952
                // For types, the computed type equals the symbol's type,
duke@0
  3953
                // except for two situations:
duke@0
  3954
                owntype = sym.type;
jjg@2213
  3955
                if (owntype.hasTag(CLASS)) {
ohrstrom@2227
  3956
                    chk.checkForBadAuxiliaryClassAccess(tree.pos(), env, (ClassSymbol)sym);
duke@0
  3957
                    Type ownOuter = owntype.getEnclosingType();
duke@0
  3958
duke@0
  3959
                    // (a) If the symbol's type is parameterized, erase it
duke@0
  3960
                    // because no type parameters were given.
duke@0
  3961
                    // We recover generic outer type later in visitTypeApply.
duke@0
  3962
                    if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
duke@0
  3963
                        owntype = types.erasure(owntype);
duke@0
  3964
                    }
duke@0
  3965
duke@0
  3966
                    // (b) If the symbol's type is an inner class, then
duke@0
  3967
                    // we have to interpret its outer type as a superclass
duke@0
  3968
                    // of the site type. Example:
duke@0
  3969
                    //
duke@0
  3970
                    // class Tree<A> { class Visitor { ... } }
duke@0
  3971
                    // class PointTree extends Tree<Point> { ... }
duke@0
  3972
                    // ...PointTree.Visitor...
duke@0
  3973
                    //
duke@0
  3974
                    // Then the type of the last expression above is
duke@0
  3975
                    // Tree<Point>.Visitor.
dbalek@2330
  3976
                    else if (ownOuter != null && ownOuter.hasTag(CLASS) && site != ownOuter) {
duke@0
  3977
                        Type normOuter = site;
jjg@2372
  3978
                        if (normOuter.hasTag(CLASS)) {
duke@0
  3979
                            normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
jjg@2372
  3980
                        }
duke@0
  3981
                        if (normOuter == null) // perhaps from an import
duke@0
  3982
                            normOuter = types.erasure(ownOuter);
duke@0
  3983
                        if (normOuter != ownOuter)
duke@0
  3984
                            owntype = new ClassType(
mcimadamore@5586
  3985
                                normOuter, List.nil(), owntype.tsym,
emc@4221
  3986
                                owntype.getMetadata());
duke@0
  3987
                    }
duke@0
  3988
                }
duke@0
  3989
                break;
duke@0
  3990
            case VAR:
duke@0
  3991
                VarSymbol v = (VarSymbol)sym;
duke@0
  3992
                // Test (4): if symbol is an instance field of a raw type,
duke@0
  3993
                // which is being assigned to, issue an unchecked warning if
duke@0
  3994
                // its type changes under erasure.
jlahoda@4301
  3995
                if (KindSelector.ASG.subset(pkind()) &&
duke@0
  3996
                    v.owner.kind == TYP &&
duke@0
  3997
                    (v.flags() & STATIC) == 0 &&
jjg@2213
  3998
                    (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
duke@0
  3999
                    Type s = types.asOuterSuper(site, v.owner);
duke@0
  4000
                    if (s != null &&
duke@0
  4001
                        s.isRaw() &&
duke@0
  4002
                        !types.isSameType(v.type, v.erasure(types))) {
duke@0
  4003
                        chk.warnUnchecked(tree.pos(),
duke@0
  4004
                                          "unchecked.assign.to.var",
duke@0
  4005
                                          v, s);
duke@0
  4006
                    }
duke@0
  4007
                }
duke@0
  4008
                // The computed type of a variable is the type of the
duke@0
  4009
                // variable symbol, taken as a member of the site type.
duke@0
  4010
                owntype = (sym.owner.kind == TYP &&
duke@0
  4011
                           sym.name != names._this && sym.name != names._super)
duke@0
  4012
                    ? types.memberType(site, sym)
duke@0
  4013
                    : sym.type;
duke@0
  4014
duke@0
  4015
                // If the variable is a constant, record constant value in
duke@0
  4016
                // computed type.
duke@0
  4017
                if (v.getConstValue() != null && isStaticReference(tree))
duke@0
  4018
                    owntype = owntype.constType(v.getConstValue());
duke@0
  4019
emc@4248
  4020
                if (resultInfo.pkind == KindSelector.VAL) {
duke@0
  4021
                    owntype = capture(owntype); // capture "names as expressions"
duke@0
  4022
                }
duke@0
  4023
                break;
duke@0
  4024
            case MTH: {
mcimadamore@2112
  4025
                owntype = checkMethod(site, sym,
mcimadamore@5853
  4026
                        new ResultInfo(resultInfo.pkind, resultInfo.pt.getReturnType(), resultInfo.checkContext, resultInfo.checkMode),
mcimadamore@2180
  4027
                        env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(),
mcimadamore@2190
  4028
                        resultInfo.pt.getTypeArguments());
duke@0
  4029
                break;
duke@0
  4030
            }
duke@0
  4031
            case PCK: case ERR:
duke@0
  4032
                owntype = sym.type;
duke@0
  4033
                break;
duke@0
  4034
            default:
duke@0
  4035
                throw new AssertionError("unexpected kind: " + sym.kind +
duke@0
  4036
                                         " in tree " + tree);
duke@0
  4037
            }
duke@0
  4038
sadayapalam@4625
  4039
            // Emit a `deprecation' warning if symbol is deprecated.
sadayapalam@4625
  4040
            // (for constructors (but not for constructor references), the error
sadayapalam@4625
  4041
            // was given when the constructor was resolved)
sadayapalam@4625
  4042
sadayapalam@4625
  4043
            if (sym.name != names.init || tree.hasTag(REFERENCE)) {
mcimadamore@1317
  4044
                chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
mcimadamore@1317
  4045
                chk.checkSunAPI(tree.pos(), sym);
jjg@2470
  4046
                chk.checkProfile(tree.pos(), sym);
jjg@667
  4047
            }
jlahoda@1761
  4048
            
dbalek@2330
  4049
            Env<AttrContext> enclosing;            
dbalek@4654
  4050
            if (owntype.isErroneous() && (sym.kind == MTH || sym.kind == VAR) && ((enclosing = enter.getEnv(sym.enclClass())) == null || enclosing.toplevel != env.toplevel)) {
jlahoda@1761
  4051
                log.error(tree, "type.error", sym);
jlahoda@1761
  4052
            }
duke@0
  4053
sadayapalam@4625
  4054
            // If symbol is a variable, check that its type and
duke@0
  4055
            // kind are compatible with the prototype and protokind.
emc@4248
  4056
            return check(tree, owntype, sym.kind.toSelector(), resultInfo);
duke@0
  4057
        }
duke@0
  4058
duke@0
  4059
        /** Check that variable is initialized and evaluate the variable's
duke@0
  4060
         *  initializer, if not yet done. Also check that variable is not
duke@0
  4061
         *  referenced before it is defined.
duke@0
  4062
         *  @param tree    The tree making up the variable reference.
duke@0
  4063
         *  @param env     The current environment.
duke@0
  4064
         *  @param v       The variable's symbol.
duke@0
  4065
         */
duke@0
  4066
        private void checkInit(JCTree tree,
duke@0
  4067
                               Env<AttrContext> env,
duke@0
  4068
                               VarSymbol v,
duke@0
  4069
                               boolean onlyWarning) {
duke@0
  4070
            // A forward reference is diagnosed if the declaration position
duke@0
  4071
            // of the variable is greater than the current tree position
duke@0
  4072
            // and the tree and variable definition occur in the same class
duke@0
  4073
            // definition.  Note that writes don't count as references.
duke@0
  4074
            // This check applies only to class and instance
duke@0
  4075
            // variables.  Local variables follow different scope rules,
duke@0
  4076
            // and are subject to definite assignment checking.
vromero@4584
  4077
            Env<AttrContext> initEnv = enclosingInitEnv(env);
vromero@4584
  4078
            if (initEnv != null &&
vromero@4584
  4079
                (initEnv.info.enclVar == v || v.pos > tree.pos) &&
duke@0
  4080
                v.owner.kind == TYP &&
duke@0
  4081
                v.owner == env.info.scope.owner.enclClass() &&
duke@0
  4082
                ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
jjg@1972
  4083
                (!env.tree.hasTag(ASSIGN) ||
duke@0
  4084
                 TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
vromero@4584
  4085
                String suffix = (initEnv.info.enclVar == v) ?
mcimadamore@272
  4086
                                "self.ref" : "forward.ref";
mcimadamore@199
  4087
                if (!onlyWarning || isStaticEnumField(v)) {
mcimadamore@272
  4088
                    log.error(tree.pos(), "illegal." + suffix);
duke@0
  4089
                } else if (useBeforeDeclarationWarning) {
mcimadamore@272
  4090
                    log.warning(tree.pos(), suffix, v);
duke@0
  4091
                }
duke@0
  4092
            }
duke@0
  4093
duke@0
  4094
            v.getConstValue(); // ensure initializer is evaluated
duke@0
  4095
duke@0
  4096
            checkEnumInitializer(tree, env, v);
duke@0
  4097
        }
duke@0
  4098
duke@0
  4099
        /**
mcimadamore@4141
  4100
         * Returns the enclosing init environment associated with this env (if any). An init env
mcimadamore@4141
  4101
         * can be either a field declaration env or a static/instance initializer env.
mcimadamore@4141
  4102
         */
mcimadamore@4141
  4103
        Env<AttrContext> enclosingInitEnv(Env<AttrContext> env) {
mcimadamore@4141
  4104
            while (true) {
mcimadamore@4141
  4105
                switch (env.tree.getTag()) {
mcimadamore@4141
  4106
                    case VARDEF:
mcimadamore@4141
  4107
                        JCVariableDecl vdecl = (JCVariableDecl)env.tree;
dbalek@5960
  4108
                        if (vdecl.sym != null && vdecl.sym.owner != null && vdecl.sym.owner.kind == TYP) {
mcimadamore@4141
  4109
                            //field
mcimadamore@4141
  4110
                            return env;
mcimadamore@4141
  4111
                        }
mcimadamore@4141
  4112
                        break;
mcimadamore@4141
  4113
                    case BLOCK:
mcimadamore@4141
  4114
                        if (env.next.tree.hasTag(CLASSDEF)) {
mcimadamore@4141
  4115
                            //instance/static initializer
mcimadamore@4141
  4116
                            return env;
mcimadamore@4141
  4117
                        }
mcimadamore@4141
  4118
                        break;
mcimadamore@4141
  4119
                    case METHODDEF:
mcimadamore@4141
  4120
                    case CLASSDEF:
mcimadamore@4141
  4121
                    case TOPLEVEL:
mcimadamore@4141
  4122
                        return null;
mcimadamore@4141
  4123
                }
mcimadamore@4141
  4124
                Assert.checkNonNull(env.next);
mcimadamore@4141
  4125
                env = env.next;
mcimadamore@4141
  4126
            }
mcimadamore@4141
  4127
        }
mcimadamore@4141
  4128
mcimadamore@4141
  4129
        /**
duke@0
  4130
         * Check for illegal references to static members of enum.  In
duke@0
  4131
         * an enum type, constructors and initializers may not
duke@0
  4132
         * reference its static members unless they are constant.
duke@0
  4133
         *
duke@0
  4134
         * @param tree    The tree making up the variable reference.
duke@0
  4135
         * @param env     The current environment.
duke@0
  4136
         * @param v       The variable's symbol.
jjh@1465
  4137
         * @jls  section 8.9 Enums
duke@0
  4138
         */
duke@0
  4139
        private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) {
jjh@1465
  4140
            // JLS:
duke@0
  4141
            //
duke@0
  4142
            // "It is a compile-time error to reference a static field
duke@0
  4143
            // of an enum type that is not a compile-time constant
duke@0
  4144
            // (15.28) from constructors, instance initializer blocks,
duke@0
  4145
            // or instance variable initializer expressions of that
duke@0
  4146
            // type. It is a compile-time error for the constructors,
duke@0
  4147
            // instance initializer blocks, or instance variable
duke@0
  4148
            // initializer expressions of an enum constant e to refer
duke@0
  4149
            // to itself or to an enum constant of the same type that
duke@0
  4150
            // is declared to the right of e."
mcimadamore@199
  4151
            if (isStaticEnumField(v)) {
duke@0
  4152
                ClassSymbol enclClass = env.info.scope.owner.enclClass();
duke@0
  4153
duke@0
  4154
                if (enclClass == null || enclClass.owner == null)
duke@0
  4155
                    return;
duke@0
  4156
duke@0
  4157
                // See if the enclosing class is the enum (or a
duke@0
  4158
                // subclass thereof) declaring v.  If not, this
duke@0
  4159
                // reference is OK.
duke@0
  4160
                if (v.owner != enclClass && !types.isSubtype(enclClass.type, v.owner.type))
duke@0
  4161
                    return;
duke@0
  4162
duke@0
  4163
                // If the reference isn't from an initializer, then
duke@0
  4164
                // the reference is OK.
duke@0
  4165
                if (!Resolve.isInitializer(env))
duke@0
  4166
                    return;
duke@0
  4167
duke@0
  4168
                log.error(tree.pos(), "illegal.enum.static.ref");
duke@0
  4169
            }
duke@0
  4170
        }
duke@0
  4171
mcimadamore@199
  4172
        /** Is the given symbol a static, non-constant field of an Enum?
mcimadamore@199
  4173
         *  Note: enum literals should not be regarded as such
mcimadamore@199
  4174
         */
mcimadamore@199
  4175
        private boolean isStaticEnumField(VarSymbol v) {
mcimadamore@199
  4176
            return Flags.isEnum(v.owner) &&
mcimadamore@199
  4177
                   Flags.isStatic(v) &&
mcimadamore@199
  4178
                   !Flags.isConstant(v) &&
mcimadamore@199
  4179
                   v.name != names._class;
duke@0
  4180
        }
duke@0
  4181
duke@0
  4182
    /**
mcimadamore@2062
  4183
     * Check that method arguments conform to its instantiation.
duke@0
  4184
     **/
duke@0
  4185
    public Type checkMethod(Type site,
vromero@3016
  4186
                            final Symbol sym,
mcimadamore@2112
  4187
                            ResultInfo resultInfo,
mcimadamore@2112
  4188
                            Env<AttrContext> env,
mcimadamore@2112
  4189
                            final List<JCExpression> argtrees,
mcimadamore@2112
  4190
                            List<Type> argtypes,
mcimadamore@2190
  4191
                            List<Type> typeargtypes) {
duke@0
  4192
        // Test (5): if symbol is an instance method of a raw type, issue
duke@0
  4193
        // an unchecked warning if its argument types change under erasure.
ntoda@4105
  4194
        if ((sym.flags() & STATIC) == 0 &&
jjg@2213
  4195
            (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
duke@0
  4196
            Type s = types.asOuterSuper(site, sym.owner);
duke@0
  4197
            if (s != null && s.isRaw() &&
duke@0
  4198
                !types.isSameTypes(sym.type.getParameterTypes(),
duke@0
  4199
                                   sym.erasure(types).getParameterTypes())) {
duke@0
  4200
                chk.warnUnchecked(env.tree.pos(),
duke@0
  4201
                                  "unchecked.call.mbr.of.raw.type",
duke@0
  4202
                                  sym, s);
duke@0
  4203
            }
duke@0
  4204
        }
duke@0
  4205
mcimadamore@2260
  4206
        if (env.info.defaultSuperCallSite != null) {
dbalek@3543
  4207
            for (Type sup : types.interfaces(env.enclClass.sym.type).prepend(types.supertype((env.enclClass.sym.type)))) {
mcimadamore@2260
  4208
                if (!sup.tsym.isSubClass(sym.enclClass(), types) ||
mcimadamore@2260
  4209
                        types.isSameType(sup, env.info.defaultSuperCallSite)) continue;
mcimadamore@2260
  4210
                List<MethodSymbol> icand_sup =
mcimadamore@2260
  4211
                        types.interfaceCandidates(sup, (MethodSymbol)sym);
mcimadamore@2260
  4212
                if (icand_sup.nonEmpty() &&
mcimadamore@2260
  4213
                        icand_sup.head != sym &&
mcimadamore@2260
  4214
                        icand_sup.head.overrides(sym, icand_sup.head.enclClass(), types, true)) {
mcimadamore@2260
  4215
                    log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite,
mcimadamore@2260
  4216
                        diags.fragment("overridden.default", sym, sup));
mcimadamore@2260
  4217
                    break;
mcimadamore@2234
  4218
                }
mcimadamore@2234
  4219
            }
mcimadamore@2260
  4220
            env.info.defaultSuperCallSite = null;
mcimadamore@2234
  4221
        }
mcimadamore@2234
  4222
mcimadamore@2526
  4223
        if (sym.isStatic() && site.isInterface() && env.tree.hasTag(APPLY)) {
mcimadamore@2364
  4224
            JCMethodInvocation app = (JCMethodInvocation)env.tree;
mcimadamore@2364
  4225
            if (app.meth.hasTag(SELECT) &&
mcimadamore@2364
  4226
                    !TreeInfo.isStaticSelector(((JCFieldAccess)app.meth).selected, names)) {
mcimadamore@2364
  4227
                log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
mcimadamore@2364
  4228
            }
mcimadamore@2364
  4229
        }
mcimadamore@2364
  4230
duke@0
  4231
        // Compute the identifier's instantiated type.
duke@0
  4232
        // For methods, we need to compute the instance type by
duke@0
  4233
        // Resolve.instantiate from the symbol's type as well as
duke@0
  4234
        // any type arguments and value arguments.
mcimadamore@4934
  4235
        Warner noteWarner = new Warner();
mcimadamore@2140
  4236
        try {
mcimadamore@2190
  4237
            Type owntype = rs.checkMethod(
mcimadamore@2140
  4238
                    env,
mcimadamore@2140
  4239
                    site,
mcimadamore@2140
  4240
                    sym,
mcimadamore@2140
  4241
                    resultInfo,
mcimadamore@2140
  4242
                    argtypes,
mcimadamore@2140
  4243
                    typeargtypes,
mcimadamore@2140
  4244
                    noteWarner);
mcimadamore@2140
  4245
mcimadamore@2796
  4246
            DeferredAttr.DeferredTypeMap checkDeferredMap =
mcimadamore@2796
  4247
                deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
mcimadamore@2796
  4248
mcimadamore@4432
  4249
            argtypes = argtypes.map(checkDeferredMap);
mcimadamore@2796
  4250
mcimadamore@2796
  4251
            if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
mcimadamore@2796
  4252
                chk.warnUnchecked(env.tree.pos(),
mcimadamore@2796
  4253
                        "unchecked.meth.invocation.applied",
mcimadamore@2796
  4254
                        kindName(sym),
mcimadamore@2796
  4255
                        sym.name,
mcimadamore@2796
  4256
                        rs.methodArguments(sym.type.getParameterTypes()),
mcimadamore@4432
  4257
                        rs.methodArguments(argtypes.map(checkDeferredMap)),
mcimadamore@2796
  4258
                        kindName(sym.location()),
mcimadamore@2796
  4259
                        sym.location());
mcimadamore@5740
  4260
                if (resultInfo.pt != Infer.anyPoly ||
mcimadamore@5740
  4261
                        !owntype.hasTag(METHOD) ||
mcimadamore@5740
  4262
                        !owntype.isPartial()) {
mcimadamore@5740
  4263
                    //if this is not a partially inferred method type, erase return type. Otherwise,
mcimadamore@5740
  4264
                    //erasure is carried out in PartiallyInferredMethodType.check().
mcimadamore@5740
  4265
                    owntype = new MethodType(owntype.getParameterTypes(),
mcimadamore@5740
  4266
                            types.erasure(owntype.getReturnType()),
mcimadamore@5740
  4267
                            types.erasure(owntype.getThrownTypes()),
mcimadamore@5740
  4268
                            syms.methodClass);
mcimadamore@5740
  4269
                }
mcimadamore@2796
  4270
            }
mcimadamore@2796
  4271
mcimadamore@4608
  4272
            PolyKind pkind = (sym.type.hasTag(FORALL) &&
mcimadamore@4608
  4273
                 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
mcimadamore@4608
  4274
                 PolyKind.POLY : PolyKind.STANDALONE;
mcimadamore@4608
  4275
            TreeInfo.setPolyKind(env.tree, pkind);
mcimadamore@4608
  4276
mcimadamore@4608
  4277
            return (resultInfo.pt == Infer.anyPoly) ?
mcimadamore@4608
  4278
                    owntype :
mcimadamore@4608
  4279
                    chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(),
mcimadamore@4608
  4280
                            resultInfo.checkContext.inferenceContext());
mcimadamore@2140
  4281
        } catch (Infer.InferenceException ex) {
mcimadamore@2140
  4282
            //invalid target type - propagate exception outwards or report error
mcimadamore@2140
  4283
            //depending on the current check context
mcimadamore@2140
  4284
            resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
dbalek@2395
  4285
            return types.createErrorType(sym.type);
mcimadamore@2140
  4286
        } catch (Resolve.InapplicableMethodException ex) {
vromero@3016
  4287
            final JCDiagnostic diag = ex.getDiagnostic();
vromero@3016
  4288
            Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) {
vromero@3016
  4289
                @Override
vromero@3016
  4290
                protected Pair<Symbol, JCDiagnostic> errCandidate() {
briangoetz@3808
  4291
                    return new Pair<>(sym, diag);
vromero@3016
  4292
                }
vromero@3016
  4293
            };
mcimadamore@4432
  4294
            List<Type> argtypes2 = argtypes.map(
vromero@3016
  4295
                    rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
vromero@3016
  4296
            JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
vromero@3016
  4297
                    env.tree, sym, site, sym.name, argtypes2, typeargtypes);
vromero@3016
  4298
            log.report(errDiag);
vromero@3016
  4299
            return types.createErrorType(site);
mcimadamore@2140
  4300
        }
mcimadamore@2062
  4301
    }
mcimadamore@2062
  4302
duke@0
  4303
    public void visitLiteral(JCLiteral tree) {
emc@4248
  4304
        result = check(tree, litType(tree.typetag).constType(tree.value),
emc@4248
  4305
                KindSelector.VAL, resultInfo);
duke@0
  4306
    }
duke@0
  4307
    //where
duke@0
  4308
    /** Return the type of a literal with given type tag.
duke@0
  4309
     */
jjg@2213
  4310
    Type litType(TypeTag tag) {
jjg@2213
  4311
        return (tag == CLASS) ? syms.stringType : syms.typeOfTag[tag.ordinal()];
duke@0
  4312
    }
duke@0
  4313
duke@0
  4314
    public void visitTypeIdent(JCPrimitiveTypeTree tree) {
emc@4248
  4315
        result = check(tree, syms.typeOfTag[tree.typetag.ordinal()], KindSelector.TYP, resultInfo);
duke@0
  4316
    }
duke@0
  4317
duke@0
  4318
    public void visitTypeArray(JCArrayTypeTree tree) {
duke@0
  4319
        Type etype = attribType(tree.elemtype, env);
emc@4221
  4320
        Type type = new ArrayType(etype, syms.arrayClass);
emc@4248
  4321
        result = check(tree, type, KindSelector.TYP, resultInfo);
duke@0
  4322
    }
duke@0
  4323
duke@0
  4324
    /** Visitor method for parameterized types.
duke@0
  4325
     *  Bound checking is left until later, since types are attributed
duke@0
  4326
     *  before supertype structure is completely known
duke@0
  4327
     */
duke@0
  4328
    public void visitTypeApply(JCTypeApply tree) {
jjg@289
  4329
        Type owntype = types.createErrorType(tree.type);
duke@0
  4330
duke@0
  4331
        // Attribute functor part of application and make sure it's a class.
duke@0
  4332
        Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env));
duke@0
  4333
duke@0
  4334
        // Attribute type parameters
duke@0
  4335
        List<Type> actuals = attribTypes(tree.arguments, env);
duke@0
  4336
jjg@2213
  4337
        if (clazztype.hasTag(CLASS)) {
duke@0
  4338
            List<Type> formals = clazztype.tsym.type.getTypeArguments();
mcimadamore@1580
  4339
            if (actuals.isEmpty()) //diamond
mcimadamore@1580
  4340
                actuals = formals;
mcimadamore@1580
  4341
mcimadamore@1580
  4342
            if (actuals.length() == formals.length()) {
duke@0
  4343
                List<Type> a = actuals;
duke@0
  4344
                List<Type> f = formals;
duke@0
  4345
                while (a.nonEmpty()) {
duke@0
  4346
                    a.head = a.head.withTypeVar(f.head);
duke@0
  4347
                    a = a.tail;
duke@0
  4348
                    f = f.tail;
duke@0
  4349
                }
duke@0
  4350
                // Compute the proper generic outer
duke@0
  4351
                Type clazzOuter = clazztype.getEnclosingType();
jjg@2213
  4352
                if (clazzOuter.hasTag(CLASS)) {
duke@0
  4353
                    Type site;
jjg@598
  4354
                    JCExpression clazz = TreeInfo.typeIn(tree.clazz);
jjg@1972
  4355
                    if (clazz.hasTag(IDENT)) {
duke@0
  4356
                        site = env.enclClass.sym.type;
jjg@1972
  4357
                    } else if (clazz.hasTag(SELECT)) {
jjg@598
  4358
                        site = ((JCFieldAccess) clazz).selected.type;
duke@0
  4359
                    } else throw new AssertionError(""+tree);
jjg@2213
  4360
                    if (clazzOuter.hasTag(CLASS) && site != clazzOuter) {
jjg@2213
  4361
                        if (site.hasTag(CLASS))
duke@0
  4362
                            site = types.asOuterSuper(site, clazzOuter.tsym);
duke@0
  4363
                        if (site == null)
duke@0
  4364
                            site = types.erasure(clazzOuter);
duke@0
  4365
                        clazzOuter = site;
duke@0
  4366
                    }
duke@0
  4367
                }
emc@3988
  4368
                owntype = new ClassType(clazzOuter, actuals, clazztype.tsym,
emc@4221
  4369
                                        clazztype.getMetadata());
duke@0
  4370
            } else {
duke@0
  4371
                if (formals.length() != 0) {
duke@0
  4372
                    log.error(tree.pos(), "wrong.number.type.args",
duke@0
  4373
                              Integer.toString(formals.length()));
duke@0
  4374
                } else {
duke@0
  4375
                    log.error(tree.pos(), "type.doesnt.take.params", clazztype.tsym);
duke@0
  4376
                }
jjg@289
  4377
                owntype = types.createErrorType(tree.type);
duke@0
  4378
            }
duke@0
  4379
        }
emc@4248
  4380
        result = check(tree, owntype, KindSelector.TYP, resultInfo);
duke@0
  4381
    }
duke@0
  4382
darcy@1452
  4383
    public void visitTypeUnion(JCTypeUnion tree) {
alundblad@3063
  4384
        ListBuffer<Type> multicatchTypes = new ListBuffer<>();
jjg@1482
  4385
        ListBuffer<Type> all_multicatchTypes = null; // lazy, only if needed
mcimadamore@1215
  4386
        for (JCExpression typeTree : tree.alternatives) {
mcimadamore@1215
  4387
            Type ctype = attribType(typeTree, env);
mcimadamore@1215
  4388
            ctype = chk.checkType(typeTree.pos(),
mcimadamore@1215
  4389
                          chk.checkClassType(typeTree.pos(), ctype),
mcimadamore@1215
  4390
                          syms.throwableType);
mcimadamore@1436
  4391
            if (!ctype.isErroneous()) {
darcy@1452
  4392
                //check that alternatives of a union type are pairwise
mcimadamore@1436
  4393
                //unrelated w.r.t. subtyping
mcimadamore@1436
  4394
                if (chk.intersects(ctype,  multicatchTypes.toList())) {
mcimadamore@1436
  4395
                    for (Type t : multicatchTypes) {
mcimadamore@1436
  4396
                        boolean sub = types.isSubtype(ctype, t);
mcimadamore@1436
  4397
                        boolean sup = types.isSubtype(t, ctype);
mcimadamore@1436
  4398
                        if (sub || sup) {
mcimadamore@1436
  4399
                            //assume 'a' <: 'b'
mcimadamore@1436
  4400
                            Type a = sub ? ctype : t;
mcimadamore@1436
  4401
                            Type b = sub ? t : ctype;
mcimadamore@1436
  4402
                            log.error(typeTree.pos(), "multicatch.types.must.be.disjoint", a, b);
mcimadamore@1436
  4403
                        }
mcimadamore@1436
  4404
                    }
mcimadamore@1436
  4405
                }
mcimadamore@1436
  4406
                multicatchTypes.append(ctype);
jjg@1482
  4407
                if (all_multicatchTypes != null)
jjg@1482
  4408
                    all_multicatchTypes.append(ctype);
jjg@1482
  4409
            } else {
jjg@1482
  4410
                if (all_multicatchTypes == null) {
alundblad@3063
  4411
                    all_multicatchTypes = new ListBuffer<>();
jjg@1482
  4412
                    all_multicatchTypes.appendList(multicatchTypes);
jjg@1482
  4413
                }
jjg@1482
  4414
                all_multicatchTypes.append(ctype);
mcimadamore@1436
  4415
            }
mcimadamore@1215
  4416
        }
sadayapalam@4483
  4417
        Type t = check(tree, types.lub(multicatchTypes.toList()),
sadayapalam@4483
  4418
                KindSelector.TYP, resultInfo.dup(CheckMode.NO_TREE_UPDATE));
jjg@2213
  4419
        if (t.hasTag(CLASS)) {
jjg@1482
  4420
            List<Type> alternatives =
jjg@1482
  4421
                ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
jjg@1482
  4422
            t = new UnionClassType((ClassType) t, alternatives);
jjg@1482
  4423
        }
jjg@1482
  4424
        tree.type = result = t;
mcimadamore@944
  4425
    }
mcimadamore@944
  4426
mcimadamore@2276
  4427
    public void visitTypeIntersection(JCTypeIntersection tree) {
mcimadamore@2276
  4428
        attribTypes(tree.bounds, env);
mcimadamore@2276
  4429
        tree.type = result = checkIntersection(tree, tree.bounds);
mcimadamore@2276
  4430
    }
mcimadamore@2276
  4431
jjg@2372
  4432
    public void visitTypeParameter(JCTypeParameter tree) {
jjg@2372
  4433
        TypeVar typeVar = (TypeVar) tree.type;
jjg@2372
  4434
jjg@2372
  4435
        if (tree.annotations != null && tree.annotations.nonEmpty()) {
jjg@4454
  4436
            annotate.annotateTypeParameterSecondStage(tree, tree.annotations);
jjg@2372
  4437
        }
jjg@2372
  4438
mcimadamore@2276
  4439
        if (!typeVar.bound.isErroneous()) {
mcimadamore@2276
  4440
            //fixup type-parameter bound computed in 'attribTypeVariables'
mcimadamore@2276
  4441
            typeVar.bound = checkIntersection(tree, tree.bounds);
mcimadamore@2276
  4442
        }
mcimadamore@2276
  4443
    }
mcimadamore@2276
  4444
mcimadamore@2276
  4445
    Type checkIntersection(JCTree tree, List<JCExpression> bounds) {
briangoetz@3808
  4446
        Set<Type> boundSet = new HashSet<>();
mcimadamore@2276
  4447
        if (bounds.nonEmpty()) {
duke@0
  4448
            // accept class or interface or typevar as first bound.
emc@3214
  4449
            bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
mcimadamore@2276
  4450
            boundSet.add(types.erasure(bounds.head.type));
mcimadamore@2276
  4451
            if (bounds.head.type.isErroneous()) {
mcimadamore@2276
  4452
                return bounds.head.type;
mcimadamore@338
  4453
            }
mcimadamore@2276
  4454
            else if (bounds.head.type.hasTag(TYPEVAR)) {
duke@0
  4455
                // if first bound was a typevar, do not accept further bounds.
mcimadamore@2276
  4456
                if (bounds.tail.nonEmpty()) {
mcimadamore@2276
  4457
                    log.error(bounds.tail.head.pos(),
duke@0
  4458
                              "type.var.may.not.be.followed.by.other.bounds");
mcimadamore@2276
  4459
                    return bounds.head.type;
duke@0
  4460
                }
duke@0
  4461
            } else {
duke@0
  4462
                // if first bound was a class or interface, accept only interfaces
duke@0
  4463
                // as further bounds.
mcimadamore@2276
  4464
                for (JCExpression bound : bounds.tail) {
emc@3214
  4465
                    bound.type = checkBase(bound.type, bound, env, false, true, false);
mcimadamore@2276
  4466
                    if (bound.type.isErroneous()) {
mcimadamore@2276
  4467
                        bounds = List.of(bound);
mcimadamore@2276
  4468
                    }
mcimadamore@2276
  4469
                    else if (bound.type.hasTag(CLASS)) {
mcimadamore@2276
  4470
                        chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
mcimadamore@2276
  4471
                    }
duke@0
  4472
                }
duke@0
  4473
            }
duke@0
  4474
        }
mcimadamore@2276
  4475
mcimadamore@2276
  4476
        if (bounds.length() == 0) {
mcimadamore@2276
  4477
            return syms.objectType;
mcimadamore@2276
  4478
        } else if (bounds.length() == 1) {
mcimadamore@2276
  4479
            return bounds.head.type;
mcimadamore@2276
  4480
        } else {
mcimadamore@4406
  4481
            Type owntype = types.makeIntersectionType(TreeInfo.types(bounds));
duke@0
  4482
            // ... the variable's bound is a class type flagged COMPOUND
duke@0
  4483
            // (see comment for TypeVar.bound).
duke@0
  4484
            // In this case, generate a class tree that represents the
duke@0
  4485
            // bound class, ...
jjg@1388
  4486
            JCExpression extending;
duke@0
  4487
            List<JCExpression> implementing;
mcimadamore@2276
  4488
            if (!bounds.head.type.isInterface()) {
mcimadamore@2276
  4489
                extending = bounds.head;
mcimadamore@2276
  4490
                implementing = bounds.tail;
duke@0
  4491
            } else {
duke@0
  4492
                extending = null;
mcimadamore@2276
  4493
                implementing = bounds;
duke@0
  4494
            }
mcimadamore@2276
  4495
            JCClassDecl cd = make.at(tree).ClassDef(
duke@0
  4496
                make.Modifiers(PUBLIC | ABSTRACT),
mcimadamore@5586
  4497
                names.empty, List.nil(),
mcimadamore@5586
  4498
                extending, implementing, List.nil());
duke@0
  4499
mcimadamore@2276
  4500
            ClassSymbol c = (ClassSymbol)owntype.tsym;
jjg@1281
  4501
            Assert.check((c.flags() & COMPOUND) != 0);
duke@0
  4502
            cd.sym = c;
duke@0
  4503
            c.sourcefile = env.toplevel.sourcefile;
duke@0
  4504
duke@0
  4505
            // ... and attribute the bound class
duke@0
  4506
            c.flags_field |= UNATTRIBUTED;
duke@0
  4507
            Env<AttrContext> cenv = enter.classEnv(cd, env);
pgovereau@4044
  4508
            typeEnvs.put(c, cenv);
mcimadamore@2276
  4509
            attribClass(c);
mcimadamore@2276
  4510
            return owntype;
duke@0
  4511
        }
duke@0
  4512
    }
duke@0
  4513
duke@0
  4514
    public void visitWildcard(JCWildcard tree) {
duke@0
  4515
        //- System.err.println("visitWildcard("+tree+");");//DEBUG
duke@0
  4516
        Type type = (tree.kind.kind == BoundKind.UNBOUND)
duke@0
  4517
            ? syms.objectType
duke@0
  4518
            : attribType(tree.inner, env);
duke@0
  4519
        result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type),
duke@0
  4520
                                              tree.kind.kind,
emc@4221
  4521
                                              syms.boundClass),
emc@4248
  4522
                KindSelector.TYP, resultInfo);
duke@0
  4523
    }
duke@0
  4524
duke@0
  4525
    public void visitAnnotation(JCAnnotation tree) {
jjg@4454
  4526
        Assert.error("should be handled in annotate");
duke@0
  4527
    }
duke@0
  4528
jjg@2372
  4529
    public void visitAnnotatedType(JCAnnotatedType tree) {
jjg@4454
  4530
        attribAnnotationTypes(tree.annotations, env);
sadayapalam@4553
  4531
        Type underlyingType = attribType(tree.underlyingType, env);
jjg@4454
  4532
        Type annotatedType = underlyingType.annotatedType(Annotations.TO_BE_SET);
jjg@4454
  4533
jjg@4454
  4534
        if (!env.info.isNewClass)
jjg@4454
  4535
            annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType);
jjg@4454
  4536
        result = tree.type = annotatedType;
jjg@2372
  4537
    }
jjg@2372
  4538
duke@0
  4539
    public void visitErroneous(JCErroneous tree) {
duke@0
  4540
        if (tree.errs != null)
dbalek@2545
  4541
            for (JCTree err : tree.errs) {
dbalek@2545
  4542
                try {
dbalek@4426
  4543
                    attribTree(err, env, new ResultInfo(KindSelector.ERR, pt()));
dbalek@2545
  4544
                } catch (AssertionError ae) {
dbalek@2545
  4545
                    //ignore
dbalek@2545
  4546
                }
dbalek@2545
  4547
            }
duke@0
  4548
        result = tree.type = syms.errType;
duke@0
  4549
    }
duke@0
  4550
duke@0
  4551
    /** Default visitor method for all other trees.
duke@0
  4552
     */
duke@0
  4553
    public void visitTree(JCTree tree) {
duke@0
  4554
        throw new AssertionError();
duke@0
  4555
    }
duke@0
  4556
jjg@1415
  4557
    /**
alanb@5016
  4558
     * Attribute an env for either a top level tree or class or module declaration.
jjg@1415
  4559
     */
jjg@1415
  4560
    public void attrib(Env<AttrContext> env) {
alanb@5016
  4561
        switch (env.tree.getTag()) {
alanb@5016
  4562
            case MODULEDEF:
alanb@5016
  4563
                attribModule(env.tree.pos(), ((JCModuleDecl)env.tree).sym);
alanb@5016
  4564
                break;
alanb@5016
  4565
            case TOPLEVEL:
alanb@5016
  4566
                attribTopLevel(env);
alanb@5016
  4567
                break;
sadayapalam@5312
  4568
            case PACKAGEDEF:
sadayapalam@5312
  4569
                attribPackage(env.tree.pos(), ((JCPackageDecl) env.tree).packge);
sadayapalam@5312
  4570
                break;
alanb@5016
  4571
            default:
alanb@5016
  4572
                attribClass(env.tree.pos(), env.enclClass.sym);
alanb@5016
  4573
        }
jjg@1415
  4574
    }
jjg@1415
  4575
jjg@1415
  4576
    /**
jjg@1415
  4577
     * Attribute a top level tree. These trees are encountered when the
jjg@1415
  4578
     * package declaration has annotations.
jjg@1415
  4579
     */
jjg@1415
  4580
    public void attribTopLevel(Env<AttrContext> env) {
jjg@1415
  4581
        JCCompilationUnit toplevel = env.toplevel;
jjg@1415
  4582
        try {
jjg@1415
  4583
            annotate.flush();
jjg@1415
  4584
        } catch (CompletionFailure ex) {
jjg@1415
  4585
            chk.completionError(toplevel.pos(), ex);
jjg@1415
  4586
        }
jjg@1415
  4587
    }
jjg@1415
  4588
sadayapalam@5312
  4589
    public void attribPackage(DiagnosticPosition pos, PackageSymbol p) {
sadayapalam@5312
  4590
        try {
sadayapalam@5312
  4591
            annotate.flush();
sadayapalam@5312
  4592
            attribPackage(p);
sadayapalam@5312
  4593
        } catch (CompletionFailure ex) {
sadayapalam@5312
  4594
            chk.completionError(pos, ex);
sadayapalam@5312
  4595
        }
sadayapalam@5312
  4596
    }
sadayapalam@5312
  4597
sadayapalam@5312
  4598
    void attribPackage(PackageSymbol p) {
sadayapalam@5312
  4599
        Env<AttrContext> env = typeEnvs.get(p);
sadayapalam@5312
  4600
        chk.checkDeprecatedAnnotation(((JCPackageDecl) env.tree).pid.pos(), p);
sadayapalam@5312
  4601
    }
sadayapalam@5312
  4602
alanb@5016
  4603
    public void attribModule(DiagnosticPosition pos, ModuleSymbol m) {
alanb@5016
  4604
        try {
alanb@5016
  4605
            annotate.flush();
alanb@5016
  4606
            attribModule(m);
alanb@5016
  4607
        } catch (CompletionFailure ex) {
alanb@5016
  4608
            chk.completionError(pos, ex);
alanb@5016
  4609
        }
alanb@5016
  4610
    }
alanb@5016
  4611
alanb@5016
  4612
    void attribModule(ModuleSymbol m) {
alanb@5016
  4613
        // Get environment current at the point of module definition.
alanb@5016
  4614
        Env<AttrContext> env = enter.typeEnvs.get(m);
alanb@5016
  4615
        attribStat(env.tree, env);
alanb@5016
  4616
    }
alanb@5016
  4617
duke@0
  4618
    /** Main method: attribute class definition associated with given class symbol.
duke@0
  4619
     *  reporting completion failures at the given position.
duke@0
  4620
     *  @param pos The source position at which completion errors are to be
duke@0
  4621
     *             reported.
duke@0
  4622
     *  @param c   The class symbol whose definition will be attributed.
duke@0
  4623
     */
duke@0
  4624
    public void attribClass(DiagnosticPosition pos, ClassSymbol c) {
duke@0
  4625
        try {
duke@0
  4626
            annotate.flush();
duke@0
  4627
            attribClass(c);
duke@0
  4628
        } catch (CompletionFailure ex) {
duke@0
  4629
            chk.completionError(pos, ex);
duke@0
  4630
        }
duke@0
  4631
    }
duke@0
  4632
duke@0
  4633
    /** Attribute class definition associated with given class symbol.
duke@0
  4634
     *  @param c   The class symbol whose definition will be attributed.
duke@0
  4635
     */
duke@0
  4636
    void attribClass(ClassSymbol c) throws CompletionFailure {
duke@0
  4637
        // Check for cycles in the inheritance graph, which can arise from
duke@0
  4638
        // ill-formed class files.
duke@0
  4639
        chk.checkNonCyclic(null, c.type);
duke@0
  4640
duke@0
  4641
        Type st = types.supertype(c.type);
duke@0
  4642
        if ((c.flags_field & Flags.COMPOUND) == 0) {
duke@0
  4643
            // First, attribute superclass.
jjg@2213
  4644
            if (st.hasTag(CLASS))
duke@0
  4645
                attribClass((ClassSymbol)st.tsym);
duke@0
  4646
duke@0
  4647
            // Next attribute owner, if it is a class.
jjg@2213
  4648
            if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS))
duke@0
  4649
                attribClass((ClassSymbol)c.owner);
duke@0
  4650
        }
duke@0
  4651
duke@0
  4652
        // The previous operations might have attributed the current class
duke@0
  4653
        // if there was a cycle. So we test first whether the class is still
duke@0
  4654
        // UNATTRIBUTED.
duke@0
  4655
        if ((c.flags_field & UNATTRIBUTED) != 0) {
duke@0
  4656
            c.flags_field &= ~UNATTRIBUTED;
duke@0
  4657
duke@0
  4658
            // Get environment current at the point of class definition.
pgovereau@4044
  4659
            Env<AttrContext> env = typeEnvs.get(c);
dbalek@134
  4660
            if (env == null) {
dbalek@134
  4661
                return;
dbalek@134
  4662
            }
pgovereau@4044
  4663
pgovereau@4044
  4664
            // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized,
duke@0
  4665
            // because the annotations were not available at the time the env was created. Therefore,
duke@0
  4666
            // we look up the environment chain for the first enclosing environment for which the
duke@0
  4667
            // lint value is set. Typically, this is the parent env, but might be further if there
duke@0
  4668
            // are any envs created as a result of TypeParameter nodes.
duke@0
  4669
            Env<AttrContext> lintEnv = env;
duke@0
  4670
            while (lintEnv.info.lint == null)
duke@0
  4671
                lintEnv = lintEnv.next;
duke@0
  4672
duke@0
  4673
            // Having found the enclosing lint value, we can initialize the lint value for this class
jjg@2786
  4674
            env.info.lint = lintEnv.info.lint.augment(c);
duke@0
  4675
duke@0
  4676
            Lint prevLint = chk.setLint(env.info.lint);
duke@0
  4677
            JavaFileObject prev = log.useSource(c.sourcefile);
mcimadamore@2190
  4678
            ResultInfo prevReturnRes = env.info.returnResult;
duke@0
  4679
duke@0
  4680
            try {
jlahoda@3044
  4681
                deferredLintHandler.flush(env.tree);
mcimadamore@2190
  4682
                env.info.returnResult = null;
duke@0
  4683
                // java.lang.Enum may not be subclassed by a non-enum
duke@0
  4684
                if (st.tsym == syms.enumSym &&
duke@0
  4685
                    ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
duke@0
  4686
                    log.error(env.tree.pos(), "enum.no.subclassing");
duke@0
  4687
duke@0
  4688
                // Enums may not be extended by source-level classes
duke@0
  4689
                if (st.tsym != null &&
duke@0
  4690
                    ((st.tsym.flags_field & Flags.ENUM) != 0) &&
darcy@2575
  4691
                    ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
duke@0
  4692
                    log.error(env.tree.pos(), "enum.types.not.extensible");
duke@0
  4693
                }
vromero@3964
  4694
vromero@3964
  4695
                if (isSerializable(c.type)) {
vromero@3964
  4696
                    env.info.isSerializable = true;
vromero@3964
  4697
                }
vromero@3964
  4698
duke@0
  4699
                attribClassBody(env, c);
duke@0
  4700
dbalek@1328
  4701
                deferredLintHandler.flush(env.tree.pos());
duke@0
  4702
                chk.checkDeprecatedAnnotation(env.tree.pos(), c);
vromero@2529
  4703
                chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
jlahoda@3135
  4704
                chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
jlahoda@5433
  4705
                chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
duke@0
  4706
            } finally {
mcimadamore@2190
  4707
                env.info.returnResult = prevReturnRes;
duke@0
  4708
                log.useSource(prev);
duke@0
  4709
                chk.setLint(prevLint);
duke@0
  4710
            }
duke@0
  4711
duke@0
  4712
        }
duke@0
  4713
    }
duke@0
  4714
duke@0
  4715
    public void visitImport(JCImport tree) {
duke@0
  4716
        // nothing to do
duke@0
  4717
    }
duke@0
  4718
alanb@5016
  4719
    public void visitModuleDef(JCModuleDecl tree) {
alanb@5016
  4720
        tree.sym.completeUsesProvides();
alanb@5550
  4721
        ModuleSymbol msym = tree.sym;
alanb@5550
  4722
        Lint lint = env.outer.info.lint = env.outer.info.lint.augment(msym);
alanb@5550
  4723
        Lint prevLint = chk.setLint(lint);
alanb@5580
  4724
        chk.checkModuleName(tree);
alanb@5550
  4725
        chk.checkDeprecatedAnnotation(tree, msym);
alanb@5550
  4726
alanb@5550
  4727
        try {
alanb@5550
  4728
            deferredLintHandler.flush(tree.pos());
alanb@5550
  4729
        } finally {
alanb@5550
  4730
            chk.setLint(prevLint);
alanb@5550
  4731
        }
alanb@5016
  4732
    }
alanb@5016
  4733
duke@0
  4734
    /** Finish the attribution of a class. */
duke@0
  4735
    private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
duke@0
  4736
        JCClassDecl tree = (JCClassDecl)env.tree;
jlahoda@1327
  4737
jlahoda@1327
  4738
        if (c != tree.sym)
jlahoda@1327
  4739
            Assert.error("c = " + c + " tree.sym = " + tree.sym + " tree = " + tree);
duke@0
  4740
duke@0
  4741
        // Validate type parameters, supertype and interfaces.
mcimadamore@2276
  4742
        attribStats(tree.typarams, env);
mcimadamore@927
  4743
        if (!c.isAnonymous()) {
mcimadamore@927
  4744
            //already checked if anonymous
mcimadamore@927
  4745
            chk.validate(tree.typarams, env);
mcimadamore@927
  4746
            chk.validate(tree.extending, env);
mcimadamore@927
  4747
            chk.validate(tree.implementing, env);
mcimadamore@927
  4748
        }
duke@0
  4749
jlahoda@4369
  4750
        c.markAbstractIfNeeded(types);
jlahoda@4369
  4751
duke@0
  4752
        // If this is a non-abstract class, check that it has no abstract
duke@0
  4753
        // methods or unimplemented methods of an implemented interface.
duke@0
  4754
        if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
vromero@4979
  4755
            chk.checkAllDefined(tree.pos(), c);
duke@0
  4756
        }
duke@0
  4757
duke@0
  4758
        if ((c.flags() & ANNOTATION) != 0) {
duke@0
  4759
            if (tree.implementing.nonEmpty())
duke@0
  4760
                log.error(tree.implementing.head.pos(),
duke@0
  4761
                          "cant.extend.intf.annotation");
duke@0
  4762
            if (tree.typarams.nonEmpty())
duke@0
  4763
                log.error(tree.typarams.head.pos(),
duke@0
  4764
                          "intf.annotation.cant.have.type.params");
jfranck@2156
  4765
jjg@4454
  4766
            // If this annotation type has a @Repeatable, validate
jjg@4454
  4767
            Attribute.Compound repeatable = c.getAnnotationTypeMetadata().getRepeatable();
jjg@4454
  4768
            // If this annotation type has a @Repeatable, validate
jjg@2339
  4769
            if (repeatable != null) {
jjg@2339
  4770
                // get diagnostic position for error reporting
jjg@2339
  4771
                DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
jfranck@2156
  4772
                Assert.checkNonNull(cbPos);
jfranck@2156
  4773
jjg@2339
  4774
                chk.validateRepeatable(c, repeatable, cbPos);
jfranck@2156
  4775
            }
duke@0
  4776
        } else {
duke@0
  4777
            // Check that all extended classes and interfaces
duke@0
  4778
            // are compatible (i.e. no two define methods with same arguments
duke@0
  4779
            // yet different return types).  (JLS 8.4.6.3)
duke@0
  4780
            chk.checkCompatibleSupertypes(tree.pos(), c.type);
mcimadamore@2234
  4781
            if (allowDefaultMethods) {
mcimadamore@2234
  4782
                chk.checkDefaultMethodClashes(tree.pos(), c.type);
mcimadamore@2234
  4783
            }
duke@0
  4784
        }
duke@0
  4785
duke@0
  4786
        // Check that class does not import the same parameterized interface
duke@0
  4787
        // with two different argument lists.
duke@0
  4788
        chk.checkClassBounds(tree.pos(), c.type);
duke@0
  4789
duke@0
  4790
        tree.type = c.type;
duke@0
  4791
jjg@1281
  4792
        for (List<JCTypeParameter> l = tree.typarams;
jjg@1281
  4793
             l.nonEmpty(); l = l.tail) {
jlahoda@4103
  4794
             Assert.checkNonNull(env.info.scope.findFirst(l.head.name));
duke@0
  4795
        }
duke@0
  4796
duke@0
  4797
        // Check that a generic class doesn't extend Throwable
duke@0
  4798
        if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
duke@0
  4799
            log.error(tree.extending.pos(), "generic.throwable");
duke@0
  4800
duke@0
  4801
        // Check that all methods which implement some
duke@0
  4802
        // method conform to the method they implement.
dbalek@3084
  4803
        DiagnosticPosition prevPos = deferredLintHandler.setPos(tree.pos());
dbalek@1333
  4804
        try {
dbalek@1333
  4805
            chk.checkImplementations(tree);
dbalek@1333
  4806
        } finally {
dbalek@1333
  4807
            deferredLintHandler.setPos(prevPos);
dbalek@1333
  4808
        }
duke@0
  4809
mcimadamore@1438
  4810
        //check that a resource implementing AutoCloseable cannot throw InterruptedException
mcimadamore@1438
  4811
        checkAutoCloseable(tree.pos(), env, c.type);
mcimadamore@1438
  4812
duke@0
  4813
        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
duke@0
  4814
            // Attribute declaration
duke@0
  4815
            attribStat(l.head, env);
duke@0
  4816
            // Check that declarations in inner classes are not static (JLS 8.1.2)
duke@0
  4817
            // Make an exception for static constants.
duke@0
  4818
            if (c.owner.kind != PCK &&
duke@0
  4819
                ((c.flags() & STATIC) == 0 || c.name == names.empty) &&
duke@0
  4820
                (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
duke@0
  4821
                Symbol sym = null;
jjg@1972
  4822
                if (l.head.hasTag(VARDEF)) sym = ((JCVariableDecl) l.head).sym;
duke@0
  4823
                if (sym == null ||
duke@0
  4824
                    sym.kind != VAR ||
jlahoda@5
  4825
                    ((VarSymbol) sym).getConstValue() == null) {
jlahoda@5
  4826
                    // Check that enum type is not local. If so, 'Enum types must not be local' is already reported
jlahoda@5
  4827
                    // and there is no need for reporting static declaration in an inner class
jlahoda@5
  4828
                    if (c.owner.kind != MTH || (c.flags() & ENUM) == 0)
jlahoda@1327
  4829
                        log.error(l.head.pos(), "icls.cant.have.static.decl", c);
jlahoda@5
  4830
                }
duke@0
  4831
            }
duke@0
  4832
        }
duke@0
  4833
duke@0
  4834
        // Check for cycles among non-initial constructors.
duke@0
  4835
        chk.checkCyclicConstructors(tree);
duke@0
  4836
duke@0
  4837
        // Check for cycles among annotation elements.
duke@0
  4838
        chk.checkNonCyclicElements(tree);
duke@0
  4839
duke@0
  4840
        // Check for proper use of serialVersionUID
alundblad@5069
  4841
        if (env.info.lint.isEnabled(LintCategory.SERIAL)
alundblad@5069
  4842
                && isSerializable(c.type)
alundblad@5069
  4843
                && (c.flags() & Flags.ENUM) == 0
alundblad@5069
  4844
                && !c.isAnonymous()
alundblad@5069
  4845
                && checkForSerial(c)) {
duke@0
  4846
            checkSerialVersionUID(tree, c);
duke@0
  4847
        }
jfranck@4203
  4848
        if (allowTypeAnnos) {
jfranck@4203
  4849
            // Correctly organize the postions of the type annotations
jfranck@4203
  4850
            typeAnnotations.organizeTypeAnnotationsBodies(tree);
jfranck@4203
  4851
jfranck@4203
  4852
            // Check type annotations applicability rules
jfranck@4203
  4853
            validateTypeAnnotations(tree, false);
jfranck@4203
  4854
        }
duke@0
  4855
    }
duke@0
  4856
        // where
vromero@2877
  4857
        boolean checkForSerial(ClassSymbol c) {
vromero@2877
  4858
            if ((c.flags() & ABSTRACT) == 0) {
vromero@2877
  4859
                return true;
vromero@2877
  4860
            } else {
vromero@2877
  4861
                return c.members().anyMatch(anyNonAbstractOrDefaultMethod);
vromero@2877
  4862
            }
vromero@2877
  4863
        }
vromero@2877
  4864
mcimadamore@5585
  4865
        public static final Filter<Symbol> anyNonAbstractOrDefaultMethod = s ->
mcimadamore@5585
  4866
                s.kind == MTH && (s.flags() & (DEFAULT | ABSTRACT)) != ABSTRACT;
vromero@2877
  4867
jfranck@2156
  4868
        /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
jfranck@2156
  4869
        private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
jfranck@2156
  4870
            for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
jfranck@2156
  4871
                if (types.isSameType(al.head.annotationType.type, t))
jfranck@2156
  4872
                    return al.head.pos();
jfranck@2156
  4873
            }
jfranck@2156
  4874
jfranck@2156
  4875
            return null;
jfranck@2156
  4876
        }
jfranck@2156
  4877
vromero@3964
  4878
        /** check if a type is a subtype of Serializable, if that is available. */
vromero@3964
  4879
        boolean isSerializable(Type t) {
duke@0
  4880
            try {
duke@0
  4881
                syms.serializableType.complete();
duke@0
  4882
            }
duke@0
  4883
            catch (CompletionFailure e) {
duke@0
  4884
                return false;
duke@0
  4885
            }
vromero@3964
  4886
            return types.isSubtype(t, syms.serializableType);
duke@0
  4887
        }
duke@0
  4888
duke@0
  4889
        /** Check that an appropriate serialVersionUID member is defined. */
duke@0
  4890
        private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) {
duke@0
  4891
duke@0
  4892
            // check for presence of serialVersionUID
jlahoda@4103
  4893
            VarSymbol svuid = null;
jlahoda@4103
  4894
            for (Symbol sym : c.members().getSymbolsByName(names.serialVersionUID)) {
jlahoda@4103
  4895
                if (sym.kind == VAR) {
jlahoda@4103
  4896
                    svuid = (VarSymbol)sym;
jlahoda@4103
  4897
                    break;
jlahoda@4103
  4898
                }
jlahoda@4103
  4899
            }
jlahoda@4103
  4900
jlahoda@4103
  4901
            if (svuid == null) {
mcimadamore@1244
  4902
                log.warning(LintCategory.SERIAL,
jjg@1008
  4903
                        tree.pos(), "missing.SVUID", c);
duke@0
  4904
                return;
duke@0
  4905
            }
duke@0
  4906
duke@0
  4907
            // check that it is static final
duke@0
  4908
            if ((svuid.flags() & (STATIC | FINAL)) !=
duke@0
  4909
                (STATIC | FINAL))
mcimadamore@1244
  4910
                log.warning(LintCategory.SERIAL,
jjg@1008
  4911
                        TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
duke@0
  4912
duke@0
  4913
            // check that it is long
jjg@2213
  4914
            else if (!svuid.type.hasTag(LONG))
mcimadamore@1244
  4915
                log.warning(LintCategory.SERIAL,
jjg@1008
  4916
                        TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);
duke@0
  4917
duke@0
  4918
            // check constant
duke@0
  4919
            else if (svuid.getConstValue() == null)
mcimadamore@1244
  4920
                log.warning(LintCategory.SERIAL,
jjg@1008
  4921
                        TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c);
duke@0
  4922
        }
duke@0
  4923
duke@0
  4924
    private Type capture(Type type) {
mcimadamore@2889
  4925
        return types.capture(type);
duke@0
  4926
    }
jjg@598
  4927
jfranck@4203
  4928
    public void validateTypeAnnotations(JCTree tree, boolean sigOnly) {
jfranck@4203
  4929
        tree.accept(new TypeAnnotationsValidator(sigOnly));
jfranck@4203
  4930
    }
jfranck@4203
  4931
    //where
jfranck@4203
  4932
    private final class TypeAnnotationsValidator extends TreeScanner {
jfranck@4203
  4933
jfranck@4203
  4934
        private final boolean sigOnly;
jfranck@4203
  4935
        public TypeAnnotationsValidator(boolean sigOnly) {
jfranck@4203
  4936
            this.sigOnly = sigOnly;
jfranck@4203
  4937
        }
jfranck@4203
  4938
jfranck@4203
  4939
        public void visitAnnotation(JCAnnotation tree) {
jfranck@4203
  4940
            chk.validateTypeAnnotation(tree, false);
jfranck@4203
  4941
            super.visitAnnotation(tree);
jfranck@4203
  4942
        }
jfranck@4203
  4943
        public void visitAnnotatedType(JCAnnotatedType tree) {
jfranck@4203
  4944
            if (!tree.underlyingType.type.isErroneous()) {
jfranck@4203
  4945
                super.visitAnnotatedType(tree);
jfranck@4203
  4946
            }
jfranck@4203
  4947
        }
jfranck@4203
  4948
        public void visitTypeParameter(JCTypeParameter tree) {
jfranck@4203
  4949
            chk.validateTypeAnnotations(tree.annotations, true);
jfranck@4203
  4950
            scan(tree.bounds);
jfranck@4203
  4951
            // Don't call super.
jfranck@4203
  4952
            // This is needed because above we call validateTypeAnnotation with
jfranck@4203
  4953
            // false, which would forbid annotations on type parameters.
jfranck@4203
  4954
            // super.visitTypeParameter(tree);
jfranck@4203
  4955
        }
jfranck@4203
  4956
        public void visitMethodDef(JCMethodDecl tree) {
jfranck@4203
  4957
            if (tree.recvparam != null &&
jfranck@4203
  4958
                    !tree.recvparam.vartype.type.isErroneous()) {
jfranck@4203
  4959
                checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
jfranck@4203
  4960
                        tree.recvparam.vartype.type.tsym);
jfranck@4203
  4961
            }
jfranck@4203
  4962
            if (tree.restype != null && tree.restype.type != null) {
jfranck@4203
  4963
                validateAnnotatedType(tree.restype, tree.restype.type);
jfranck@4203
  4964
            }
jfranck@4203
  4965
            if (sigOnly) {
jfranck@4203
  4966
                scan(tree.mods);
jfranck@4203
  4967
                scan(tree.restype);
jfranck@4203
  4968
                scan(tree.typarams);
jfranck@4203
  4969
                scan(tree.recvparam);
jfranck@4203
  4970
                scan(tree.params);
jfranck@4203
  4971
                scan(tree.thrown);
jfranck@4203
  4972
            } else {
jfranck@4203
  4973
                scan(tree.defaultValue);
jfranck@4203
  4974
                scan(tree.body);
jfranck@4203
  4975
            }
jfranck@4203
  4976
        }
jfranck@4203
  4977
        public void visitVarDef(final JCVariableDecl tree) {
jfranck@4203
  4978
            //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
dbalek@3762
  4979
            if (tree.sym != null && tree.sym.type != null && !tree.sym.type.isErroneous())
jfranck@4203
  4980
                validateAnnotatedType(tree.vartype, tree.sym.type);
jfranck@4203
  4981
            scan(tree.mods);
jfranck@4203
  4982
            scan(tree.vartype);
jfranck@4203
  4983
            if (!sigOnly) {
jfranck@4203
  4984
                scan(tree.init);
jfranck@4203
  4985
            }
jfranck@4203
  4986
        }
jfranck@4203
  4987
        public void visitTypeCast(JCTypeCast tree) {
jfranck@4203
  4988
            if (tree.clazz != null && tree.clazz.type != null)
jfranck@4203
  4989
                validateAnnotatedType(tree.clazz, tree.clazz.type);
jfranck@4203
  4990
            super.visitTypeCast(tree);
jfranck@4203
  4991
        }
jfranck@4203
  4992
        public void visitTypeTest(JCInstanceOf tree) {
jfranck@4203
  4993
            if (tree.clazz != null && tree.clazz.type != null)
jfranck@4203
  4994
                validateAnnotatedType(tree.clazz, tree.clazz.type);
jfranck@4203
  4995
            super.visitTypeTest(tree);
jfranck@4203
  4996
        }
jfranck@4203
  4997
        public void visitNewClass(JCNewClass tree) {
jfranck@4308
  4998
            if (tree.clazz != null && tree.clazz.type != null) {
jfranck@4308
  4999
                if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
jfranck@4308
  5000
                    checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
jfranck@4308
  5001
                            tree.clazz.type.tsym);
jfranck@4308
  5002
                }
jfranck@4308
  5003
                if (tree.def != null) {
jfranck@4308
  5004
                    checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
jfranck@4308
  5005
                }
jfranck@4308
  5006
jfranck@4203
  5007
                validateAnnotatedType(tree.clazz, tree.clazz.type);
jfranck@4203
  5008
            }
jfranck@4203
  5009
            super.visitNewClass(tree);
jfranck@4203
  5010
        }
jfranck@4203
  5011
        public void visitNewArray(JCNewArray tree) {
jfranck@4203
  5012
            if (tree.elemtype != null && tree.elemtype.type != null) {
jfranck@4203
  5013
                if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
jfranck@4203
  5014
                    checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
jfranck@4203
  5015
                            tree.elemtype.type.tsym);
jfranck@4203
  5016
                }
jfranck@4203
  5017
                validateAnnotatedType(tree.elemtype, tree.elemtype.type);
jfranck@4203
  5018
            }
jfranck@4203
  5019
            super.visitNewArray(tree);
jfranck@4203
  5020
        }
jfranck@4203
  5021
        public void visitClassDef(JCClassDecl tree) {
jfranck@4203
  5022
            //System.err.println("validateTypeAnnotations.visitClassDef " + tree);
jfranck@4203
  5023
            if (sigOnly) {
jfranck@4203
  5024
                scan(tree.mods);
jfranck@4203
  5025
                scan(tree.typarams);
jfranck@4203
  5026
                scan(tree.extending);
jfranck@4203
  5027
                scan(tree.implementing);
jfranck@4203
  5028
            }
jfranck@4203
  5029
            for (JCTree member : tree.defs) {
jfranck@4203
  5030
                if (member.hasTag(Tag.CLASSDEF)) {
jfranck@4203
  5031
                    continue;
jfranck@4203
  5032
                }
jfranck@4203
  5033
                scan(member);
jfranck@4203
  5034
            }
jfranck@4203
  5035
        }
jfranck@4203
  5036
        public void visitBlock(JCBlock tree) {
jfranck@4203
  5037
            if (!sigOnly) {
jfranck@4203
  5038
                scan(tree.stats);
jfranck@4203
  5039
            }
jfranck@4203
  5040
        }
jfranck@4203
  5041
jfranck@4203
  5042
        /* I would want to model this after
jfranck@4203
  5043
         * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
jfranck@4203
  5044
         * and override visitSelect and visitTypeApply.
jfranck@4203
  5045
         * However, we only set the annotated type in the top-level type
jfranck@4203
  5046
         * of the symbol.
jfranck@4203
  5047
         * Therefore, we need to override each individual location where a type
jfranck@4203
  5048
         * can occur.
jfranck@4203
  5049
         */
jfranck@4203
  5050
        private void validateAnnotatedType(final JCTree errtree, final Type type) {
jfranck@4203
  5051
            //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
jfranck@4203
  5052
dbalek@4735
  5053
            if (type.isPrimitiveOrVoid() || type.isErroneous()) {
jfranck@4203
  5054
                return;
jfranck@4203
  5055
            }
jfranck@4203
  5056
jfranck@4203
  5057
            JCTree enclTr = errtree;
jfranck@4203
  5058
            Type enclTy = type;
jfranck@4203
  5059
jfranck@4203
  5060
            boolean repeat = true;
jfranck@4203
  5061
            while (repeat) {
dbalek@3751
  5062
                if (enclTr == null) {
dbalek@3751
  5063
                    Assert.error("Unexpected null tree within: "+ errtree + " with kind: " + errtree.getKind());
dbalek@3751
  5064
                }
jfranck@4203
  5065
                if (enclTr.hasTag(TYPEAPPLY)) {
jfranck@4203
  5066
                    List<Type> tyargs = enclTy.getTypeArguments();
jfranck@4203
  5067
                    List<JCExpression> trargs = ((JCTypeApply)enclTr).getTypeArguments();
jfranck@4203
  5068
                    if (trargs.length() > 0) {
jfranck@4203
  5069
                        // Nothing to do for diamonds
jfranck@4203
  5070
                        if (tyargs.length() == trargs.length()) {
jfranck@4203
  5071
                            for (int i = 0; i < tyargs.length(); ++i) {
jfranck@4203
  5072
                                validateAnnotatedType(trargs.get(i), tyargs.get(i));
jfranck@4203
  5073
                            }
jfranck@4203
  5074
                        }
jfranck@4203
  5075
                        // If the lengths don't match, it's either a diamond
jfranck@4203
  5076
                        // or some nested type that redundantly provides
jfranck@4203
  5077
                        // type arguments in the tree.
jfranck@4203
  5078
                    }
jfranck@4203
  5079
jfranck@4203
  5080
                    // Look at the clazz part of a generic type
jfranck@4203
  5081
                    enclTr = ((JCTree.JCTypeApply)enclTr).clazz;
jfranck@4203
  5082
                }
jfranck@4203
  5083
jfranck@4203
  5084
                if (enclTr.hasTag(SELECT)) {
jfranck@4203
  5085
                    enclTr = ((JCTree.JCFieldAccess)enclTr).getExpression();
jfranck@4203
  5086
                    if (enclTy != null &&
jfranck@4203
  5087
                            !enclTy.hasTag(NONE)) {
jfranck@4203
  5088
                        enclTy = enclTy.getEnclosingType();
jfranck@4203
  5089
                    }
jfranck@4203
  5090
                } else if (enclTr.hasTag(ANNOTATED_TYPE)) {
jfranck@4203
  5091
                    JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
jfranck@4203
  5092
                    if (enclTy == null || enclTy.hasTag(NONE)) {
jfranck@4203
  5093
                        if (at.getAnnotations().size() == 1) {
jfranck@4203
  5094
                            log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
jfranck@4203
  5095
                        } else {
jfranck@4203
  5096
                            ListBuffer<Attribute.Compound> comps = new ListBuffer<>();
jfranck@4203
  5097
                            for (JCAnnotation an : at.getAnnotations()) {
jfranck@4203
  5098
                                comps.add(an.attribute);
jfranck@4203
  5099
                            }
jfranck@4203
  5100
                            log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList());
jfranck@4203
  5101
                        }
jfranck@4203
  5102
                        repeat = false;
jfranck@4203
  5103
                    }
jfranck@4203
  5104
                    enclTr = at.underlyingType;
jfranck@4203
  5105
                    // enclTy doesn't need to be changed
jfranck@4203
  5106
                } else if (enclTr.hasTag(IDENT)) {
jfranck@4203
  5107
                    repeat = false;
jfranck@4203
  5108
                } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
jfranck@4203
  5109
                    JCWildcard wc = (JCWildcard) enclTr;
jfranck@4203
  5110
                    if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) {
jfranck@4203
  5111
                        validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getExtendsBound());
jfranck@4203
  5112
                    } else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
jfranck@4203
  5113
                        validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getSuperBound());
jfranck@4203
  5114
                    } else {
jfranck@4203
  5115
                        // Nothing to do for UNBOUND
jfranck@4203
  5116
                    }
jfranck@4203
  5117
                    repeat = false;
jfranck@4203
  5118
                } else if (enclTr.hasTag(TYPEARRAY)) {
jfranck@4203
  5119
                    JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
jfranck@4203
  5120
                    validateAnnotatedType(art.getType(), ((ArrayType)enclTy).getComponentType());
jfranck@4203
  5121
                    repeat = false;
jfranck@4203
  5122
                } else if (enclTr.hasTag(TYPEUNION)) {
jfranck@4203
  5123
                    JCTypeUnion ut = (JCTypeUnion) enclTr;
jfranck@4203
  5124
                    for (JCTree t : ut.getTypeAlternatives()) {
jfranck@4203
  5125
                        validateAnnotatedType(t, t.type);
jfranck@4203
  5126
                    }
jfranck@4203
  5127
                    repeat = false;
jfranck@4203
  5128
                } else if (enclTr.hasTag(TYPEINTERSECTION)) {
jfranck@4203
  5129
                    JCTypeIntersection it = (JCTypeIntersection) enclTr;
jfranck@4203
  5130
                    for (JCTree t : it.getBounds()) {
jfranck@4203
  5131
                        validateAnnotatedType(t, t.type);
jfranck@4203
  5132
                    }
jfranck@4203
  5133
                    repeat = false;
jfranck@4203
  5134
                } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE ||
jfranck@4203
  5135
                           enclTr.getKind() == JCTree.Kind.ERRONEOUS) {
jfranck@4203
  5136
                    repeat = false;
jlahoda@3203
  5137
                } else if (enclTr.getKind() == JCTree.Kind.ERRONEOUS) {
jlahoda@3203
  5138
                    repeat = false;
jfranck@4203
  5139
                } else {
jfranck@4203
  5140
                    Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() +
jfranck@4203
  5141
                            " within: "+ errtree + " with kind: " + errtree.getKind());
jfranck@4203
  5142
                }
jfranck@4203
  5143
            }
jfranck@4203
  5144
        }
jfranck@4203
  5145
jfranck@4203
  5146
        private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
jfranck@4203
  5147
                Symbol sym) {
jfranck@4203
  5148
            // Ensure that no declaration annotations are present.
jfranck@4203
  5149
            // Note that a tree type might be an AnnotatedType with
jfranck@4203
  5150
            // empty annotations, if only declaration annotations were given.
jfranck@4203
  5151
            // This method will raise an error for such a type.
jfranck@4203
  5152
            for (JCAnnotation ai : annotations) {
jfranck@4203
  5153
                if (!ai.type.isErroneous() &&
jjg@4454
  5154
                        typeAnnotations.annotationTargetType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
alundblad@4459
  5155
                    log.error(ai.pos(), Errors.AnnotationTypeNotApplicableToType(ai.type));
jfranck@4203
  5156
                }
jfranck@4203
  5157
            }
jfranck@4203
  5158
        }
jfranck@4203
  5159
    }
jfranck@4203
  5160
jlahoda@5
  5161
    public Env<AttrContext> dupLocalEnv(Env<AttrContext> localEnv) {
jlahoda@5
  5162
        return localEnv.dup(localEnv.tree, localEnv.info.dup(localEnv.info.scope.dupUnshared()));
jlahoda@5
  5163
    }
jlahoda@1082
  5164
dbalek@2374
  5165
// <editor-fold desc="post-attribution visitor">
mcimadamore@1079
  5166
mcimadamore@1079
  5167
    /**
mcimadamore@1079
  5168
     * Handle missing types/symbols in an AST. This routine is useful when
mcimadamore@1079
  5169
     * the compiler has encountered some errors (which might have ended up
mcimadamore@1079
  5170
     * terminating attribution abruptly); if the compiler is used in fail-over
mcimadamore@1079
  5171
     * mode (e.g. by an IDE) and the AST contains semantic errors, this routine
mcimadamore@1079
  5172
     * prevents NPE to be progagated during subsequent compilation steps.
mcimadamore@1079
  5173
     */
mcimadamore@2191
  5174
    public void postAttr(JCTree tree) {
mcimadamore@2191
  5175
        new PostAttrAnalyzer().scan(tree);
mcimadamore@1079
  5176
    }
mcimadamore@1079
  5177
mcimadamore@1079
  5178
    class PostAttrAnalyzer extends TreeScanner {
mcimadamore@1079
  5179
mcimadamore@1079
  5180
        private void initTypeIfNeeded(JCTree that) {
mcimadamore@1079
  5181
            if (that.type == null) {
vromero@3836
  5182
                if (that.hasTag(METHODDEF)) {
pgovereau@4007
  5183
                    that.type = dummyMethodType((JCMethodDecl)that);
vromero@3836
  5184
                } else {
vromero@3836
  5185
                    that.type = syms.unknownType;
vromero@3836
  5186
                }
mcimadamore@1079
  5187
            }
mcimadamore@1079
  5188
        }
mcimadamore@1079
  5189
pgovereau@4007
  5190
        /* Construct a dummy method type. If we have a method declaration,
pgovereau@4007
  5191
         * and the declared return type is void, then use that return type
pgovereau@4007
  5192
         * instead of UNKNOWN to avoid spurious error messages in lambda
pgovereau@4007
  5193
         * bodies (see:JDK-8041704).
pgovereau@4007
  5194
         */
pgovereau@4007
  5195
        private Type dummyMethodType(JCMethodDecl md) {
pgovereau@4007
  5196
            Type restype = syms.unknownType;
dbalek@3531
  5197
            if (md != null && md.restype != null && md.restype.hasTag(TYPEIDENT)) {
pgovereau@4007
  5198
                JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype;
pgovereau@4007
  5199
                if (prim.typetag == VOID)
pgovereau@4007
  5200
                    restype = syms.voidType;
pgovereau@4007
  5201
            }
mcimadamore@5586
  5202
            return new MethodType(List.nil(), restype,
mcimadamore@5586
  5203
                                  List.nil(), syms.methodClass);
pgovereau@4007
  5204
        }
vromero@3836
  5205
        private Type dummyMethodType() {
pgovereau@4007
  5206
            return dummyMethodType(null);
vromero@3836
  5207
        }
vromero@3836
  5208
mcimadamore@1079
  5209
        @Override
mcimadamore@1079
  5210
        public void scan(JCTree tree) {
mcimadamore@1079
  5211
            if (tree == null) return;
mcimadamore@1079
  5212
            if (tree instanceof JCExpression) {
mcimadamore@1079
  5213
                initTypeIfNeeded(tree);
mcimadamore@1079
  5214
            }
mcimadamore@1079
  5215
            super.scan(tree);
mcimadamore@1079
  5216
        }
mcimadamore@1079
  5217
mcimadamore@1079
  5218
        @Override
mcimadamore@1079
  5219
        public void visitIdent(JCIdent that) {
mcimadamore@1079
  5220
            if (that.sym == null) {
mcimadamore@1079
  5221
                that.sym = syms.unknownSymbol;
mcimadamore@1079
  5222
            }
mcimadamore@1079
  5223
        }
mcimadamore@1079
  5224
mcimadamore@1079
  5225
        @Override
mcimadamore@1079
  5226
        public void visitSelect(JCFieldAccess that) {
mcimadamore@1079
  5227
            if (that.sym == null) {
mcimadamore@1079
  5228
                that.sym = syms.unknownSymbol;
mcimadamore@1079
  5229
            }
mcimadamore@1079
  5230
            super.visitSelect(that);
mcimadamore@1079
  5231
        }
mcimadamore@1079
  5232
mcimadamore@1079
  5233
        @Override
mcimadamore@1079
  5234
        public void visitClassDef(JCClassDecl that) {
mcimadamore@1079
  5235
            initTypeIfNeeded(that);
mcimadamore@1079
  5236
            if (that.sym == null) {
mcimadamore@1079
  5237
                that.sym = new ClassSymbol(0, that.name, that.type, syms.noSymbol);
mcimadamore@1079
  5238
            }
mcimadamore@1079
  5239
            super.visitClassDef(that);
mcimadamore@1079
  5240
        }
dbalek@3531
  5241
        
dbalek@3531
  5242
        private boolean inMethodParams = false;
mcimadamore@1079
  5243
mcimadamore@1079
  5244
        @Override
mcimadamore@1079
  5245
        public void visitMethodDef(JCMethodDecl that) {
mcimadamore@1079
  5246
            initTypeIfNeeded(that);
mcimadamore@1079
  5247
            if (that.sym == null) {
mcimadamore@1079
  5248
                that.sym = new MethodSymbol(0, that.name, that.type, syms.noSymbol);
mcimadamore@1079
  5249
            }
dbalek@3531
  5250
            scan(that.mods);
dbalek@3531
  5251
            scan(that.restype);
dbalek@3531
  5252
            scan(that.typarams);
dbalek@3531
  5253
            try {
dbalek@3531
  5254
                inMethodParams = true;
dbalek@3531
  5255
                scan(that.recvparam);
dbalek@3531
  5256
                scan(that.params);
dbalek@3531
  5257
            } finally {
dbalek@3531
  5258
                inMethodParams = false;
dbalek@3531
  5259
            }
dbalek@3531
  5260
            scan(that.thrown);
dbalek@3531
  5261
            scan(that.defaultValue);
dbalek@3531
  5262
            scan(that.body);
mcimadamore@1079
  5263
        }
mcimadamore@1079
  5264
mcimadamore@1079
  5265
        @Override
mcimadamore@1079
  5266
        public void visitVarDef(JCVariableDecl that) {
mcimadamore@1079
  5267
            initTypeIfNeeded(that);
mcimadamore@1079
  5268
            if (that.sym == null) {
dbalek@3531
  5269
                that.sym = new VarSymbol(inMethodParams ? Flags.PARAMETER : 0, that.name, that.type, syms.noSymbol);
mcimadamore@1079
  5270
                that.sym.adr = 0;
mcimadamore@1079
  5271
            }
vromero@5800
  5272
            if (that.vartype == null) {
vromero@5800
  5273
                that.vartype = make.Erroneous();
vromero@5800
  5274
            }
mcimadamore@1079
  5275
            super.visitVarDef(that);
mcimadamore@1079
  5276
        }
mcimadamore@1079
  5277
mcimadamore@1079
  5278
        @Override
mcimadamore@1079
  5279
        public void visitNewClass(JCNewClass that) {
mcimadamore@1079
  5280
            if (that.constructor == null) {
vromero@3836
  5281
                that.constructor = new MethodSymbol(0, names.init,
vromero@3836
  5282
                        dummyMethodType(), syms.noSymbol);
mcimadamore@1079
  5283
            }
mcimadamore@1079
  5284
            if (that.constructorType == null) {
mcimadamore@1079
  5285
                that.constructorType = syms.unknownType;
mcimadamore@1079
  5286
            }
mcimadamore@1079
  5287
            super.visitNewClass(that);
mcimadamore@1079
  5288
        }
mcimadamore@1079
  5289
mcimadamore@1079
  5290
        @Override
jjh@1568
  5291
        public void visitAssignop(JCAssignOp that) {
vromero@3836
  5292
            if (that.operator == null) {
vromero@3836
  5293
                that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
vromero@3836
  5294
                        -1, syms.noSymbol);
vromero@3836
  5295
            }
jjh@1568
  5296
            super.visitAssignop(that);
jjh@1568
  5297
        }
jjh@1568
  5298
jjh@1568
  5299
        @Override
mcimadamore@1079
  5300
        public void visitBinary(JCBinary that) {
vromero@3836
  5301
            if (that.operator == null) {
vromero@3836
  5302
                that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
vromero@3836
  5303
                        -1, syms.noSymbol);
vromero@3836
  5304
            }
mcimadamore@1079
  5305
            super.visitBinary(that);
mcimadamore@1079
  5306
        }
mcimadamore@1079
  5307
mcimadamore@1079
  5308
        @Override
mcimadamore@1079
  5309
        public void visitUnary(JCUnary that) {
vromero@3836
  5310
            if (that.operator == null) {
vromero@3836
  5311
                that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
vromero@3836
  5312
                        -1, syms.noSymbol);
vromero@3836
  5313
            }
mcimadamore@1079
  5314
            super.visitUnary(that);
mcimadamore@1079
  5315
        }
mcimadamore@2195
  5316
mcimadamore@2195
  5317
        @Override
mcimadamore@2361
  5318
        public void visitLambda(JCLambda that) {
mcimadamore@2361
  5319
            super.visitLambda(that);
mcimadamore@2361
  5320
            if (that.targets == null) {
mcimadamore@2361
  5321
                that.targets = List.nil();
mcimadamore@2361
  5322
            }
mcimadamore@2361
  5323
        }
mcimadamore@2361
  5324
mcimadamore@2361
  5325
        @Override
mcimadamore@2195
  5326
        public void visitReference(JCMemberReference that) {
mcimadamore@2195
  5327
            super.visitReference(that);
mcimadamore@2195
  5328
            if (that.sym == null) {
vromero@3836
  5329
                that.sym = new MethodSymbol(0, names.empty, dummyMethodType(),
vromero@3836
  5330
                        syms.noSymbol);
mcimadamore@2195
  5331
            }
mcimadamore@2361
  5332
            if (that.targets == null) {
mcimadamore@2361
  5333
                that.targets = List.nil();
mcimadamore@2361
  5334
            }
mcimadamore@2195
  5335
        }
dbalek@2330
  5336
dbalek@2330
  5337
        @Override
dbalek@1254
  5338
        public void visitErroneous(JCErroneous tree) {
dbalek@1254
  5339
            scan(tree.errs);
dbalek@1254
  5340
        }
mcimadamore@1079
  5341
    }
mcimadamore@1079
  5342
    // </editor-fold>
alanb@5016
  5343
alanb@5016
  5344
    public void setPackageSymbols(JCExpression pid, Symbol pkg) {
alanb@5016
  5345
        new TreeScanner() {
alanb@5016
  5346
            Symbol packge = pkg;
alanb@5016
  5347
            @Override
alanb@5016
  5348
            public void visitIdent(JCIdent that) {
alanb@5016
  5349
                that.sym = packge;
alanb@5016
  5350
            }
alanb@5016
  5351
alanb@5016
  5352
            @Override
alanb@5016
  5353
            public void visitSelect(JCFieldAccess that) {
alanb@5016
  5354
                that.sym = packge;
alanb@5016
  5355
                packge = packge.owner;
alanb@5016
  5356
                super.visitSelect(that);
alanb@5016
  5357
            }
alanb@5016
  5358
        }.scan(pid);
alanb@5016
  5359
    }
alanb@5016
  5360
duke@0
  5361
}