langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 29776 984a79b71cfe
parent 29774 9d438163db79
child 29842 826ac2519523
equal deleted inserted replaced
29775:dc7df633fea1 29776:984a79b71cfe
    44 import com.sun.tools.javac.comp.Check.CheckContext;
    44 import com.sun.tools.javac.comp.Check.CheckContext;
    45 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
    45 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
    46 import com.sun.tools.javac.comp.Infer.InferenceContext;
    46 import com.sun.tools.javac.comp.Infer.InferenceContext;
    47 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
    47 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
    48 import com.sun.tools.javac.jvm.*;
    48 import com.sun.tools.javac.jvm.*;
       
    49 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
       
    50 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
       
    51 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs;
       
    52 import com.sun.tools.javac.resources.CompilerProperties.Errors;
    49 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
    53 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
    50 import com.sun.tools.javac.tree.*;
    54 import com.sun.tools.javac.tree.*;
    51 import com.sun.tools.javac.tree.JCTree.*;
    55 import com.sun.tools.javac.tree.JCTree.*;
    52 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
    56 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
    53 import com.sun.tools.javac.util.*;
    57 import com.sun.tools.javac.util.*;
    54 import com.sun.tools.javac.util.DefinedBy.Api;
    58 import com.sun.tools.javac.util.DefinedBy.Api;
    55 import com.sun.tools.javac.util.Dependencies.AttributionKind;
    59 import com.sun.tools.javac.util.Dependencies.AttributionKind;
    56 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    60 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
       
    61 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
    57 import com.sun.tools.javac.util.List;
    62 import com.sun.tools.javac.util.List;
    58 import static com.sun.tools.javac.code.Flags.*;
    63 import static com.sun.tools.javac.code.Flags.*;
    59 import static com.sun.tools.javac.code.Flags.ANNOTATION;
    64 import static com.sun.tools.javac.code.Flags.ANNOTATION;
    60 import static com.sun.tools.javac.code.Flags.BLOCK;
    65 import static com.sun.tools.javac.code.Flags.BLOCK;
    61 import static com.sun.tools.javac.code.Kinds.*;
    66 import static com.sun.tools.javac.code.Kinds.*;
   217      */
   222      */
   218     Type check(final JCTree tree,
   223     Type check(final JCTree tree,
   219                final Type found,
   224                final Type found,
   220                final KindSelector ownkind,
   225                final KindSelector ownkind,
   221                final ResultInfo resultInfo) {
   226                final ResultInfo resultInfo) {
       
   227         return check(tree, found, ownkind, resultInfo, true);
       
   228     }
       
   229     /** Check kind and type of given tree against protokind and prototype.
       
   230      *  If check succeeds, store type in tree and return it.
       
   231      *  If check fails, store errType in tree and return it.
       
   232      *  No checks are performed if the prototype is a method type.
       
   233      *  It is not necessary in this case since we know that kind and type
       
   234      *  are correct.
       
   235      *
       
   236      *  @param tree     The tree whose kind and type is checked
       
   237      *  @param found    The computed type of the tree
       
   238      *  @param ownkind  The computed kind of the tree
       
   239      *  @param resultInfo  The expected result of the tree
       
   240      *  @param recheckPostInference If true and inference is underway, arrange to recheck the tree after inference finishes.
       
   241      */
       
   242     Type check(final JCTree tree,
       
   243                final Type found,
       
   244                final KindSelector ownkind,
       
   245                final ResultInfo resultInfo,
       
   246                boolean recheckPostInference) {
   222         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
   247         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
   223         Type owntype;
   248         Type owntype;
   224         boolean shouldCheck = !found.hasTag(ERROR) &&
   249         boolean shouldCheck = !found.hasTag(ERROR) &&
   225                 !resultInfo.pt.hasTag(METHOD) &&
   250                 !resultInfo.pt.hasTag(METHOD) &&
   226                 !resultInfo.pt.hasTag(FORALL);
   251                 !resultInfo.pt.hasTag(FORALL);
   231             owntype = types.createErrorType(found);
   256             owntype = types.createErrorType(found);
   232         } else if (allowPoly && inferenceContext.free(found)) {
   257         } else if (allowPoly && inferenceContext.free(found)) {
   233             //delay the check if there are inference variables in the found type
   258             //delay the check if there are inference variables in the found type
   234             //this means we are dealing with a partially inferred poly expression
   259             //this means we are dealing with a partially inferred poly expression
   235             owntype = shouldCheck ? resultInfo.pt : found;
   260             owntype = shouldCheck ? resultInfo.pt : found;
   236             inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt),
   261             if (recheckPostInference) {
   237                     instantiatedContext -> {
   262                 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt),
   238                         ResultInfo pendingResult =
   263                         instantiatedContext -> {
   239                                 resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
   264                             ResultInfo pendingResult =
   240                         check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
   265                                     resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
   241                     });
   266                             check(tree, inferenceContext.asInstType(found), ownkind, pendingResult, false);
       
   267                         });
       
   268             }
   242         } else {
   269         } else {
   243             owntype = shouldCheck ?
   270             owntype = shouldCheck ?
   244             resultInfo.check(tree, found) :
   271             resultInfo.check(tree, found) :
   245             found;
   272             found;
   246         }
   273         }
   860             if (m.isStatic()) {
   887             if (m.isStatic()) {
   861                 chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
   888                 chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
   862             } else {
   889             } else {
   863                 chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
   890                 chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
   864             }
   891             }
   865             chk.checkOverride(tree, m);
   892             chk.checkOverride(env, tree, m);
   866 
   893 
   867             if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) {
   894             if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) {
   868                 log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
   895                 log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
   869             }
   896             }
   870 
   897 
  1967             if ((clazztype.tsym.flags_field & Flags.ENUM) != 0 &&
  1994             if ((clazztype.tsym.flags_field & Flags.ENUM) != 0 &&
  1968                 (!env.tree.hasTag(VARDEF) ||
  1995                 (!env.tree.hasTag(VARDEF) ||
  1969                  (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 ||
  1996                  (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 ||
  1970                  ((JCVariableDecl) env.tree).init != tree))
  1997                  ((JCVariableDecl) env.tree).init != tree))
  1971                 log.error(tree.pos(), "enum.cant.be.instantiated");
  1998                 log.error(tree.pos(), "enum.cant.be.instantiated");
       
  1999 
       
  2000             boolean isSpeculativeDiamondInferenceRound = TreeInfo.isDiamond(tree) &&
       
  2001                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
       
  2002             boolean skipNonDiamondPath = false;
  1972             // Check that class is not abstract
  2003             // Check that class is not abstract
  1973             if (cdef == null &&
  2004             if (cdef == null && !isSpeculativeDiamondInferenceRound && // class body may be nulled out in speculative tree copy
  1974                 (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
  2005                 (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
  1975                 log.error(tree.pos(), "abstract.cant.be.instantiated",
  2006                 log.error(tree.pos(), "abstract.cant.be.instantiated",
  1976                           clazztype.tsym);
  2007                           clazztype.tsym);
       
  2008                 skipNonDiamondPath = true;
  1977             } else if (cdef != null && clazztype.tsym.isInterface()) {
  2009             } else if (cdef != null && clazztype.tsym.isInterface()) {
  1978                 // Check that no constructor arguments are given to
  2010                 // Check that no constructor arguments are given to
  1979                 // anonymous classes implementing an interface
  2011                 // anonymous classes implementing an interface
  1980                 if (!argtypes.isEmpty())
  2012                 if (!argtypes.isEmpty())
  1981                     log.error(tree.args.head.pos(), "anon.class.impl.intf.no.args");
  2013                     log.error(tree.args.head.pos(), "anon.class.impl.intf.no.args");
  1984                     log.error(tree.typeargs.head.pos(), "anon.class.impl.intf.no.typeargs");
  2016                     log.error(tree.typeargs.head.pos(), "anon.class.impl.intf.no.typeargs");
  1985 
  2017 
  1986                 // Error recovery: pretend no arguments were supplied.
  2018                 // Error recovery: pretend no arguments were supplied.
  1987                 argtypes = List.nil();
  2019                 argtypes = List.nil();
  1988                 typeargtypes = List.nil();
  2020                 typeargtypes = List.nil();
  1989             } else if (TreeInfo.isDiamond(tree)) {
  2021                 skipNonDiamondPath = true;
       
  2022             }
       
  2023             if (TreeInfo.isDiamond(tree)) {
  1990                 ClassType site = new ClassType(clazztype.getEnclosingType(),
  2024                 ClassType site = new ClassType(clazztype.getEnclosingType(),
  1991                             clazztype.tsym.type.getTypeArguments(),
  2025                             clazztype.tsym.type.getTypeArguments(),
  1992                                                clazztype.tsym,
  2026                                                clazztype.tsym,
  1993                                                clazztype.getMetadata());
  2027                                                clazztype.getMetadata());
  1994 
  2028 
  2020                         diamondEnv,
  2054                         diamondEnv,
  2021                         diamondResult);
  2055                         diamondResult);
  2022 
  2056 
  2023                 tree.clazz.type = types.createErrorType(clazztype);
  2057                 tree.clazz.type = types.createErrorType(clazztype);
  2024                 if (!constructorType.isErroneous()) {
  2058                 if (!constructorType.isErroneous()) {
  2025                     tree.clazz.type = clazztype = constructorType.getReturnType();
  2059                     tree.clazz.type = clazz.type = constructorType.getReturnType();
  2026                     tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
  2060                     tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
  2027                 }
  2061                 }
  2028                 clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
  2062                 clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
  2029             }
  2063             }
  2030 
  2064 
  2031             // Resolve the called constructor under the assumption
  2065             // Resolve the called constructor under the assumption
  2032             // that we are referring to a superclass instance of the
  2066             // that we are referring to a superclass instance of the
  2033             // current instance (JLS ???).
  2067             // current instance (JLS ???).
  2034             else {
  2068             else if (!skipNonDiamondPath) {
  2035                 //the following code alters some of the fields in the current
  2069                 //the following code alters some of the fields in the current
  2036                 //AttrContext - hence, the current context must be dup'ed in
  2070                 //AttrContext - hence, the current context must be dup'ed in
  2037                 //order to avoid downstream failures
  2071                 //order to avoid downstream failures
  2038                 Env<AttrContext> rsEnv = localEnv.dup(tree);
  2072                 Env<AttrContext> rsEnv = localEnv.dup(tree);
  2039                 rsEnv.info.selectSuper = cdef != null;
  2073                 rsEnv.info.selectSuper = cdef != null;
  2050                         Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
  2084                         Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
  2051                 }
  2085                 }
  2052             }
  2086             }
  2053 
  2087 
  2054             if (cdef != null) {
  2088             if (cdef != null) {
  2055                 // We are seeing an anonymous class instance creation.
  2089                 visitAnonymousClassDefinition(tree, clazz, clazztype, cdef, localEnv, argtypes, typeargtypes, pkind);
  2056                 // In this case, the class instance creation
  2090                 return;
  2057                 // expression
       
  2058                 //
       
  2059                 //    E.new <typeargs1>C<typargs2>(args) { ... }
       
  2060                 //
       
  2061                 // is represented internally as
       
  2062                 //
       
  2063                 //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
       
  2064                 //
       
  2065                 // This expression is then *transformed* as follows:
       
  2066                 //
       
  2067                 // (1) add an extends or implements clause
       
  2068                 // (2) add a constructor.
       
  2069                 //
       
  2070                 // For instance, if C is a class, and ET is the type of E,
       
  2071                 // the expression
       
  2072                 //
       
  2073                 //    E.new <typeargs1>C<typargs2>(args) { ... }
       
  2074                 //
       
  2075                 // is translated to (where X is a fresh name and typarams is the
       
  2076                 // parameter list of the super constructor):
       
  2077                 //
       
  2078                 //   new <typeargs1>X(<*nullchk*>E, args) where
       
  2079                 //     X extends C<typargs2> {
       
  2080                 //       <typarams> X(ET e, args) {
       
  2081                 //         e.<typeargs1>super(args)
       
  2082                 //       }
       
  2083                 //       ...
       
  2084                 //     }
       
  2085 
       
  2086                 if (clazztype.tsym.isInterface()) {
       
  2087                     cdef.implementing = List.of(clazz);
       
  2088                 } else {
       
  2089                     cdef.extending = clazz;
       
  2090                 }
       
  2091 
       
  2092                 if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
       
  2093                     isSerializable(clazztype)) {
       
  2094                     localEnv.info.isSerializable = true;
       
  2095                 }
       
  2096 
       
  2097                 attribStat(cdef, localEnv);
       
  2098 
       
  2099                 // If an outer instance is given,
       
  2100                 // prefix it to the constructor arguments
       
  2101                 // and delete it from the new expression
       
  2102                 if (tree.encl != null && !clazztype.tsym.isInterface()) {
       
  2103                     tree.args = tree.args.prepend(makeNullCheck(tree.encl));
       
  2104                     argtypes = argtypes.prepend(tree.encl.type);
       
  2105                     tree.encl = null;
       
  2106                 }
       
  2107 
       
  2108                 // Reassign clazztype and recompute constructor.
       
  2109                 clazztype = cdef.sym.type;
       
  2110                 Symbol sym = tree.constructor = rs.resolveConstructor(
       
  2111                     tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
       
  2112                 Assert.check(!sym.kind.isResolutionError());
       
  2113                 tree.constructor = sym;
       
  2114                 tree.constructorType = checkId(noCheckTree,
       
  2115                     clazztype,
       
  2116                     tree.constructor,
       
  2117                     localEnv,
       
  2118                     new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
       
  2119             }
  2091             }
  2120 
  2092 
  2121             if (tree.constructor != null && tree.constructor.kind == MTH)
  2093             if (tree.constructor != null && tree.constructor.kind == MTH)
  2122                 owntype = clazztype;
  2094                 owntype = clazztype;
  2123         }
  2095         }
  2130                         tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
  2102                         tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
  2131                     });
  2103                     });
  2132         }
  2104         }
  2133         chk.validate(tree.typeargs, localEnv);
  2105         chk.validate(tree.typeargs, localEnv);
  2134     }
  2106     }
       
  2107 
       
  2108         // where
       
  2109         private void visitAnonymousClassDefinition(JCNewClass tree, JCExpression clazz, Type clazztype,
       
  2110                                                    JCClassDecl cdef, Env<AttrContext> localEnv,
       
  2111                                                    List<Type> argtypes, List<Type> typeargtypes,
       
  2112                                                    KindSelector pkind) {
       
  2113             // We are seeing an anonymous class instance creation.
       
  2114             // In this case, the class instance creation
       
  2115             // expression
       
  2116             //
       
  2117             //    E.new <typeargs1>C<typargs2>(args) { ... }
       
  2118             //
       
  2119             // is represented internally as
       
  2120             //
       
  2121             //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
       
  2122             //
       
  2123             // This expression is then *transformed* as follows:
       
  2124             //
       
  2125             // (1) add an extends or implements clause
       
  2126             // (2) add a constructor.
       
  2127             //
       
  2128             // For instance, if C is a class, and ET is the type of E,
       
  2129             // the expression
       
  2130             //
       
  2131             //    E.new <typeargs1>C<typargs2>(args) { ... }
       
  2132             //
       
  2133             // is translated to (where X is a fresh name and typarams is the
       
  2134             // parameter list of the super constructor):
       
  2135             //
       
  2136             //   new <typeargs1>X(<*nullchk*>E, args) where
       
  2137             //     X extends C<typargs2> {
       
  2138             //       <typarams> X(ET e, args) {
       
  2139             //         e.<typeargs1>super(args)
       
  2140             //       }
       
  2141             //       ...
       
  2142             //     }
       
  2143             InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
       
  2144             final boolean isDiamond = TreeInfo.isDiamond(tree);
       
  2145             if (isDiamond
       
  2146                     && ((tree.constructorType != null && inferenceContext.free(tree.constructorType))
       
  2147                     || (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) {
       
  2148                 inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type),
       
  2149                         instantiatedContext -> {
       
  2150                             tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
       
  2151                             clazz.type = instantiatedContext.asInstType(clazz.type);
       
  2152                             visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef, localEnv, argtypes, typeargtypes, pkind);
       
  2153                         });
       
  2154             } else {
       
  2155                 if (isDiamond && clazztype.hasTag(CLASS)) {
       
  2156                     List<Type> invalidDiamondArgs = chk.checkDiamondDenotable((ClassType)clazztype);
       
  2157                     if (!clazztype.isErroneous() && invalidDiamondArgs.nonEmpty()) {
       
  2158                         // One or more types inferred in the previous steps is non-denotable.
       
  2159                         Fragment fragment = Diamond(clazztype.tsym);
       
  2160                         log.error(tree.clazz.pos(),
       
  2161                                 Errors.CantApplyDiamond1(
       
  2162                                         fragment,
       
  2163                                         invalidDiamondArgs.size() > 1 ?
       
  2164                                                 DiamondInvalidArgs(invalidDiamondArgs, fragment) :
       
  2165                                                 DiamondInvalidArg(invalidDiamondArgs, fragment)));
       
  2166                     }
       
  2167                     // For <>(){}, inferred types must also be accessible.
       
  2168                     for (Type t : clazztype.getTypeArguments()) {
       
  2169                         rs.checkAccessibleType(env, t);
       
  2170                     }
       
  2171                 }
       
  2172 
       
  2173                 // If we already errored, be careful to avoid a further avalanche. ErrorType answers
       
  2174                 // false for isInterface call even when the original type is an interface.
       
  2175                 boolean implementing = clazztype.tsym.isInterface() ||
       
  2176                         clazztype.isErroneous() && clazztype.getOriginalType().tsym.isInterface();
       
  2177 
       
  2178                 if (implementing) {
       
  2179                     cdef.implementing = List.of(clazz);
       
  2180                 } else {
       
  2181                     cdef.extending = clazz;
       
  2182                 }
       
  2183 
       
  2184                 if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
       
  2185                     isSerializable(clazztype)) {
       
  2186                     localEnv.info.isSerializable = true;
       
  2187                 }
       
  2188 
       
  2189                 attribStat(cdef, localEnv);
       
  2190 
       
  2191                 List<Type> finalargtypes;
       
  2192                 // If an outer instance is given,
       
  2193                 // prefix it to the constructor arguments
       
  2194                 // and delete it from the new expression
       
  2195                 if (tree.encl != null && !clazztype.tsym.isInterface()) {
       
  2196                     tree.args = tree.args.prepend(makeNullCheck(tree.encl));
       
  2197                     finalargtypes = argtypes.prepend(tree.encl.type);
       
  2198                     tree.encl = null;
       
  2199                 } else {
       
  2200                     finalargtypes = argtypes;
       
  2201                 }
       
  2202 
       
  2203                 // Reassign clazztype and recompute constructor. As this necessarily involves
       
  2204                 // another attribution pass for deferred types in the case of <>, replicate
       
  2205                 // them. Original arguments have right decorations already.
       
  2206                 if (isDiamond && pkind.contains(KindSelector.POLY)) {
       
  2207                     finalargtypes = finalargtypes.map(deferredAttr.deferredCopier);
       
  2208                 }
       
  2209 
       
  2210                 clazztype = cdef.sym.type;
       
  2211                 Symbol sym = tree.constructor = rs.resolveConstructor(
       
  2212                         tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes);
       
  2213                 Assert.check(!sym.kind.isResolutionError());
       
  2214                 tree.constructor = sym;
       
  2215                 tree.constructorType = checkId(noCheckTree,
       
  2216                         clazztype,
       
  2217                         tree.constructor,
       
  2218                         localEnv,
       
  2219                         new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes)));
       
  2220             }
       
  2221             Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ?
       
  2222                                 clazztype : types.createErrorType(tree.type);
       
  2223             result = check(tree, owntype, KindSelector.VAL, resultInfo, false);
       
  2224             chk.validate(tree.typeargs, localEnv);
       
  2225         }
  2135 
  2226 
  2136     /** Make an attributed null check tree.
  2227     /** Make an attributed null check tree.
  2137      */
  2228      */
  2138     public JCExpression makeNullCheck(JCExpression arg) {
  2229     public JCExpression makeNullCheck(JCExpression arg) {
  2139         // optimization: X.this is never null; skip null check
  2230         // optimization: X.this is never null; skip null check