1 /* 2 * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.comp; 27 28 import com.sun.tools.javac.api.Formattable.LocalizedString; 29 import com.sun.tools.javac.code.*; 30 import com.sun.tools.javac.code.Scope.WriteableScope; 31 import com.sun.tools.javac.code.Source.Feature; 32 import com.sun.tools.javac.code.Symbol.*; 33 import com.sun.tools.javac.code.Type.*; 34 import com.sun.tools.javac.comp.Attr.ResultInfo; 35 import com.sun.tools.javac.comp.Check.CheckContext; 36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; 38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType; 39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; 40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template; 41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind; 42 import com.sun.tools.javac.jvm.*; 43 import com.sun.tools.javac.main.Option; 44 import com.sun.tools.javac.resources.CompilerProperties.Errors; 45 import com.sun.tools.javac.resources.CompilerProperties.Fragments; 46 import com.sun.tools.javac.resources.CompilerProperties.Warnings; 47 import com.sun.tools.javac.tree.*; 48 import com.sun.tools.javac.tree.JCTree.*; 49 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; 50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; 51 import com.sun.tools.javac.util.*; 52 import com.sun.tools.javac.util.DefinedBy.Api; 53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 56 57 import java.util.Arrays; 58 import java.util.Collection; 59 import java.util.EnumSet; 60 import java.util.HashSet; 61 import java.util.Iterator; 62 import java.util.LinkedHashMap; 63 import java.util.Map; 64 import java.util.Set; 65 import java.util.function.BiFunction; 66 import java.util.function.BiPredicate; 67 import java.util.function.Function; 68 import java.util.function.Predicate; 69 import java.util.function.UnaryOperator; 70 import java.util.stream.Stream; 71 import java.util.stream.StreamSupport; 72 73 import javax.lang.model.element.ElementVisitor; 74 75 import static com.sun.tools.javac.code.Flags.*; 76 import static com.sun.tools.javac.code.Flags.BLOCK; 77 import static com.sun.tools.javac.code.Flags.STATIC; 78 import static com.sun.tools.javac.code.Kinds.*; 79 import static com.sun.tools.javac.code.Kinds.Kind.*; 80 import static com.sun.tools.javac.code.TypeTag.*; 81 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; 82 import static com.sun.tools.javac.main.Option.DOE; 83 import static com.sun.tools.javac.tree.JCTree.Tag.*; 84 import static com.sun.tools.javac.util.Iterators.createCompoundIterator; 85 86 /** Helper class for name resolution, used mostly by the attribution phase. 87 * 88 * <p><b>This is NOT part of any supported API. 89 * If you write code that depends on this, you do so at your own risk. 90 * This code and its internal interfaces are subject to change or 91 * deletion without notice.</b> 92 */ 93 public class Resolve { 94 protected static final Context.Key<Resolve> resolveKey = new Context.Key<>(); 95 96 Names names; 97 Log log; 98 Symtab syms; 99 Attr attr; 100 AttrRecover attrRecover; 101 DeferredAttr deferredAttr; 102 Check chk; 103 Infer infer; 104 Preview preview; 105 ClassFinder finder; 106 ModuleFinder moduleFinder; 107 Types types; 108 JCDiagnostic.Factory diags; 109 public final boolean allowModules; 110 public final boolean allowRecords; 111 private final boolean compactMethodDiags; 112 private final boolean allowLocalVariableTypeInference; 113 private final boolean allowYieldStatement; 114 private final boolean allowPrivateMembersInPermitsClause; 115 final EnumSet<VerboseResolutionMode> verboseResolutionMode; 116 final boolean dumpMethodReferenceSearchResults; 117 final boolean dumpStacktraceOnError; 118 119 WriteableScope polymorphicSignatureScope; 120 121 @SuppressWarnings("this-escape") 122 protected Resolve(Context context) { 123 context.put(resolveKey, this); 124 syms = Symtab.instance(context); 125 126 varNotFound = new SymbolNotFoundError(ABSENT_VAR); 127 methodNotFound = new SymbolNotFoundError(ABSENT_MTH); 128 typeNotFound = new SymbolNotFoundError(ABSENT_TYP); 129 referenceNotFound = ReferenceLookupResult.error(methodNotFound); 130 131 names = Names.instance(context); 132 log = Log.instance(context); 133 attr = Attr.instance(context); 134 attrRecover = AttrRecover.instance(context); 135 deferredAttr = DeferredAttr.instance(context); 136 chk = Check.instance(context); 137 infer = Infer.instance(context); 138 finder = ClassFinder.instance(context); 139 moduleFinder = ModuleFinder.instance(context); 140 types = Types.instance(context); 141 diags = JCDiagnostic.Factory.instance(context); 142 preview = Preview.instance(context); 143 Source source = Source.instance(context); 144 Options options = Options.instance(context); 145 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") || 146 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics"); 147 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); 148 Target target = Target.instance(context); 149 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source); 150 allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source); 151 allowPrivateMembersInPermitsClause = Feature.PRIVATE_MEMBERS_IN_PERMITS_CLAUSE.allowedInSource(source); 152 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol); 153 allowModules = Feature.MODULES.allowedInSource(source); 154 allowRecords = Feature.RECORDS.allowedInSource(source); 155 dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults"); 156 dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE); 157 } 158 159 /** error symbols, which are returned when resolution fails 160 */ 161 private final SymbolNotFoundError varNotFound; 162 private final SymbolNotFoundError methodNotFound; 163 private final SymbolNotFoundError typeNotFound; 164 165 /** empty reference lookup result */ 166 private final ReferenceLookupResult referenceNotFound; 167 168 public static Resolve instance(Context context) { 169 Resolve instance = context.get(resolveKey); 170 if (instance == null) 171 instance = new Resolve(context); 172 return instance; 173 } 174 175 private static Symbol bestOf(Symbol s1, 176 Symbol s2) { 177 return s1.kind.betterThan(s2.kind) ? s1 : s2; 178 } 179 180 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support"> 181 enum VerboseResolutionMode { 182 SUCCESS("success"), 183 FAILURE("failure"), 184 APPLICABLE("applicable"), 185 INAPPLICABLE("inapplicable"), 186 DEFERRED_INST("deferred-inference"), 187 PREDEF("predef"), 188 OBJECT_INIT("object-init"), 189 INTERNAL("internal"); 190 191 final String opt; 192 193 private VerboseResolutionMode(String opt) { 194 this.opt = opt; 195 } 196 197 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) { 198 String s = opts.get("debug.verboseResolution"); 199 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class); 200 if (s == null) return res; 201 if (s.contains("all")) { 202 res = EnumSet.allOf(VerboseResolutionMode.class); 203 } 204 Collection<String> args = Arrays.asList(s.split(",")); 205 for (VerboseResolutionMode mode : values()) { 206 if (args.contains(mode.opt)) { 207 res.add(mode); 208 } else if (args.contains("-" + mode.opt)) { 209 res.remove(mode); 210 } 211 } 212 return res; 213 } 214 } 215 216 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, 217 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) { 218 boolean success = !bestSoFar.kind.isResolutionError(); 219 220 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { 221 return; 222 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { 223 return; 224 } 225 226 if (bestSoFar.name == names.init && 227 bestSoFar.owner == syms.objectType.tsym && 228 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { 229 return; //skip diags for Object constructor resolution 230 } else if (site == syms.predefClass.type && 231 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { 232 return; //skip spurious diags for predef symbols (i.e. operators) 233 } else if (currentResolutionContext.internalResolution && 234 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { 235 return; 236 } 237 238 int pos = 0; 239 int mostSpecificPos = -1; 240 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>(); 241 for (Candidate c : currentResolutionContext.candidates) { 242 if (currentResolutionContext.step != c.step || 243 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || 244 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) { 245 continue; 246 } else { 247 subDiags.append(c.isApplicable() ? 248 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) : 249 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details)); 250 if (c.sym == bestSoFar) 251 mostSpecificPos = pos; 252 pos++; 253 } 254 } 255 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; 256 List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step)); 257 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, 258 site.tsym, mostSpecificPos, currentResolutionContext.step, 259 methodArguments(argtypes2), 260 methodArguments(typeargtypes)); 261 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); 262 log.report(d); 263 } 264 265 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) { 266 JCDiagnostic subDiag = null; 267 if (sym.type.hasTag(FORALL)) { 268 subDiag = diags.fragment(Fragments.PartialInstSig(inst)); 269 } 270 271 String key = subDiag == null ? 272 "applicable.method.found" : 273 "applicable.method.found.1"; 274 275 return diags.fragment(key, pos, sym, subDiag); 276 } 277 278 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) { 279 return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag)); 280 } 281 // </editor-fold> 282 283 /* ************************************************************************ 284 * Identifier resolution 285 *************************************************************************/ 286 287 /** An environment is "static" if its static level is greater than 288 * the one of its outer environment 289 */ 290 protected static boolean isStatic(Env<AttrContext> env) { 291 return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel; 292 } 293 294 /** An environment is an "initializer" if it is a constructor or 295 * an instance initializer. 296 */ 297 static boolean isInitializer(Env<AttrContext> env) { 298 Symbol owner = env.info.scope.owner; 299 return owner.isConstructor() || 300 owner.owner.kind == TYP && 301 (owner.kind == VAR || 302 owner.kind == MTH && (owner.flags() & BLOCK) != 0) && 303 (owner.flags() & STATIC) == 0; 304 } 305 306 /** Is class accessible in given environment? 307 * @param env The current environment. 308 * @param c The class whose accessibility is checked. 309 */ 310 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) { 311 return isAccessible(env, c, false); 312 } 313 314 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) { 315 316 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor 317 to refer to an inaccessible type 318 */ 319 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0) 320 return true; 321 322 if (env.info.visitingServiceImplementation && 323 env.toplevel.modle == c.packge().modle) { 324 return true; 325 } 326 327 boolean isAccessible = false; 328 switch ((short)(c.flags() & AccessFlags)) { 329 case PRIVATE: 330 isAccessible = 331 env.enclClass.sym.outermostClass() == 332 c.owner.outermostClass(); 333 break; 334 case 0: 335 isAccessible = 336 env.toplevel.packge == c.owner // fast special case 337 || 338 env.toplevel.packge == c.packge(); 339 break; 340 default: // error recovery 341 isAccessible = true; 342 break; 343 case PUBLIC: 344 if (allowModules) { 345 ModuleSymbol currModule = env.toplevel.modle; 346 currModule.complete(); 347 PackageSymbol p = c.packge(); 348 isAccessible = 349 currModule == p.modle || 350 currModule.visiblePackages.get(p.fullname) == p || 351 p == syms.rootPackage || 352 (p.modle == syms.unnamedModule && currModule.readModules.contains(p.modle)); 353 } else { 354 isAccessible = true; 355 } 356 break; 357 case PROTECTED: 358 isAccessible = 359 env.toplevel.packge == c.owner // fast special case 360 || 361 env.toplevel.packge == c.packge() 362 || 363 isInnerSubClass(env.enclClass.sym, c.owner) 364 || 365 env.info.allowProtectedAccess; 366 break; 367 } 368 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ? 369 isAccessible : 370 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner); 371 } 372 //where 373 /** Is given class a subclass of given base class, or an inner class 374 * of a subclass? 375 * Return null if no such class exists. 376 * @param c The class which is the subclass or is contained in it. 377 * @param base The base class 378 */ 379 private boolean isInnerSubClass(ClassSymbol c, Symbol base) { 380 while (c != null && !c.isSubClass(base, types)) { 381 c = c.owner.enclClass(); 382 } 383 return c != null; 384 } 385 386 boolean isAccessible(Env<AttrContext> env, Type t) { 387 return isAccessible(env, t, false); 388 } 389 390 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { 391 if (t.hasTag(ARRAY)) { 392 return isAccessible(env, types.cvarUpperBound(types.elemtype(t))); 393 } else if (t.isUnion()) { 394 return StreamSupport.stream(((UnionClassType) t).getAlternativeTypes().spliterator(), false) 395 .allMatch(alternative -> isAccessible(env, alternative.tsym, checkInner)); 396 } else { 397 return isAccessible(env, t.tsym, checkInner); 398 } 399 } 400 401 /** Is symbol accessible as a member of given type in given environment? 402 * @param env The current environment. 403 * @param site The type of which the tested symbol is regarded 404 * as a member. 405 * @param sym The symbol. 406 */ 407 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) { 408 return isAccessible(env, site, sym, false); 409 } 410 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) { 411 if (sym.name == names.init && sym.owner != site.tsym) return false; 412 413 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor 414 to refer to an inaccessible type 415 */ 416 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0) 417 return true; 418 419 if (env.info.visitingServiceImplementation && 420 env.toplevel.modle == sym.packge().modle) { 421 return true; 422 } 423 424 switch ((short)(sym.flags() & AccessFlags)) { 425 case PRIVATE: 426 return 427 (env.enclClass.sym == sym.owner // fast special case 428 || 429 env.enclClass.sym.outermostClass() == 430 sym.owner.outermostClass() 431 || 432 privateMemberInPermitsClauseIfAllowed(env, sym)) 433 && 434 sym.isInheritedIn(site.tsym, types); 435 case 0: 436 return 437 (env.toplevel.packge == sym.owner.owner // fast special case 438 || 439 env.toplevel.packge == sym.packge()) 440 && 441 isAccessible(env, site, checkInner) 442 && 443 sym.isInheritedIn(site.tsym, types) 444 && 445 notOverriddenIn(site, sym); 446 case PROTECTED: 447 return 448 (env.toplevel.packge == sym.owner.owner // fast special case 449 || 450 env.toplevel.packge == sym.packge() 451 || 452 isProtectedAccessible(sym, env.enclClass.sym, site) 453 || 454 // OK to select instance method or field from 'super' or type name 455 // (but type names should be disallowed elsewhere!) 456 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) 457 && 458 isAccessible(env, site, checkInner) 459 && 460 notOverriddenIn(site, sym); 461 default: // this case includes erroneous combinations as well 462 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym); 463 } 464 } 465 466 private boolean privateMemberInPermitsClauseIfAllowed(Env<AttrContext> env, Symbol sym) { 467 return allowPrivateMembersInPermitsClause && 468 env.info.isPermitsClause && 469 ((JCClassDecl) env.tree).sym.outermostClass() == sym.owner.outermostClass(); 470 } 471 472 //where 473 /* `sym' is accessible only if not overridden by 474 * another symbol which is a member of `site' 475 * (because, if it is overridden, `sym' is not strictly 476 * speaking a member of `site'). A polymorphic signature method 477 * cannot be overridden (e.g. MH.invokeExact(Object[])). 478 */ 479 private boolean notOverriddenIn(Type site, Symbol sym) { 480 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) 481 return true; 482 else { 483 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 484 return (s2 == null || s2 == sym || sym.owner == s2.owner || (sym.owner.isInterface() && s2.owner == syms.objectType.tsym) || 485 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); 486 } 487 } 488 //where 489 /** Is given protected symbol accessible if it is selected from given site 490 * and the selection takes place in given class? 491 * @param sym The symbol with protected access 492 * @param c The class where the access takes place 493 * @param site The type of the qualifier 494 */ 495 private 496 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { 497 Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site; 498 while (c != null && 499 !(c.isSubClass(sym.owner, types) && 500 (c.flags() & INTERFACE) == 0 && 501 // In JLS 2e 6.6.2.1, the subclass restriction applies 502 // only to instance fields and methods -- types are excluded 503 // regardless of whether they are declared 'static' or not. 504 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types)))) 505 c = c.owner.enclClass(); 506 return c != null; 507 } 508 509 /** 510 * Performs a recursive scan of a type looking for accessibility problems 511 * from current attribution environment 512 */ 513 void checkAccessibleType(Env<AttrContext> env, Type t) { 514 accessibilityChecker.visit(t, env); 515 } 516 517 /** 518 * Accessibility type-visitor 519 */ 520 Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker = 521 new Types.SimpleVisitor<Void, Env<AttrContext>>() { 522 523 void visit(List<Type> ts, Env<AttrContext> env) { 524 for (Type t : ts) { 525 visit(t, env); 526 } 527 } 528 529 public Void visitType(Type t, Env<AttrContext> env) { 530 return null; 531 } 532 533 @Override 534 public Void visitArrayType(ArrayType t, Env<AttrContext> env) { 535 visit(t.elemtype, env); 536 return null; 537 } 538 539 @Override 540 public Void visitClassType(ClassType t, Env<AttrContext> env) { 541 visit(t.getTypeArguments(), env); 542 if (!isAccessible(env, t, true)) { 543 accessBase(new AccessError(env, null, t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true); 544 } 545 return null; 546 } 547 548 @Override 549 public Void visitWildcardType(WildcardType t, Env<AttrContext> env) { 550 visit(t.type, env); 551 return null; 552 } 553 554 @Override 555 public Void visitMethodType(MethodType t, Env<AttrContext> env) { 556 visit(t.getParameterTypes(), env); 557 visit(t.getReturnType(), env); 558 visit(t.getThrownTypes(), env); 559 return null; 560 } 561 }; 562 563 /** Try to instantiate the type of a method so that it fits 564 * given type arguments and argument types. If successful, return 565 * the method's instantiated type, else return null. 566 * The instantiation will take into account an additional leading 567 * formal parameter if the method is an instance method seen as a member 568 * of an under determined site. In this case, we treat site as an additional 569 * parameter and the parameters of the class containing the method as 570 * additional type variables that get instantiated. 571 * 572 * @param env The current environment 573 * @param site The type of which the method is a member. 574 * @param m The method symbol. 575 * @param argtypes The invocation's given value arguments. 576 * @param typeargtypes The invocation's given type arguments. 577 * @param allowBoxing Allow boxing conversions of arguments. 578 * @param useVarargs Box trailing arguments into an array for varargs. 579 */ 580 Type rawInstantiate(Env<AttrContext> env, 581 Type site, 582 Symbol m, 583 ResultInfo resultInfo, 584 List<Type> argtypes, 585 List<Type> typeargtypes, 586 boolean allowBoxing, 587 boolean useVarargs, 588 Warner warn) throws Infer.InferenceException { 589 Type mt = types.memberType(site, m); 590 // tvars is the list of formal type variables for which type arguments 591 // need to inferred. 592 List<Type> tvars = List.nil(); 593 if (typeargtypes == null) typeargtypes = List.nil(); 594 if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) { 595 // This is not a polymorphic method, but typeargs are supplied 596 // which is fine, see JLS 15.12.2.1 597 } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) { 598 ForAll pmt = (ForAll) mt; 599 if (typeargtypes.length() != pmt.tvars.length()) 600 // not enough args 601 throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length()))), dumpStacktraceOnError); 602 // Check type arguments are within bounds 603 List<Type> formals = pmt.tvars; 604 List<Type> actuals = typeargtypes; 605 while (formals.nonEmpty() && actuals.nonEmpty()) { 606 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head), 607 pmt.tvars, typeargtypes); 608 for (; bounds.nonEmpty(); bounds = bounds.tail) { 609 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) { 610 throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds)), dumpStacktraceOnError); 611 } 612 } 613 formals = formals.tail; 614 actuals = actuals.tail; 615 } 616 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes); 617 } else if (mt.hasTag(FORALL)) { 618 ForAll pmt = (ForAll) mt; 619 List<Type> tvars1 = types.newInstances(pmt.tvars); 620 tvars = tvars.appendList(tvars1); 621 mt = types.subst(pmt.qtype, pmt.tvars, tvars1); 622 } 623 624 // find out whether we need to go the slow route via infer 625 boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/ 626 for (List<Type> l = argtypes; 627 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded; 628 l = l.tail) { 629 if (l.head.hasTag(FORALL)) instNeeded = true; 630 } 631 632 if (instNeeded) { 633 return infer.instantiateMethod(env, 634 tvars, 635 (MethodType)mt, 636 resultInfo, 637 (MethodSymbol)m, 638 argtypes, 639 allowBoxing, 640 useVarargs, 641 currentResolutionContext, 642 warn); 643 } 644 645 DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn); 646 currentResolutionContext.methodCheck.argumentsAcceptable(env, dc, 647 argtypes, mt.getParameterTypes(), warn); 648 dc.complete(); 649 return mt; 650 } 651 652 Type checkMethod(Env<AttrContext> env, 653 Type site, 654 Symbol m, 655 ResultInfo resultInfo, 656 List<Type> argtypes, 657 List<Type> typeargtypes, 658 Warner warn) { 659 MethodResolutionContext prevContext = currentResolutionContext; 660 try { 661 currentResolutionContext = new MethodResolutionContext(); 662 currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ? 663 AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK; 664 if (env.tree.hasTag(JCTree.Tag.REFERENCE)) { 665 //method/constructor references need special check class 666 //to handle inference variables in 'argtypes' (might happen 667 //during an unsticking round) 668 currentResolutionContext.methodCheck = 669 new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); 670 } 671 MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase; 672 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, 673 step.isBoxingRequired(), step.isVarargsRequired(), warn); 674 } 675 finally { 676 currentResolutionContext = prevContext; 677 } 678 } 679 680 /** Same but returns null instead throwing a NoInstanceException 681 */ 682 Type instantiate(Env<AttrContext> env, 683 Type site, 684 Symbol m, 685 ResultInfo resultInfo, 686 List<Type> argtypes, 687 List<Type> typeargtypes, 688 boolean allowBoxing, 689 boolean useVarargs, 690 Warner warn) { 691 try { 692 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, 693 allowBoxing, useVarargs, warn); 694 } catch (InapplicableMethodException ex) { 695 return null; 696 } 697 } 698 699 /** 700 * This interface defines an entry point that should be used to perform a 701 * method check. A method check usually consist in determining as to whether 702 * a set of types (actuals) is compatible with another set of types (formals). 703 * Since the notion of compatibility can vary depending on the circumstances, 704 * this interfaces allows to easily add new pluggable method check routines. 705 */ 706 interface MethodCheck { 707 /** 708 * Main method check routine. A method check usually consist in determining 709 * as to whether a set of types (actuals) is compatible with another set of 710 * types (formals). If an incompatibility is found, an unchecked exception 711 * is assumed to be thrown. 712 */ 713 void argumentsAcceptable(Env<AttrContext> env, 714 DeferredAttrContext deferredAttrContext, 715 List<Type> argtypes, 716 List<Type> formals, 717 Warner warn); 718 719 /** 720 * Retrieve the method check object that will be used during a 721 * most specific check. 722 */ 723 MethodCheck mostSpecificCheck(List<Type> actuals); 724 } 725 726 /** 727 * Helper enum defining all method check diagnostics (used by resolveMethodCheck). 728 */ 729 enum MethodCheckDiag { 730 /** 731 * Actuals and formals differs in length. 732 */ 733 ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"), 734 /** 735 * An actual is incompatible with a formal. 736 */ 737 ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"), 738 /** 739 * An actual is incompatible with the varargs element type. 740 */ 741 VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"), 742 /** 743 * The varargs element type is inaccessible. 744 */ 745 INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type"); 746 747 final String basicKey; 748 final String inferKey; 749 750 MethodCheckDiag(String basicKey, String inferKey) { 751 this.basicKey = basicKey; 752 this.inferKey = inferKey; 753 } 754 755 String regex() { 756 return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey); 757 } 758 } 759 760 /** 761 * Dummy method check object. All methods are deemed applicable, regardless 762 * of their formal parameter types. 763 */ 764 MethodCheck nilMethodCheck = new MethodCheck() { 765 public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) { 766 //do nothing - method always applicable regardless of actuals 767 } 768 769 public MethodCheck mostSpecificCheck(List<Type> actuals) { 770 return this; 771 } 772 }; 773 774 /** 775 * Base class for 'real' method checks. The class defines the logic for 776 * iterating through formals and actuals and provides and entry point 777 * that can be used by subclasses in order to define the actual check logic. 778 */ 779 abstract class AbstractMethodCheck implements MethodCheck { 780 @Override 781 public void argumentsAcceptable(final Env<AttrContext> env, 782 DeferredAttrContext deferredAttrContext, 783 List<Type> argtypes, 784 List<Type> formals, 785 Warner warn) { 786 //should we expand formals? 787 boolean useVarargs = deferredAttrContext.phase.isVarargsRequired(); 788 JCTree callTree = treeForDiagnostics(env); 789 List<JCExpression> trees = TreeInfo.args(callTree); 790 791 //inference context used during this method check 792 InferenceContext inferenceContext = deferredAttrContext.inferenceContext; 793 794 Type varargsFormal = useVarargs ? formals.last() : null; 795 796 if (varargsFormal == null && 797 argtypes.size() != formals.size()) { 798 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 799 } 800 801 while (argtypes.nonEmpty() && formals.head != varargsFormal) { 802 DiagnosticPosition pos = trees != null ? trees.head : null; 803 checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn); 804 argtypes = argtypes.tail; 805 formals = formals.tail; 806 trees = trees != null ? trees.tail : trees; 807 } 808 809 if (formals.head != varargsFormal) { 810 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 811 } 812 813 if (useVarargs) { 814 //note: if applicability check is triggered by most specific test, 815 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) 816 final Type elt = types.elemtype(varargsFormal); 817 while (argtypes.nonEmpty()) { 818 DiagnosticPosition pos = trees != null ? trees.head : null; 819 checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn); 820 argtypes = argtypes.tail; 821 trees = trees != null ? trees.tail : trees; 822 } 823 } 824 } 825 826 // where 827 private JCTree treeForDiagnostics(Env<AttrContext> env) { 828 return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree; 829 } 830 831 /** 832 * Does the actual argument conforms to the corresponding formal? 833 */ 834 abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn); 835 836 protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { 837 boolean inferDiag = inferenceContext != infer.emptyContext; 838 if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) { 839 Object[] args2 = new Object[args.length + 1]; 840 System.arraycopy(args, 0, args2, 1, args.length); 841 args2[0] = inferenceContext.inferenceVars(); 842 args = args2; 843 } 844 String key = inferDiag ? diag.inferKey : diag.basicKey; 845 throw inferDiag ? 846 infer.error(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)) : 847 getMethodCheckFailure().setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)); 848 } 849 850 /** 851 * To eliminate the overhead associated with allocating an exception object in such an 852 * hot execution path, we use flyweight pattern - and share the same exception instance 853 * across multiple method check failures. 854 */ 855 class SharedInapplicableMethodException extends InapplicableMethodException { 856 private static final long serialVersionUID = 0; 857 858 SharedInapplicableMethodException() { 859 super(null, Resolve.this.dumpStacktraceOnError); 860 } 861 862 SharedInapplicableMethodException setMessage(JCDiagnostic details) { 863 this.diagnostic = details; 864 return this; 865 } 866 } 867 868 private SharedInapplicableMethodException methodCheckFailure; 869 870 public MethodCheck mostSpecificCheck(List<Type> actuals) { 871 return nilMethodCheck; 872 } 873 874 private SharedInapplicableMethodException getMethodCheckFailure() { 875 return methodCheckFailure == null ? methodCheckFailure = new SharedInapplicableMethodException() : methodCheckFailure; 876 } 877 } 878 879 /** 880 * Arity-based method check. A method is applicable if the number of actuals 881 * supplied conforms to the method signature. 882 */ 883 MethodCheck arityMethodCheck = new AbstractMethodCheck() { 884 @Override 885 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 886 //do nothing - actual always compatible to formals 887 } 888 889 @Override 890 public String toString() { 891 return "arityMethodCheck"; 892 } 893 }; 894 895 /** 896 * Main method applicability routine. Given a list of actual types A, 897 * a list of formal types F, determines whether the types in A are 898 * compatible (by method invocation conversion) with the types in F. 899 * 900 * Since this routine is shared between overload resolution and method 901 * type-inference, a (possibly empty) inference context is used to convert 902 * formal types to the corresponding 'undet' form ahead of a compatibility 903 * check so that constraints can be propagated and collected. 904 * 905 * Moreover, if one or more types in A is a deferred type, this routine uses 906 * DeferredAttr in order to perform deferred attribution. If one or more actual 907 * deferred types are stuck, they are placed in a queue and revisited later 908 * after the remainder of the arguments have been seen. If this is not sufficient 909 * to 'unstuck' the argument, a cyclic inference error is called out. 910 * 911 * A method check handler (see above) is used in order to report errors. 912 */ 913 MethodCheck resolveMethodCheck = new AbstractMethodCheck() { 914 915 @Override 916 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 917 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); 918 mresult.check(pos, actual); 919 } 920 921 @Override 922 public void argumentsAcceptable(final Env<AttrContext> env, 923 DeferredAttrContext deferredAttrContext, 924 List<Type> argtypes, 925 List<Type> formals, 926 Warner warn) { 927 super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn); 928 // should we check varargs element type accessibility? 929 if (deferredAttrContext.phase.isVarargsRequired()) { 930 if (deferredAttrContext.mode == AttrMode.CHECK) { 931 varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext); 932 } 933 } 934 } 935 936 /** 937 * Test that the runtime array element type corresponding to 't' is accessible. 't' should be the 938 * varargs element type of either the method invocation type signature (after inference completes) 939 * or the method declaration signature (before inference completes). 940 */ 941 private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) { 942 if (inferenceContext.free(t)) { 943 inferenceContext.addFreeTypeListener(List.of(t), 944 solvedContext -> varargsAccessible(env, solvedContext.asInstType(t), solvedContext)); 945 } else { 946 if (!isAccessible(env, types.erasure(t))) { 947 Symbol location = env.enclClass.sym; 948 reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); 949 } 950 } 951 } 952 953 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, 954 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { 955 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { 956 MethodCheckDiag methodDiag = varargsCheck ? 957 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; 958 959 @Override 960 public void report(DiagnosticPosition pos, JCDiagnostic details) { 961 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); 962 } 963 }; 964 return new MethodResultInfo(to, checkContext); 965 } 966 967 @Override 968 public MethodCheck mostSpecificCheck(List<Type> actuals) { 969 return new MostSpecificCheck(actuals); 970 } 971 972 @Override 973 public String toString() { 974 return "resolveMethodCheck"; 975 } 976 }; 977 978 /** 979 * This class handles method reference applicability checks; since during 980 * these checks it's sometime possible to have inference variables on 981 * the actual argument types list, the method applicability check must be 982 * extended so that inference variables are 'opened' as needed. 983 */ 984 class MethodReferenceCheck extends AbstractMethodCheck { 985 986 InferenceContext pendingInferenceContext; 987 988 MethodReferenceCheck(InferenceContext pendingInferenceContext) { 989 this.pendingInferenceContext = pendingInferenceContext; 990 } 991 992 @Override 993 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 994 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); 995 mresult.check(pos, actual); 996 } 997 998 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, 999 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { 1000 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { 1001 MethodCheckDiag methodDiag = varargsCheck ? 1002 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; 1003 1004 @Override 1005 public boolean compatible(Type found, Type req, Warner warn) { 1006 found = pendingInferenceContext.asUndetVar(found); 1007 if (found.hasTag(UNDETVAR) && req.isPrimitive()) { 1008 req = types.boxedClass(req).type; 1009 } 1010 return super.compatible(found, req, warn); 1011 } 1012 1013 @Override 1014 public void report(DiagnosticPosition pos, JCDiagnostic details) { 1015 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); 1016 } 1017 }; 1018 return new MethodResultInfo(to, checkContext); 1019 } 1020 1021 @Override 1022 public MethodCheck mostSpecificCheck(List<Type> actuals) { 1023 return new MostSpecificCheck(actuals); 1024 } 1025 1026 @Override 1027 public String toString() { 1028 return "MethodReferenceCheck"; 1029 } 1030 } 1031 1032 /** 1033 * Check context to be used during method applicability checks. A method check 1034 * context might contain inference variables. 1035 */ 1036 abstract class MethodCheckContext implements CheckContext { 1037 1038 boolean strict; 1039 DeferredAttrContext deferredAttrContext; 1040 Warner rsWarner; 1041 1042 public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) { 1043 this.strict = strict; 1044 this.deferredAttrContext = deferredAttrContext; 1045 this.rsWarner = rsWarner; 1046 } 1047 1048 public boolean compatible(Type found, Type req, Warner warn) { 1049 InferenceContext inferenceContext = deferredAttrContext.inferenceContext; 1050 return strict ? 1051 types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) : 1052 types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn); 1053 } 1054 1055 public void report(DiagnosticPosition pos, JCDiagnostic details) { 1056 throw new InapplicableMethodException(details, Resolve.this.dumpStacktraceOnError); 1057 } 1058 1059 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) { 1060 return rsWarner; 1061 } 1062 1063 public InferenceContext inferenceContext() { 1064 return deferredAttrContext.inferenceContext; 1065 } 1066 1067 public DeferredAttrContext deferredAttrContext() { 1068 return deferredAttrContext; 1069 } 1070 1071 @Override 1072 public String toString() { 1073 return "MethodCheckContext"; 1074 } 1075 } 1076 1077 /** 1078 * ResultInfo class to be used during method applicability checks. Check 1079 * for deferred types goes through special path. 1080 */ 1081 class MethodResultInfo extends ResultInfo { 1082 1083 public MethodResultInfo(Type pt, CheckContext checkContext) { 1084 attr.super(KindSelector.VAL, pt, checkContext); 1085 } 1086 1087 @Override 1088 protected Type check(DiagnosticPosition pos, Type found) { 1089 if (found.hasTag(DEFERRED)) { 1090 DeferredType dt = (DeferredType)found; 1091 return dt.check(this); 1092 } else { 1093 Type uResult = U(found); 1094 Type capturedType = pos == null || pos.getTree() == null ? 1095 types.capture(uResult) : 1096 checkContext.inferenceContext() 1097 .cachedCapture(pos.getTree(), uResult, true); 1098 return super.check(pos, chk.checkNonVoid(pos, capturedType)); 1099 } 1100 } 1101 1102 /** 1103 * javac has a long-standing 'simplification' (see 6391995): 1104 * given an actual argument type, the method check is performed 1105 * on its upper bound. This leads to inconsistencies when an 1106 * argument type is checked against itself. For example, given 1107 * a type-variable T, it is not true that {@code U(T) <: T}, 1108 * so we need to guard against that. 1109 */ 1110 private Type U(Type found) { 1111 return found == pt ? 1112 found : types.cvarUpperBound(found); 1113 } 1114 1115 @Override 1116 protected MethodResultInfo dup(Type newPt) { 1117 return new MethodResultInfo(newPt, checkContext); 1118 } 1119 1120 @Override 1121 protected ResultInfo dup(CheckContext newContext) { 1122 return new MethodResultInfo(pt, newContext); 1123 } 1124 1125 @Override 1126 protected ResultInfo dup(Type newPt, CheckContext newContext) { 1127 return new MethodResultInfo(newPt, newContext); 1128 } 1129 } 1130 1131 /** 1132 * Most specific method applicability routine. Given a list of actual types A, 1133 * a list of formal types F1, and a list of formal types F2, the routine determines 1134 * as to whether the types in F1 can be considered more specific than those in F2 w.r.t. 1135 * argument types A. 1136 */ 1137 class MostSpecificCheck implements MethodCheck { 1138 1139 List<Type> actuals; 1140 1141 MostSpecificCheck(List<Type> actuals) { 1142 this.actuals = actuals; 1143 } 1144 1145 @Override 1146 public void argumentsAcceptable(final Env<AttrContext> env, 1147 DeferredAttrContext deferredAttrContext, 1148 List<Type> formals1, 1149 List<Type> formals2, 1150 Warner warn) { 1151 formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired()); 1152 while (formals2.nonEmpty()) { 1153 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head); 1154 mresult.check(null, formals1.head); 1155 formals1 = formals1.tail; 1156 formals2 = formals2.tail; 1157 actuals = actuals.isEmpty() ? actuals : actuals.tail; 1158 } 1159 } 1160 1161 /** 1162 * Create a method check context to be used during the most specific applicability check 1163 */ 1164 ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext, 1165 Warner rsWarner, Type actual) { 1166 return attr.new ResultInfo(KindSelector.VAL, to, 1167 new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual)); 1168 } 1169 1170 /** 1171 * Subclass of method check context class that implements most specific 1172 * method conversion. If the actual type under analysis is a deferred type 1173 * a full blown structural analysis is carried out. 1174 */ 1175 class MostSpecificCheckContext extends MethodCheckContext { 1176 1177 Type actual; 1178 1179 public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) { 1180 super(true, deferredAttrContext, rsWarner); 1181 this.actual = actual; 1182 } 1183 1184 public boolean compatible(Type found, Type req, Warner warn) { 1185 if (unrelatedFunctionalInterfaces(found, req) && 1186 (actual != null && actual.getTag() == DEFERRED)) { 1187 DeferredType dt = (DeferredType) actual; 1188 JCTree speculativeTree = dt.speculativeTree(deferredAttrContext); 1189 if (speculativeTree != deferredAttr.stuckTree) { 1190 return functionalInterfaceMostSpecific(found, req, speculativeTree); 1191 } 1192 } 1193 return compatibleBySubtyping(found, req); 1194 } 1195 1196 private boolean compatibleBySubtyping(Type found, Type req) { 1197 if (!strict && found.isPrimitive() != req.isPrimitive()) { 1198 found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found); 1199 } 1200 return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req)); 1201 } 1202 1203 /** Whether {@code t} and {@code s} are unrelated functional interface types. */ 1204 private boolean unrelatedFunctionalInterfaces(Type t, Type s) { 1205 return types.isFunctionalInterface(t.tsym) && 1206 types.isFunctionalInterface(s.tsym) && 1207 unrelatedInterfaces(t, s); 1208 } 1209 1210 /** Whether {@code t} and {@code s} are unrelated interface types; recurs on intersections. **/ 1211 private boolean unrelatedInterfaces(Type t, Type s) { 1212 if (t.isCompound()) { 1213 for (Type ti : types.interfaces(t)) { 1214 if (!unrelatedInterfaces(ti, s)) { 1215 return false; 1216 } 1217 } 1218 return true; 1219 } else if (s.isCompound()) { 1220 for (Type si : types.interfaces(s)) { 1221 if (!unrelatedInterfaces(t, si)) { 1222 return false; 1223 } 1224 } 1225 return true; 1226 } else { 1227 return types.asSuper(t, s.tsym) == null && types.asSuper(s, t.tsym) == null; 1228 } 1229 } 1230 1231 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */ 1232 private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) { 1233 Type tDesc; 1234 Type tDescNoCapture; 1235 Type sDesc; 1236 try { 1237 tDesc = types.findDescriptorType(types.capture(t)); 1238 tDescNoCapture = types.findDescriptorType(t); 1239 sDesc = types.findDescriptorType(s); 1240 } catch (Types.FunctionDescriptorLookupError ex) { 1241 // don't report, a more meaningful error should be reported upstream 1242 return false; 1243 } 1244 final List<Type> tTypeParams = tDesc.getTypeArguments(); 1245 final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments(); 1246 final List<Type> sTypeParams = sDesc.getTypeArguments(); 1247 1248 // compare type parameters 1249 if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) { 1250 return false; 1251 } 1252 // can't use Types.hasSameBounds on sDesc because bounds may have ivars 1253 List<Type> tIter = tTypeParams; 1254 List<Type> sIter = sTypeParams; 1255 while (tIter.nonEmpty() && sIter.nonEmpty()) { 1256 Type tBound = tIter.head.getUpperBound(); 1257 Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams); 1258 if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) { 1259 return false; 1260 } 1261 if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) { 1262 return false; 1263 } 1264 tIter = tIter.tail; 1265 sIter = sIter.tail; 1266 } 1267 if (!tIter.isEmpty() || !sIter.isEmpty()) { 1268 return false; 1269 } 1270 1271 // compare parameters 1272 List<Type> tParams = tDesc.getParameterTypes(); 1273 List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes(); 1274 List<Type> sParams = sDesc.getParameterTypes(); 1275 while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) { 1276 Type tParam = tParams.head; 1277 Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams); 1278 Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams); 1279 if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) { 1280 return false; 1281 } 1282 if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) { 1283 return false; 1284 } 1285 if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) { 1286 return false; 1287 } 1288 tParams = tParams.tail; 1289 tParamsNoCapture = tParamsNoCapture.tail; 1290 sParams = sParams.tail; 1291 } 1292 if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) { 1293 return false; 1294 } 1295 1296 // compare returns 1297 Type tRet = tDesc.getReturnType(); 1298 Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams); 1299 if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) { 1300 return false; 1301 } 1302 MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet); 1303 msc.scan(tree); 1304 return msc.result; 1305 } 1306 1307 /** 1308 * Tests whether one functional interface type can be considered more specific 1309 * than another unrelated functional interface type for the scanned expression. 1310 */ 1311 class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner { 1312 1313 final Type tRet; 1314 final Type sRet; 1315 boolean result; 1316 1317 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */ 1318 MostSpecificFunctionReturnChecker(Type tRet, Type sRet) { 1319 this.tRet = tRet; 1320 this.sRet = sRet; 1321 result = true; 1322 } 1323 1324 @Override 1325 void skip(JCTree tree) { 1326 result = false; 1327 } 1328 1329 @Override 1330 public void visitConditional(JCConditional tree) { 1331 scan(asExpr(tree.truepart)); 1332 scan(asExpr(tree.falsepart)); 1333 } 1334 1335 @Override 1336 public void visitReference(JCMemberReference tree) { 1337 if (sRet.hasTag(VOID)) { 1338 // do nothing 1339 } else if (tRet.hasTag(VOID)) { 1340 result = false; 1341 } else if (tRet.isPrimitive() != sRet.isPrimitive()) { 1342 boolean retValIsPrimitive = 1343 tree.refPolyKind == PolyKind.STANDALONE && 1344 tree.sym.type.getReturnType().isPrimitive(); 1345 result &= (retValIsPrimitive == tRet.isPrimitive()) && 1346 (retValIsPrimitive != sRet.isPrimitive()); 1347 } else { 1348 result &= compatibleBySubtyping(tRet, sRet); 1349 } 1350 } 1351 1352 @Override 1353 public void visitParens(JCParens tree) { 1354 scan(asExpr(tree.expr)); 1355 } 1356 1357 @Override 1358 public void visitLambda(JCLambda tree) { 1359 if (sRet.hasTag(VOID)) { 1360 // do nothing 1361 } else if (tRet.hasTag(VOID)) { 1362 result = false; 1363 } else { 1364 List<JCExpression> lambdaResults = lambdaResults(tree); 1365 if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) { 1366 for (JCExpression expr : lambdaResults) { 1367 result &= functionalInterfaceMostSpecific(tRet, sRet, expr); 1368 } 1369 } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) { 1370 for (JCExpression expr : lambdaResults) { 1371 boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive(); 1372 result &= (retValIsPrimitive == tRet.isPrimitive()) && 1373 (retValIsPrimitive != sRet.isPrimitive()); 1374 } 1375 } else { 1376 result &= compatibleBySubtyping(tRet, sRet); 1377 } 1378 } 1379 } 1380 //where 1381 1382 private List<JCExpression> lambdaResults(JCLambda lambda) { 1383 if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { 1384 return List.of(asExpr((JCExpression) lambda.body)); 1385 } else { 1386 final ListBuffer<JCExpression> buffer = new ListBuffer<>(); 1387 DeferredAttr.LambdaReturnScanner lambdaScanner = 1388 new DeferredAttr.LambdaReturnScanner() { 1389 @Override 1390 public void visitReturn(JCReturn tree) { 1391 if (tree.expr != null) { 1392 buffer.append(asExpr(tree.expr)); 1393 } 1394 } 1395 }; 1396 lambdaScanner.scan(lambda.body); 1397 return buffer.toList(); 1398 } 1399 } 1400 1401 private JCExpression asExpr(JCExpression expr) { 1402 if (expr.type.hasTag(DEFERRED)) { 1403 JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext); 1404 if (speculativeTree != deferredAttr.stuckTree) { 1405 expr = (JCExpression)speculativeTree; 1406 } 1407 } 1408 return expr; 1409 } 1410 } 1411 1412 } 1413 1414 public MethodCheck mostSpecificCheck(List<Type> actuals) { 1415 Assert.error("Cannot get here!"); 1416 return null; 1417 } 1418 } 1419 1420 public static class InapplicableMethodException extends CompilerInternalException { 1421 private static final long serialVersionUID = 0; 1422 1423 transient JCDiagnostic diagnostic; 1424 1425 InapplicableMethodException(JCDiagnostic diag, boolean dumpStackTraceOnError) { 1426 super(dumpStackTraceOnError); 1427 this.diagnostic = diag; 1428 } 1429 1430 public JCDiagnostic getDiagnostic() { 1431 return diagnostic; 1432 } 1433 } 1434 1435 /* *************************************************************************** 1436 * Symbol lookup 1437 * the following naming conventions for arguments are used 1438 * 1439 * env is the environment where the symbol was mentioned 1440 * site is the type of which the symbol is a member 1441 * name is the symbol's name 1442 * if no arguments are given 1443 * argtypes are the value arguments, if we search for a method 1444 * 1445 * If no symbol was found, a ResolveError detailing the problem is returned. 1446 ****************************************************************************/ 1447 1448 /** Find field. Synthetic fields are always skipped. 1449 * @param env The current environment. 1450 * @param site The original type from where the selection takes place. 1451 * @param name The name of the field. 1452 * @param c The class to search for the field. This is always 1453 * a superclass or implemented interface of site's class. 1454 */ 1455 Symbol findField(Env<AttrContext> env, 1456 Type site, 1457 Name name, 1458 TypeSymbol c) { 1459 while (c.type.hasTag(TYPEVAR)) 1460 c = c.type.getUpperBound().tsym; 1461 Symbol bestSoFar = varNotFound; 1462 Symbol sym; 1463 for (Symbol s : c.members().getSymbolsByName(name)) { 1464 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) { 1465 return isAccessible(env, site, s) 1466 ? s : new AccessError(env, site, s); 1467 } 1468 } 1469 Type st = types.supertype(c.type); 1470 if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) { 1471 sym = findField(env, site, name, st.tsym); 1472 bestSoFar = bestOf(bestSoFar, sym); 1473 } 1474 for (List<Type> l = types.interfaces(c.type); 1475 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1476 l = l.tail) { 1477 sym = findField(env, site, name, l.head.tsym); 1478 if (bestSoFar.exists() && sym.exists() && 1479 sym.owner != bestSoFar.owner) 1480 bestSoFar = new AmbiguityError(bestSoFar, sym); 1481 else 1482 bestSoFar = bestOf(bestSoFar, sym); 1483 } 1484 return bestSoFar; 1485 } 1486 1487 /** Resolve a field identifier, throw a fatal error if not found. 1488 * @param pos The position to use for error reporting. 1489 * @param env The environment current at the method invocation. 1490 * @param site The type of the qualifying expression, in which 1491 * identifier is searched. 1492 * @param name The identifier's name. 1493 */ 1494 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env, 1495 Type site, Name name) { 1496 Symbol sym = findField(env, site, name, site.tsym); 1497 if (sym.kind == VAR) return (VarSymbol)sym; 1498 else throw new FatalError( 1499 diags.fragment(Fragments.FatalErrCantLocateField(name))); 1500 } 1501 1502 /** Find unqualified variable or field with given name. 1503 * Synthetic fields always skipped. 1504 * @param pos The position to use for error reporting. 1505 * @param env The current environment. 1506 * @param name The name of the variable or field. 1507 */ 1508 Symbol findVar(DiagnosticPosition pos, Env<AttrContext> env, Name name) { 1509 Symbol bestSoFar = varNotFound; 1510 Env<AttrContext> env1 = env; 1511 boolean staticOnly = false; 1512 while (env1.outer != null) { 1513 Symbol sym = null; 1514 for (Symbol s : env1.info.scope.getSymbolsByName(name)) { 1515 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) { 1516 sym = s; 1517 if (staticOnly) { 1518 return new StaticError(sym); 1519 } 1520 break; 1521 } 1522 } 1523 if (isStatic(env1)) staticOnly = true; 1524 if (sym == null) { 1525 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym); 1526 } 1527 if (sym.exists()) { 1528 if (sym.kind == VAR && 1529 sym.owner.kind == TYP && 1530 (sym.flags() & STATIC) == 0) { 1531 if (staticOnly) 1532 return new StaticError(sym); 1533 if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) 1534 return new RefBeforeCtorCalledError(sym); 1535 } 1536 return sym; 1537 } else { 1538 bestSoFar = bestOf(bestSoFar, sym); 1539 } 1540 1541 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1542 env1 = env1.outer; 1543 } 1544 1545 Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass); 1546 if (sym.exists()) 1547 return sym; 1548 if (bestSoFar.exists()) 1549 return bestSoFar; 1550 1551 Symbol origin = null; 1552 for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) { 1553 for (Symbol currentSymbol : sc.getSymbolsByName(name)) { 1554 if (currentSymbol.kind != VAR) 1555 continue; 1556 // invariant: sym.kind == Symbol.Kind.VAR 1557 if (!bestSoFar.kind.isResolutionError() && 1558 currentSymbol.owner != bestSoFar.owner) 1559 return new AmbiguityError(bestSoFar, currentSymbol); 1560 else if (!bestSoFar.kind.betterThan(VAR)) { 1561 origin = sc.getOrigin(currentSymbol).owner; 1562 bestSoFar = isAccessible(env, origin.type, currentSymbol) 1563 ? currentSymbol : new AccessError(env, origin.type, currentSymbol); 1564 } 1565 } 1566 if (bestSoFar.exists()) break; 1567 } 1568 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type) 1569 return bestSoFar.clone(origin); 1570 else 1571 return bestSoFar; 1572 } 1573 1574 Warner noteWarner = new Warner(); 1575 1576 /** Select the best method for a call site among two choices. 1577 * @param env The current environment. 1578 * @param site The original type from where the 1579 * selection takes place. 1580 * @param argtypes The invocation's value arguments, 1581 * @param typeargtypes The invocation's type arguments, 1582 * @param sym Proposed new best match. 1583 * @param bestSoFar Previously found best match. 1584 * @param allowBoxing Allow boxing conversions of arguments. 1585 * @param useVarargs Box trailing arguments into an array for varargs. 1586 */ 1587 @SuppressWarnings("fallthrough") 1588 Symbol selectBest(Env<AttrContext> env, 1589 Type site, 1590 List<Type> argtypes, 1591 List<Type> typeargtypes, 1592 Symbol sym, 1593 Symbol bestSoFar, 1594 boolean allowBoxing, 1595 boolean useVarargs) { 1596 if (sym.kind == ERR || 1597 (site.tsym != sym.owner && !sym.isInheritedIn(site.tsym, types)) || 1598 !notOverriddenIn(site, sym)) { 1599 return bestSoFar; 1600 } else if (useVarargs && (sym.flags() & VARARGS) == 0) { 1601 return bestSoFar.kind.isResolutionError() ? 1602 new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) : 1603 bestSoFar; 1604 } 1605 Assert.check(!sym.kind.isResolutionError()); 1606 try { 1607 types.noWarnings.clear(); 1608 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, 1609 allowBoxing, useVarargs, types.noWarnings); 1610 currentResolutionContext.addApplicableCandidate(sym, mt); 1611 } catch (InapplicableMethodException ex) { 1612 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); 1613 // Currently, an InapplicableMethodException occurs. 1614 // If bestSoFar.kind was ABSENT_MTH, return an InapplicableSymbolError(kind is WRONG_MTH). 1615 // If bestSoFar.kind was HIDDEN(AccessError)/WRONG_MTH/WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS). 1616 // See JDK-8255968 for more information. 1617 switch (bestSoFar.kind) { 1618 case ABSENT_MTH: 1619 return new InapplicableSymbolError(currentResolutionContext); 1620 case HIDDEN: 1621 if (bestSoFar instanceof AccessError accessError) { 1622 // Add the JCDiagnostic of previous AccessError to the currentResolutionContext 1623 // and construct InapplicableSymbolsError. 1624 // Intentionally fallthrough. 1625 currentResolutionContext.addInapplicableCandidate(accessError.sym, 1626 accessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes)); 1627 } else { 1628 return bestSoFar; 1629 } 1630 case WRONG_MTH: 1631 bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1632 default: 1633 return bestSoFar; 1634 } 1635 } 1636 if (!isAccessible(env, site, sym)) { 1637 AccessError curAccessError = new AccessError(env, site, sym); 1638 JCDiagnostic curDiagnostic = curAccessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes); 1639 // Currently, an AccessError occurs. 1640 // If bestSoFar.kind was ABSENT_MTH, return an AccessError(kind is HIDDEN). 1641 // If bestSoFar.kind was HIDDEN(AccessError), WRONG_MTH, WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS). 1642 // See JDK-8255968 for more information. 1643 if (bestSoFar.kind == ABSENT_MTH) { 1644 bestSoFar = curAccessError; 1645 } else if (bestSoFar.kind == WRONG_MTH) { 1646 // Add the JCDiagnostic of current AccessError to the currentResolutionContext 1647 // and construct InapplicableSymbolsError. 1648 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic); 1649 bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1650 } else if (bestSoFar.kind == WRONG_MTHS) { 1651 // Add the JCDiagnostic of current AccessError to the currentResolutionContext 1652 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic); 1653 } else if (bestSoFar.kind == HIDDEN && bestSoFar instanceof AccessError accessError) { 1654 // Add the JCDiagnostics of previous and current AccessError to the currentResolutionContext 1655 // and construct InapplicableSymbolsError. 1656 currentResolutionContext.addInapplicableCandidate(accessError.sym, 1657 accessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes)); 1658 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic); 1659 bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1660 } 1661 return bestSoFar; 1662 } 1663 return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS) 1664 ? sym 1665 : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs); 1666 } 1667 1668 /* Return the most specific of the two methods for a call, 1669 * given that both are accessible and applicable. 1670 * @param m1 A new candidate for most specific. 1671 * @param m2 The previous most specific candidate. 1672 * @param env The current environment. 1673 * @param site The original type from where the selection 1674 * takes place. 1675 * @param allowBoxing Allow boxing conversions of arguments. 1676 * @param useVarargs Box trailing arguments into an array for varargs. 1677 */ 1678 Symbol mostSpecific(List<Type> argtypes, Symbol m1, 1679 Symbol m2, 1680 Env<AttrContext> env, 1681 final Type site, 1682 boolean useVarargs) { 1683 switch (m2.kind) { 1684 case MTH: 1685 if (m1 == m2) return m1; 1686 boolean m1SignatureMoreSpecific = 1687 signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs); 1688 boolean m2SignatureMoreSpecific = 1689 signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs); 1690 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 1691 Type mt1 = types.memberType(site, m1); 1692 Type mt2 = types.memberType(site, m2); 1693 if (!types.overrideEquivalent(mt1, mt2)) 1694 return ambiguityError(m1, m2); 1695 1696 // same signature; select (a) the non-bridge method, or 1697 // (b) the one that overrides the other, or (c) the concrete 1698 // one, or (d) merge both abstract signatures 1699 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) 1700 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 1701 1702 if (m1.baseSymbol() == m2.baseSymbol()) { 1703 // this is the same imported symbol which has been cloned twice. 1704 // Return the first one (either will do). 1705 return m1; 1706 } 1707 1708 // if one overrides or hides the other, use it 1709 TypeSymbol m1Owner = (TypeSymbol)m1.owner; 1710 TypeSymbol m2Owner = (TypeSymbol)m2.owner; 1711 // the two owners can never be the same if the target methods are compiled from source, 1712 // but we need to protect against cases where the methods are defined in some classfile 1713 // and make sure we issue an ambiguity error accordingly (by skipping the logic below). 1714 if (m1Owner != m2Owner) { 1715 if (types.asSuper(m1Owner.type, m2Owner) != null && 1716 ((m1.owner.flags_field & INTERFACE) == 0 || 1717 (m2.owner.flags_field & INTERFACE) != 0) && 1718 m1.overrides(m2, m1Owner, types, false)) 1719 return m1; 1720 if (types.asSuper(m2Owner.type, m1Owner) != null && 1721 ((m2.owner.flags_field & INTERFACE) == 0 || 1722 (m1.owner.flags_field & INTERFACE) != 0) && 1723 m2.overrides(m1, m2Owner, types, false)) 1724 return m2; 1725 } 1726 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; 1727 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; 1728 if (m1Abstract && !m2Abstract) return m2; 1729 if (m2Abstract && !m1Abstract) return m1; 1730 // both abstract or both concrete 1731 return ambiguityError(m1, m2); 1732 } 1733 if (m1SignatureMoreSpecific) return m1; 1734 if (m2SignatureMoreSpecific) return m2; 1735 return ambiguityError(m1, m2); 1736 case AMBIGUOUS: 1737 //compare m1 to ambiguous methods in m2 1738 AmbiguityError e = (AmbiguityError)m2.baseSymbol(); 1739 boolean m1MoreSpecificThanAnyAmbiguous = true; 1740 boolean allAmbiguousMoreSpecificThanM1 = true; 1741 for (Symbol s : e.ambiguousSyms) { 1742 Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs); 1743 m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1; 1744 allAmbiguousMoreSpecificThanM1 &= moreSpecific == s; 1745 } 1746 if (m1MoreSpecificThanAnyAmbiguous) 1747 return m1; 1748 //if m1 is more specific than some ambiguous methods, but other ambiguous methods are 1749 //more specific than m1, add it as a new ambiguous method: 1750 if (!allAmbiguousMoreSpecificThanM1) 1751 e.addAmbiguousSymbol(m1); 1752 return e; 1753 default: 1754 throw new AssertionError(); 1755 } 1756 } 1757 //where 1758 private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) { 1759 noteWarner.clear(); 1760 int maxLength = Math.max( 1761 Math.max(m1.type.getParameterTypes().length(), actuals.length()), 1762 m2.type.getParameterTypes().length()); 1763 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1764 try { 1765 currentResolutionContext = new MethodResolutionContext(); 1766 currentResolutionContext.step = prevResolutionContext.step; 1767 currentResolutionContext.methodCheck = 1768 prevResolutionContext.methodCheck.mostSpecificCheck(actuals); 1769 Type mst = instantiate(env, site, m2, null, 1770 adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null, 1771 false, useVarargs, noteWarner); 1772 return mst != null && 1773 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); 1774 } finally { 1775 currentResolutionContext = prevResolutionContext; 1776 } 1777 } 1778 1779 List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) { 1780 if ((msym.flags() & VARARGS) != 0 && allowVarargs) { 1781 Type varargsElem = types.elemtype(args.last()); 1782 if (varargsElem == null) { 1783 Assert.error("Bad varargs = " + args.last() + " " + msym); 1784 } 1785 List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse(); 1786 while (newArgs.length() < length) { 1787 newArgs = newArgs.append(newArgs.last()); 1788 } 1789 return newArgs; 1790 } else { 1791 return args; 1792 } 1793 } 1794 //where 1795 Symbol ambiguityError(Symbol m1, Symbol m2) { 1796 if (((m1.flags() | m2.flags()) & CLASH) != 0) { 1797 return (m1.flags() & CLASH) == 0 ? m1 : m2; 1798 } else { 1799 return new AmbiguityError(m1, m2); 1800 } 1801 } 1802 1803 Symbol findMethodInScope(Env<AttrContext> env, 1804 Type site, 1805 Name name, 1806 List<Type> argtypes, 1807 List<Type> typeargtypes, 1808 Scope sc, 1809 Symbol bestSoFar, 1810 boolean allowBoxing, 1811 boolean useVarargs, 1812 boolean abstractok) { 1813 for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) { 1814 bestSoFar = selectBest(env, site, argtypes, typeargtypes, s, 1815 bestSoFar, allowBoxing, useVarargs); 1816 } 1817 return bestSoFar; 1818 } 1819 //where 1820 class LookupFilter implements Predicate<Symbol> { 1821 1822 boolean abstractOk; 1823 1824 LookupFilter(boolean abstractOk) { 1825 this.abstractOk = abstractOk; 1826 } 1827 1828 @Override 1829 public boolean test(Symbol s) { 1830 long flags = s.flags(); 1831 return s.kind == MTH && 1832 (flags & SYNTHETIC) == 0 && 1833 (abstractOk || 1834 (flags & DEFAULT) != 0 || 1835 (flags & ABSTRACT) == 0); 1836 } 1837 } 1838 1839 /** Find best qualified method matching given name, type and value 1840 * arguments. 1841 * @param env The current environment. 1842 * @param site The original type from where the selection 1843 * takes place. 1844 * @param name The method's name. 1845 * @param argtypes The method's value arguments. 1846 * @param typeargtypes The method's type arguments 1847 * @param allowBoxing Allow boxing conversions of arguments. 1848 * @param useVarargs Box trailing arguments into an array for varargs. 1849 */ 1850 Symbol findMethod(Env<AttrContext> env, 1851 Type site, 1852 Name name, 1853 List<Type> argtypes, 1854 List<Type> typeargtypes, 1855 boolean allowBoxing, 1856 boolean useVarargs) { 1857 Symbol bestSoFar = methodNotFound; 1858 bestSoFar = findMethod(env, 1859 site, 1860 name, 1861 argtypes, 1862 typeargtypes, 1863 site.tsym.type, 1864 bestSoFar, 1865 allowBoxing, 1866 useVarargs); 1867 if (bestSoFar.kind == AMBIGUOUS) { 1868 AmbiguityError a_err = (AmbiguityError)bestSoFar.baseSymbol(); 1869 bestSoFar = a_err.mergeAbstracts(site); 1870 } 1871 return bestSoFar; 1872 } 1873 // where 1874 private Symbol findMethod(Env<AttrContext> env, 1875 Type site, 1876 Name name, 1877 List<Type> argtypes, 1878 List<Type> typeargtypes, 1879 Type intype, 1880 Symbol bestSoFar, 1881 boolean allowBoxing, 1882 boolean useVarargs) { 1883 @SuppressWarnings({"unchecked","rawtypes"}) 1884 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() }; 1885 1886 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK; 1887 boolean isInterface = site.tsym.isInterface(); 1888 for (TypeSymbol s : isInterface ? List.of(intype.tsym) : superclasses(intype)) { 1889 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1890 s.members(), bestSoFar, allowBoxing, useVarargs, true); 1891 if (name == names.init) return bestSoFar; 1892 iphase = (iphase == null) ? null : iphase.update(s, this); 1893 if (iphase != null) { 1894 for (Type itype : types.interfaces(s.type)) { 1895 itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]); 1896 } 1897 } 1898 } 1899 1900 Symbol concrete = bestSoFar.kind.isValid() && 1901 (bestSoFar.flags() & ABSTRACT) == 0 ? 1902 bestSoFar : methodNotFound; 1903 1904 for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) { 1905 //keep searching for abstract methods 1906 for (Type itype : itypes[iphase2.ordinal()]) { 1907 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure()) 1908 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && 1909 (itype.tsym.flags() & DEFAULT) == 0) continue; 1910 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1911 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true); 1912 if (concrete != bestSoFar && 1913 concrete.kind.isValid() && 1914 bestSoFar.kind.isValid() && 1915 types.isSubSignature(concrete.type, bestSoFar.type)) { 1916 //this is an hack - as javac does not do full membership checks 1917 //most specific ends up comparing abstract methods that might have 1918 //been implemented by some concrete method in a subclass and, 1919 //because of raw override, it is possible for an abstract method 1920 //to be more specific than the concrete method - so we need 1921 //to explicitly call that out (see CR 6178365) 1922 bestSoFar = concrete; 1923 } 1924 } 1925 } 1926 if (isInterface && bestSoFar.kind.isResolutionError()) { 1927 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1928 syms.objectType.tsym.members(), bestSoFar, allowBoxing, useVarargs, true); 1929 if (bestSoFar.kind.isValid()) { 1930 Symbol baseSymbol = bestSoFar; 1931 bestSoFar = new MethodSymbol(bestSoFar.flags_field, bestSoFar.name, bestSoFar.type, intype.tsym) { 1932 @Override 1933 public Symbol baseSymbol() { 1934 return baseSymbol; 1935 } 1936 }; 1937 } 1938 } 1939 return bestSoFar; 1940 } 1941 1942 enum InterfaceLookupPhase { 1943 ABSTRACT_OK() { 1944 @Override 1945 InterfaceLookupPhase update(Symbol s, Resolve rs) { 1946 //We should not look for abstract methods if receiver is a concrete class 1947 //(as concrete classes are expected to implement all abstracts coming 1948 //from superinterfaces) 1949 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) { 1950 return this; 1951 } else { 1952 return DEFAULT_OK; 1953 } 1954 } 1955 }, 1956 DEFAULT_OK() { 1957 @Override 1958 InterfaceLookupPhase update(Symbol s, Resolve rs) { 1959 return this; 1960 } 1961 }; 1962 1963 abstract InterfaceLookupPhase update(Symbol s, Resolve rs); 1964 } 1965 1966 /** 1967 * Return an Iterable object to scan the superclasses of a given type. 1968 * It's crucial that the scan is done lazily, as we don't want to accidentally 1969 * access more supertypes than strictly needed (as this could trigger completion 1970 * errors if some of the not-needed supertypes are missing/ill-formed). 1971 */ 1972 Iterable<TypeSymbol> superclasses(final Type intype) { 1973 return () -> new Iterator<TypeSymbol>() { 1974 1975 List<TypeSymbol> seen = List.nil(); 1976 TypeSymbol currentSym = symbolFor(intype); 1977 TypeSymbol prevSym = null; 1978 1979 public boolean hasNext() { 1980 if (currentSym == syms.noSymbol) { 1981 currentSym = symbolFor(types.supertype(prevSym.type)); 1982 } 1983 return currentSym != null; 1984 } 1985 1986 public TypeSymbol next() { 1987 prevSym = currentSym; 1988 currentSym = syms.noSymbol; 1989 Assert.check(prevSym != null || prevSym != syms.noSymbol); 1990 return prevSym; 1991 } 1992 1993 public void remove() { 1994 throw new UnsupportedOperationException(); 1995 } 1996 1997 TypeSymbol symbolFor(Type t) { 1998 if (!t.hasTag(CLASS) && 1999 !t.hasTag(TYPEVAR)) { 2000 return null; 2001 } 2002 t = types.skipTypeVars(t, false); 2003 if (seen.contains(t.tsym)) { 2004 //degenerate case in which we have a circular 2005 //class hierarchy - because of ill-formed classfiles 2006 return null; 2007 } 2008 seen = seen.prepend(t.tsym); 2009 return t.tsym; 2010 } 2011 }; 2012 } 2013 2014 /** Find unqualified method matching given name, type and value arguments. 2015 * @param env The current environment. 2016 * @param name The method's name. 2017 * @param argtypes The method's value arguments. 2018 * @param typeargtypes The method's type arguments. 2019 * @param allowBoxing Allow boxing conversions of arguments. 2020 * @param useVarargs Box trailing arguments into an array for varargs. 2021 */ 2022 Symbol findFun(Env<AttrContext> env, Name name, 2023 List<Type> argtypes, List<Type> typeargtypes, 2024 boolean allowBoxing, boolean useVarargs) { 2025 Symbol bestSoFar = methodNotFound; 2026 Env<AttrContext> env1 = env; 2027 boolean staticOnly = false; 2028 while (env1.outer != null) { 2029 if (isStatic(env1)) staticOnly = true; 2030 Assert.check(env1.info.preferredTreeForDiagnostics == null); 2031 env1.info.preferredTreeForDiagnostics = env.tree; 2032 try { 2033 Symbol sym = findMethod( 2034 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 2035 allowBoxing, useVarargs); 2036 if (sym.exists()) { 2037 if (sym.kind == MTH && 2038 sym.owner.kind == TYP && 2039 (sym.flags() & STATIC) == 0) { 2040 if (staticOnly) 2041 return new StaticError(sym); 2042 if (env1.info.ctorPrologue && env1 == env) 2043 return new RefBeforeCtorCalledError(sym); 2044 } 2045 return sym; 2046 } else { 2047 bestSoFar = bestOf(bestSoFar, sym); 2048 } 2049 } finally { 2050 env1.info.preferredTreeForDiagnostics = null; 2051 } 2052 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 2053 env1 = env1.outer; 2054 } 2055 2056 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 2057 typeargtypes, allowBoxing, useVarargs); 2058 if (sym.exists()) 2059 return sym; 2060 2061 for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) { 2062 Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner; 2063 if (currentSym.kind == MTH) { 2064 if (currentSym.owner.type != origin.type) 2065 currentSym = currentSym.clone(origin); 2066 if (!isAccessible(env, origin.type, currentSym)) 2067 currentSym = new AccessError(env, origin.type, currentSym); 2068 bestSoFar = selectBest(env, origin.type, 2069 argtypes, typeargtypes, 2070 currentSym, bestSoFar, 2071 allowBoxing, useVarargs); 2072 } 2073 } 2074 if (bestSoFar.exists()) 2075 return bestSoFar; 2076 2077 for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) { 2078 Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner; 2079 if (currentSym.kind == MTH) { 2080 if (currentSym.owner.type != origin.type) 2081 currentSym = currentSym.clone(origin); 2082 if (!isAccessible(env, origin.type, currentSym)) 2083 currentSym = new AccessError(env, origin.type, currentSym); 2084 bestSoFar = selectBest(env, origin.type, 2085 argtypes, typeargtypes, 2086 currentSym, bestSoFar, 2087 allowBoxing, useVarargs); 2088 } 2089 } 2090 return bestSoFar; 2091 } 2092 2093 /** Load toplevel or member class with given fully qualified name and 2094 * verify that it is accessible. 2095 * @param env The current environment. 2096 * @param name The fully qualified name of the class to be loaded. 2097 */ 2098 Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) { 2099 try { 2100 ClassSymbol c = finder.loadClass(env.toplevel.modle, name); 2101 return isAccessible(env, c) ? c : new AccessError(env, null, c); 2102 } catch (ClassFinder.BadClassFile err) { 2103 return new BadClassFileError(err); 2104 } catch (CompletionFailure ex) { 2105 Symbol candidate = recoveryLoadClass.loadClass(env, name); 2106 2107 if (candidate != null) { 2108 return candidate; 2109 } 2110 2111 return typeNotFound; 2112 } 2113 } 2114 2115 public interface RecoveryLoadClass { 2116 Symbol loadClass(Env<AttrContext> env, Name name); 2117 } 2118 2119 private final RecoveryLoadClass noRecovery = (env, name) -> null; 2120 2121 private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() { 2122 @Override public Symbol loadClass(Env<AttrContext> env, Name name) { 2123 List<Name> candidates = Convert.classCandidates(name); 2124 return lookupInvisibleSymbol(env, name, 2125 n -> () -> createCompoundIterator(candidates, 2126 c -> syms.getClassesForName(c) 2127 .iterator()), 2128 (ms, n) -> { 2129 for (Name candidate : candidates) { 2130 try { 2131 return finder.loadClass(ms, candidate); 2132 } catch (CompletionFailure cf) { 2133 //ignore 2134 } 2135 } 2136 return null; 2137 }, sym -> sym.kind == Kind.TYP, typeNotFound); 2138 } 2139 }; 2140 2141 private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> { 2142 Scope importScope = env.toplevel.namedImportScope; 2143 Symbol existing = importScope.findFirst(Convert.shortName(name), 2144 sym -> sym.kind == TYP && sym.flatName() == name); 2145 2146 if (existing != null) { 2147 return new InvisibleSymbolError(env, true, existing); 2148 } 2149 return null; 2150 }; 2151 2152 private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> { 2153 Scope importScope = env.toplevel.starImportScope; 2154 Symbol existing = importScope.findFirst(Convert.shortName(name), 2155 sym -> sym.kind == TYP && sym.flatName() == name); 2156 2157 if (existing != null) { 2158 try { 2159 existing = finder.loadClass(existing.packge().modle, name); 2160 2161 return new InvisibleSymbolError(env, true, existing); 2162 } catch (CompletionFailure cf) { 2163 //ignore 2164 } 2165 } 2166 2167 return null; 2168 }; 2169 2170 Symbol lookupPackage(Env<AttrContext> env, Name name) { 2171 PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name); 2172 2173 if (allowModules && isImportOnDemand(env, name)) { 2174 if (pack.members().isEmpty()) { 2175 return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> { 2176 sym.complete(); 2177 return !sym.members().isEmpty(); 2178 }, pack); 2179 } 2180 } 2181 2182 return pack; 2183 } 2184 2185 private boolean isImportOnDemand(Env<AttrContext> env, Name name) { 2186 if (!env.tree.hasTag(IMPORT)) 2187 return false; 2188 2189 JCTree qualid = ((JCImport) env.tree).qualid; 2190 2191 if (!qualid.hasTag(SELECT)) 2192 return false; 2193 2194 if (TreeInfo.name(qualid) != names.asterisk) 2195 return false; 2196 2197 return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name; 2198 } 2199 2200 private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env, 2201 Name name, 2202 Function<Name, Iterable<S>> get, 2203 BiFunction<ModuleSymbol, Name, S> load, 2204 Predicate<S> validate, 2205 Symbol defaultResult) { 2206 //even if a class/package cannot be found in the current module and among packages in modules 2207 //it depends on that are exported for any or this module, the class/package may exist internally 2208 //in some of these modules, or may exist in a module on which this module does not depend. 2209 //Provide better diagnostic in such cases by looking for the class in any module: 2210 Iterable<? extends S> candidates = get.apply(name); 2211 2212 for (S sym : candidates) { 2213 if (validate.test(sym)) 2214 return createInvisibleSymbolError(env, sym); 2215 } 2216 2217 Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules()); 2218 2219 recoverableModules.add(syms.unnamedModule); 2220 recoverableModules.remove(env.toplevel.modle); 2221 2222 for (ModuleSymbol ms : recoverableModules) { 2223 //avoid overly eager completing classes from source-based modules, as those 2224 //may not be completable with the current compiler settings: 2225 if (ms.sourceLocation == null) { 2226 if (ms.classLocation == null) { 2227 ms = moduleFinder.findModule(ms); 2228 } 2229 2230 if (ms.kind != ERR) { 2231 S sym = load.apply(ms, name); 2232 2233 if (sym != null && validate.test(sym)) { 2234 return createInvisibleSymbolError(env, sym); 2235 } 2236 } 2237 } 2238 } 2239 2240 return defaultResult; 2241 } 2242 2243 private Symbol createInvisibleSymbolError(Env<AttrContext> env, Symbol sym) { 2244 if (symbolPackageVisible(env, sym)) { 2245 return new AccessError(env, null, sym); 2246 } else { 2247 return new InvisibleSymbolError(env, false, sym); 2248 } 2249 } 2250 2251 private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) { 2252 ModuleSymbol envMod = env.toplevel.modle; 2253 PackageSymbol symPack = sym.packge(); 2254 return envMod == symPack.modle || 2255 envMod.visiblePackages.containsKey(symPack.fullname); 2256 } 2257 2258 /** 2259 * Find a type declared in a scope (not inherited). Return null 2260 * if none is found. 2261 * @param env The current environment. 2262 * @param site The original type from where the selection takes 2263 * place. 2264 * @param name The type's name. 2265 * @param c The class to search for the member type. This is 2266 * always a superclass or implemented interface of 2267 * site's class. 2268 */ 2269 Symbol findImmediateMemberType(Env<AttrContext> env, 2270 Type site, 2271 Name name, 2272 TypeSymbol c) { 2273 for (Symbol sym : c.members().getSymbolsByName(name)) { 2274 if (sym.kind == TYP) { 2275 return isAccessible(env, site, sym) 2276 ? sym 2277 : new AccessError(env, site, sym); 2278 } 2279 } 2280 return typeNotFound; 2281 } 2282 2283 /** Find a member type inherited from a superclass or interface. 2284 * @param env The current environment. 2285 * @param site The original type from where the selection takes 2286 * place. 2287 * @param name The type's name. 2288 * @param c The class to search for the member type. This is 2289 * always a superclass or implemented interface of 2290 * site's class. 2291 */ 2292 Symbol findInheritedMemberType(Env<AttrContext> env, 2293 Type site, 2294 Name name, 2295 TypeSymbol c) { 2296 Symbol bestSoFar = typeNotFound; 2297 Symbol sym; 2298 Type st = types.supertype(c.type); 2299 if (st != null && st.hasTag(CLASS)) { 2300 sym = findMemberType(env, site, name, st.tsym); 2301 bestSoFar = bestOf(bestSoFar, sym); 2302 } 2303 for (List<Type> l = types.interfaces(c.type); 2304 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 2305 l = l.tail) { 2306 sym = findMemberType(env, site, name, l.head.tsym); 2307 if (!bestSoFar.kind.isResolutionError() && 2308 !sym.kind.isResolutionError() && 2309 sym.owner != bestSoFar.owner) 2310 bestSoFar = new AmbiguityError(bestSoFar, sym); 2311 else 2312 bestSoFar = bestOf(bestSoFar, sym); 2313 } 2314 return bestSoFar; 2315 } 2316 2317 /** Find qualified member type. 2318 * @param env The current environment. 2319 * @param site The original type from where the selection takes 2320 * place. 2321 * @param name The type's name. 2322 * @param c The class to search for the member type. This is 2323 * always a superclass or implemented interface of 2324 * site's class. 2325 */ 2326 Symbol findMemberType(Env<AttrContext> env, 2327 Type site, 2328 Name name, 2329 TypeSymbol c) { 2330 Symbol sym = findImmediateMemberType(env, site, name, c); 2331 2332 if (sym != typeNotFound) 2333 return sym; 2334 2335 return findInheritedMemberType(env, site, name, c); 2336 2337 } 2338 2339 /** Find a global type in given scope and load corresponding class. 2340 * @param env The current environment. 2341 * @param scope The scope in which to look for the type. 2342 * @param name The type's name. 2343 */ 2344 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) { 2345 Symbol bestSoFar = typeNotFound; 2346 for (Symbol s : scope.getSymbolsByName(name)) { 2347 Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass); 2348 if (bestSoFar.kind == TYP && sym.kind == TYP && 2349 bestSoFar != sym) 2350 return new AmbiguityError(bestSoFar, sym); 2351 else 2352 bestSoFar = bestOf(bestSoFar, sym); 2353 } 2354 return bestSoFar; 2355 } 2356 2357 Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) { 2358 for (Symbol sym : env.info.scope.getSymbolsByName(name)) { 2359 if (sym.kind == TYP) { 2360 if (sym.type.hasTag(TYPEVAR) && 2361 (staticOnly || (isStatic(env) && sym.owner.kind == TYP))) 2362 // if staticOnly is set, it means that we have recursed through a static declaration, 2363 // so type variable symbols should not be accessible. If staticOnly is unset, but 2364 // we are in a static declaration (field or method), we should not allow type-variables 2365 // defined in the enclosing class to "leak" into this context. 2366 return new StaticError(sym); 2367 return sym; 2368 } 2369 } 2370 return typeNotFound; 2371 } 2372 2373 /** Find an unqualified type symbol. 2374 * @param env The current environment. 2375 * @param name The type's name. 2376 */ 2377 Symbol findType(Env<AttrContext> env, Name name) { 2378 if (name == names.empty) 2379 return typeNotFound; // do not allow inadvertent "lookup" of anonymous types 2380 Symbol bestSoFar = typeNotFound; 2381 Symbol sym; 2382 boolean staticOnly = false; 2383 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) { 2384 // First, look for a type variable and the first member type 2385 final Symbol tyvar = findTypeVar(env1, name, staticOnly); 2386 if (isStatic(env1)) staticOnly = true; 2387 sym = findImmediateMemberType(env1, env1.enclClass.sym.type, 2388 name, env1.enclClass.sym); 2389 2390 // Return the type variable if we have it, and have no 2391 // immediate member, OR the type variable is for a method. 2392 if (tyvar != typeNotFound) { 2393 if (env.baseClause || sym == typeNotFound || 2394 (tyvar.kind == TYP && tyvar.exists() && 2395 tyvar.owner.kind == MTH)) { 2396 return tyvar; 2397 } 2398 } 2399 2400 // If the environment is a class def, finish up, 2401 // otherwise, do the entire findMemberType 2402 if (sym == typeNotFound) 2403 sym = findInheritedMemberType(env1, env1.enclClass.sym.type, 2404 name, env1.enclClass.sym); 2405 2406 if (staticOnly && sym.kind == TYP && 2407 sym.type.hasTag(CLASS) && 2408 sym.type.getEnclosingType().hasTag(CLASS) && 2409 env1.enclClass.sym.type.isParameterized() && 2410 sym.type.getEnclosingType().isParameterized()) 2411 return new StaticError(sym); 2412 else if (sym.exists()) return sym; 2413 else bestSoFar = bestOf(bestSoFar, sym); 2414 2415 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass; 2416 if ((encl.sym.flags() & STATIC) != 0) 2417 staticOnly = true; 2418 } 2419 2420 if (!env.tree.hasTag(IMPORT)) { 2421 sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery); 2422 if (sym.exists()) return sym; 2423 else bestSoFar = bestOf(bestSoFar, sym); 2424 2425 sym = findGlobalType(env, env.toplevel.toplevelScope, name, noRecovery); 2426 if (sym.exists()) return sym; 2427 else bestSoFar = bestOf(bestSoFar, sym); 2428 2429 sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery); 2430 if (sym.exists()) return sym; 2431 else bestSoFar = bestOf(bestSoFar, sym); 2432 2433 sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery); 2434 if (sym.exists()) return sym; 2435 else bestSoFar = bestOf(bestSoFar, sym); 2436 } 2437 2438 return bestSoFar; 2439 } 2440 2441 /** Find an unqualified identifier which matches a specified kind set. 2442 * @param pos position on which report warnings, if any; 2443 * null warnings should not be reported 2444 * @param env The current environment. 2445 * @param name The identifier's name. 2446 * @param kind Indicates the possible symbol kinds 2447 * (a subset of VAL, TYP, PCK). 2448 */ 2449 Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) { 2450 try { 2451 return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name)); 2452 } catch (ClassFinder.BadClassFile err) { 2453 return new BadClassFileError(err); 2454 } catch (CompletionFailure cf) { 2455 chk.completionError(pos, cf); 2456 return typeNotFound; 2457 } 2458 } 2459 2460 Symbol findIdentInternal(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) { 2461 Symbol bestSoFar = typeNotFound; 2462 Symbol sym; 2463 2464 if (kind.contains(KindSelector.VAL)) { 2465 sym = findVar(pos, env, name); 2466 if (sym.exists()) return sym; 2467 else bestSoFar = bestOf(bestSoFar, sym); 2468 } 2469 2470 if (kind.contains(KindSelector.TYP)) { 2471 sym = findType(env, name); 2472 if (sym.exists()) return sym; 2473 else bestSoFar = bestOf(bestSoFar, sym); 2474 } 2475 2476 if (kind.contains(KindSelector.PCK)) 2477 return lookupPackage(env, name); 2478 else return bestSoFar; 2479 } 2480 2481 /** Find an identifier in a package which matches a specified kind set. 2482 * @param pos position on which report warnings, if any; 2483 * null warnings should not be reported 2484 * @param env The current environment. 2485 * @param name The identifier's name. 2486 * @param kind Indicates the possible symbol kinds 2487 * (a nonempty subset of TYP, PCK). 2488 */ 2489 Symbol findIdentInPackage(DiagnosticPosition pos, 2490 Env<AttrContext> env, TypeSymbol pck, 2491 Name name, KindSelector kind) { 2492 return checkNonExistentType(checkRestrictedType(pos, findIdentInPackageInternal(env, pck, name, kind), name)); 2493 } 2494 2495 Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck, 2496 Name name, KindSelector kind) { 2497 Name fullname = TypeSymbol.formFullName(name, pck); 2498 Symbol bestSoFar = typeNotFound; 2499 if (kind.contains(KindSelector.TYP)) { 2500 RecoveryLoadClass recoveryLoadClass = 2501 allowModules && !kind.contains(KindSelector.PCK) && 2502 !pck.exists() && !env.info.attributionMode.isSpeculative ? 2503 doRecoveryLoadClass : noRecovery; 2504 Symbol sym = loadClass(env, fullname, recoveryLoadClass); 2505 if (sym.exists()) { 2506 // don't allow programs to use flatnames 2507 if (name == sym.name) return sym; 2508 } 2509 else bestSoFar = bestOf(bestSoFar, sym); 2510 } 2511 if (kind.contains(KindSelector.PCK)) { 2512 return lookupPackage(env, fullname); 2513 } 2514 return bestSoFar; 2515 } 2516 2517 /** Find an identifier among the members of a given type `site'. 2518 * @param pos position on which report warnings, if any; 2519 * null warnings should not be reported 2520 * @param env The current environment. 2521 * @param site The type containing the symbol to be found. 2522 * @param name The identifier's name. 2523 * @param kind Indicates the possible symbol kinds 2524 * (a subset of VAL, TYP). 2525 */ 2526 Symbol findIdentInType(DiagnosticPosition pos, 2527 Env<AttrContext> env, Type site, 2528 Name name, KindSelector kind) { 2529 try { 2530 return checkNonExistentType(checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name)); 2531 } catch (ClassFinder.BadClassFile err) { 2532 return new BadClassFileError(err); 2533 } catch (CompletionFailure cf) { 2534 chk.completionError(pos, cf); 2535 return typeNotFound; 2536 } 2537 } 2538 2539 private Symbol checkNonExistentType(Symbol symbol) { 2540 /* Guard against returning a type is not on the class path of the current compilation, 2541 * but *was* on the class path of a separate compilation that produced a class file 2542 * that is on the class path of the current compilation. Such a type will fail completion 2543 * but the completion failure may have been silently swallowed (e.g. missing annotation types) 2544 * with an error stub symbol lingering in the symbol tables. 2545 */ 2546 return symbol instanceof ClassSymbol c && c.type.isErroneous() && c.classfile == null ? typeNotFound : symbol; 2547 } 2548 2549 Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site, 2550 Name name, KindSelector kind) { 2551 Symbol bestSoFar = typeNotFound; 2552 Symbol sym; 2553 if (kind.contains(KindSelector.VAL)) { 2554 sym = findField(env, site, name, site.tsym); 2555 if (sym.exists()) return sym; 2556 else bestSoFar = bestOf(bestSoFar, sym); 2557 } 2558 2559 if (kind.contains(KindSelector.TYP)) { 2560 sym = findMemberType(env, site, name, site.tsym); 2561 if (sym.exists()) return sym; 2562 else bestSoFar = bestOf(bestSoFar, sym); 2563 } 2564 return bestSoFar; 2565 } 2566 2567 private Symbol checkRestrictedType(DiagnosticPosition pos, Symbol bestSoFar, Name name) { 2568 if (bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP) { 2569 if (allowLocalVariableTypeInference && name.equals(names.var)) { 2570 bestSoFar = new BadRestrictedTypeError(names.var); 2571 } else if (name.equals(names.yield)) { 2572 if (allowYieldStatement) { 2573 bestSoFar = new BadRestrictedTypeError(names.yield); 2574 } else if (pos != null) { 2575 log.warning(pos, Warnings.IllegalRefToRestrictedType(names.yield)); 2576 } 2577 } 2578 } 2579 return bestSoFar; 2580 } 2581 2582 /* *************************************************************************** 2583 * Access checking 2584 * The following methods convert ResolveErrors to ErrorSymbols, issuing 2585 * an error message in the process 2586 ****************************************************************************/ 2587 2588 /** If `sym' is a bad symbol: report error and return errSymbol 2589 * else pass through unchanged, 2590 * additional arguments duplicate what has been used in trying to find the 2591 * symbol {@literal (--> flyweight pattern)}. This improves performance since we 2592 * expect misses to happen frequently. 2593 * 2594 * @param sym The symbol that was found, or a ResolveError. 2595 * @param pos The position to use for error reporting. 2596 * @param location The symbol the served as a context for this lookup 2597 * @param site The original type from where the selection took place. 2598 * @param name The symbol's name. 2599 * @param qualified Did we get here through a qualified expression resolution? 2600 * @param argtypes The invocation's value arguments, 2601 * if we looked for a method. 2602 * @param typeargtypes The invocation's type arguments, 2603 * if we looked for a method. 2604 * @param logResolveHelper helper class used to log resolve errors 2605 */ 2606 Symbol accessInternal(Symbol sym, 2607 DiagnosticPosition pos, 2608 Symbol location, 2609 Type site, 2610 Name name, 2611 boolean qualified, 2612 List<Type> argtypes, 2613 List<Type> typeargtypes, 2614 LogResolveHelper logResolveHelper) { 2615 if (sym.kind.isResolutionError()) { 2616 ResolveError errSym = (ResolveError)sym.baseSymbol(); 2617 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol); 2618 argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes); 2619 if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) { 2620 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes); 2621 } 2622 } 2623 return sym; 2624 } 2625 2626 /** 2627 * Variant of the generalized access routine, to be used for generating method 2628 * resolution diagnostics 2629 */ 2630 Symbol accessMethod(Symbol sym, 2631 DiagnosticPosition pos, 2632 Symbol location, 2633 Type site, 2634 Name name, 2635 boolean qualified, 2636 List<Type> argtypes, 2637 List<Type> typeargtypes) { 2638 return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper); 2639 } 2640 2641 /** Same as original accessMethod(), but without location. 2642 */ 2643 Symbol accessMethod(Symbol sym, 2644 DiagnosticPosition pos, 2645 Type site, 2646 Name name, 2647 boolean qualified, 2648 List<Type> argtypes, 2649 List<Type> typeargtypes) { 2650 return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes); 2651 } 2652 2653 /** 2654 * Variant of the generalized access routine, to be used for generating variable, 2655 * type resolution diagnostics 2656 */ 2657 Symbol accessBase(Symbol sym, 2658 DiagnosticPosition pos, 2659 Symbol location, 2660 Type site, 2661 Name name, 2662 boolean qualified) { 2663 return accessInternal(sym, pos, location, site, name, qualified, List.nil(), null, basicLogResolveHelper); 2664 } 2665 2666 /** Same as original accessBase(), but without location. 2667 */ 2668 Symbol accessBase(Symbol sym, 2669 DiagnosticPosition pos, 2670 Type site, 2671 Name name, 2672 boolean qualified) { 2673 return accessBase(sym, pos, site.tsym, site, name, qualified); 2674 } 2675 2676 interface LogResolveHelper { 2677 boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes); 2678 List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes); 2679 } 2680 2681 LogResolveHelper basicLogResolveHelper = new LogResolveHelper() { 2682 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2683 return !site.isErroneous(); 2684 } 2685 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2686 return argtypes; 2687 } 2688 }; 2689 2690 LogResolveHelper silentLogResolveHelper = new LogResolveHelper() { 2691 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2692 return false; 2693 } 2694 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2695 return argtypes; 2696 } 2697 }; 2698 2699 LogResolveHelper methodLogResolveHelper = new LogResolveHelper() { 2700 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2701 return !site.isErroneous() && 2702 !Type.isErroneous(argtypes) && 2703 (typeargtypes == null || !Type.isErroneous(typeargtypes)); 2704 } 2705 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2706 return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); 2707 } 2708 }; 2709 2710 class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap { 2711 2712 public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) { 2713 deferredAttr.super(mode, msym, step); 2714 } 2715 2716 @Override 2717 protected Type typeOf(DeferredType dt, Type pt) { 2718 Type res = super.typeOf(dt, pt); 2719 if (!res.isErroneous()) { 2720 switch (TreeInfo.skipParens(dt.tree).getTag()) { 2721 case LAMBDA: 2722 case REFERENCE: 2723 return dt; 2724 case CONDEXPR: 2725 return res == Type.recoveryType ? 2726 dt : res; 2727 } 2728 } 2729 return res; 2730 } 2731 } 2732 2733 /** Check that sym is not an abstract method. 2734 */ 2735 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { 2736 if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0) 2737 log.error(pos, 2738 Errors.AbstractCantBeAccessedDirectly(kindName(sym),sym, sym.location())); 2739 } 2740 2741 /* *************************************************************************** 2742 * Name resolution 2743 * Naming conventions are as for symbol lookup 2744 * Unlike the find... methods these methods will report access errors 2745 ****************************************************************************/ 2746 2747 /** Resolve an unqualified (non-method) identifier. 2748 * @param pos The position to use for error reporting. 2749 * @param env The environment current at the identifier use. 2750 * @param name The identifier's name. 2751 * @param kind The set of admissible symbol kinds for the identifier. 2752 */ 2753 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env, 2754 Name name, KindSelector kind) { 2755 return accessBase( 2756 findIdent(pos, env, name, kind), 2757 pos, env.enclClass.sym.type, name, false); 2758 } 2759 2760 /** Resolve an unqualified method identifier. 2761 * @param pos The position to use for error reporting. 2762 * @param env The environment current at the method invocation. 2763 * @param name The identifier's name. 2764 * @param argtypes The types of the invocation's value arguments. 2765 * @param typeargtypes The types of the invocation's type arguments. 2766 */ 2767 Symbol resolveMethod(DiagnosticPosition pos, 2768 Env<AttrContext> env, 2769 Name name, 2770 List<Type> argtypes, 2771 List<Type> typeargtypes) { 2772 return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck, 2773 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) { 2774 @Override 2775 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2776 return findFun(env, name, argtypes, typeargtypes, 2777 phase.isBoxingRequired(), 2778 phase.isVarargsRequired()); 2779 }}); 2780 } 2781 2782 /** Resolve a qualified method identifier 2783 * @param pos The position to use for error reporting. 2784 * @param env The environment current at the method invocation. 2785 * @param site The type of the qualifying expression, in which 2786 * identifier is searched. 2787 * @param name The identifier's name. 2788 * @param argtypes The types of the invocation's value arguments. 2789 * @param typeargtypes The types of the invocation's type arguments. 2790 */ 2791 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 2792 Type site, Name name, List<Type> argtypes, 2793 List<Type> typeargtypes) { 2794 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes); 2795 } 2796 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 2797 Symbol location, Type site, Name name, List<Type> argtypes, 2798 List<Type> typeargtypes) { 2799 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes); 2800 } 2801 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext, 2802 DiagnosticPosition pos, Env<AttrContext> env, 2803 Symbol location, Type site, Name name, List<Type> argtypes, 2804 List<Type> typeargtypes) { 2805 return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) { 2806 @Override 2807 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2808 return findMethod(env, site, name, argtypes, typeargtypes, 2809 phase.isBoxingRequired(), 2810 phase.isVarargsRequired()); 2811 } 2812 @Override 2813 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2814 if (sym.kind.isResolutionError()) { 2815 sym = super.access(env, pos, location, sym); 2816 } else { 2817 MethodSymbol msym = (MethodSymbol)sym; 2818 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) { 2819 env.info.pendingResolutionPhase = BASIC; 2820 return findPolymorphicSignatureInstance(env, sym, argtypes); 2821 } 2822 } 2823 return sym; 2824 } 2825 }); 2826 } 2827 2828 /** Find or create an implicit method of exactly the given type (after erasure). 2829 * Searches in a side table, not the main scope of the site. 2830 * This emulates the lookup process required by JSR 292 in JVM. 2831 * @param env Attribution environment 2832 * @param spMethod signature polymorphic method - i.e. MH.invokeExact 2833 * @param argtypes The required argument types 2834 */ 2835 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, 2836 final Symbol spMethod, 2837 List<Type> argtypes) { 2838 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, 2839 (MethodSymbol)spMethod, currentResolutionContext, argtypes); 2840 return findPolymorphicSignatureInstance(spMethod, mtype); 2841 } 2842 2843 Symbol findPolymorphicSignatureInstance(final Symbol spMethod, 2844 Type mtype) { 2845 for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) { 2846 // Check that there is already a method symbol for the method 2847 // type and owner 2848 if (types.isSameType(mtype, sym.type) && 2849 spMethod.owner == sym.owner) { 2850 return sym; 2851 } 2852 } 2853 2854 Type spReturnType = spMethod.asType().getReturnType(); 2855 if (types.isSameType(spReturnType, syms.objectType)) { 2856 // Polymorphic return, pass through mtype 2857 } else if (!types.isSameType(spReturnType, mtype.getReturnType())) { 2858 // Retain the sig poly method's return type, which differs from that of mtype 2859 // Will result in an incompatible return type error 2860 mtype = new MethodType(mtype.getParameterTypes(), 2861 spReturnType, 2862 mtype.getThrownTypes(), 2863 syms.methodClass); 2864 } 2865 2866 // Create the desired method 2867 // Retain static modifier is to support invocations to 2868 // MethodHandle.linkTo* methods 2869 long flags = ABSTRACT | HYPOTHETICAL | 2870 spMethod.flags() & (Flags.AccessFlags | Flags.STATIC); 2871 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) { 2872 @Override 2873 public Symbol baseSymbol() { 2874 return spMethod; 2875 } 2876 }; 2877 if (!mtype.isErroneous()) { // Cache only if kosher. 2878 polymorphicSignatureScope.enter(msym); 2879 } 2880 return msym; 2881 } 2882 2883 /** Resolve a qualified method identifier, throw a fatal error if not 2884 * found. 2885 * @param pos The position to use for error reporting. 2886 * @param env The environment current at the method invocation. 2887 * @param site The type of the qualifying expression, in which 2888 * identifier is searched. 2889 * @param name The identifier's name. 2890 * @param argtypes The types of the invocation's value arguments. 2891 * @param typeargtypes The types of the invocation's type arguments. 2892 */ 2893 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env, 2894 Type site, Name name, 2895 List<Type> argtypes, 2896 List<Type> typeargtypes) { 2897 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2898 resolveContext.internalResolution = true; 2899 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym, 2900 site, name, argtypes, typeargtypes); 2901 if (sym.kind == MTH) return (MethodSymbol)sym; 2902 else throw new FatalError( 2903 diags.fragment(Fragments.FatalErrCantLocateMeth(name))); 2904 } 2905 2906 /** Resolve constructor. 2907 * @param pos The position to use for error reporting. 2908 * @param env The environment current at the constructor invocation. 2909 * @param site The type of class for which a constructor is searched. 2910 * @param argtypes The types of the constructor invocation's value 2911 * arguments. 2912 * @param typeargtypes The types of the constructor invocation's type 2913 * arguments. 2914 */ 2915 Symbol resolveConstructor(DiagnosticPosition pos, 2916 Env<AttrContext> env, 2917 Type site, 2918 List<Type> argtypes, 2919 List<Type> typeargtypes) { 2920 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); 2921 } 2922 2923 private Symbol resolveConstructor(MethodResolutionContext resolveContext, 2924 final DiagnosticPosition pos, 2925 Env<AttrContext> env, 2926 Type site, 2927 List<Type> argtypes, 2928 List<Type> typeargtypes) { 2929 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 2930 @Override 2931 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2932 return findConstructor(pos, env, site, argtypes, typeargtypes, 2933 phase.isBoxingRequired(), 2934 phase.isVarargsRequired()); 2935 } 2936 }); 2937 } 2938 2939 /** Resolve a constructor, throw a fatal error if not found. 2940 * @param pos The position to use for error reporting. 2941 * @param env The environment current at the method invocation. 2942 * @param site The type to be constructed. 2943 * @param argtypes The types of the invocation's value arguments. 2944 * @param typeargtypes The types of the invocation's type arguments. 2945 */ 2946 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 2947 Type site, 2948 List<Type> argtypes, 2949 List<Type> typeargtypes) { 2950 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2951 resolveContext.internalResolution = true; 2952 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 2953 if (sym.kind == MTH) return (MethodSymbol)sym; 2954 else throw new FatalError( 2955 diags.fragment(Fragments.FatalErrCantLocateCtor(site))); 2956 } 2957 2958 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 2959 Type site, List<Type> argtypes, 2960 List<Type> typeargtypes, 2961 boolean allowBoxing, 2962 boolean useVarargs) { 2963 Symbol sym = findMethod(env, site, 2964 names.init, argtypes, 2965 typeargtypes, allowBoxing, 2966 useVarargs); 2967 chk.checkDeprecated(pos, env.info.scope.owner, sym); 2968 chk.checkPreview(pos, env.info.scope.owner, sym); 2969 return sym; 2970 } 2971 2972 /** Resolve constructor using diamond inference. 2973 * @param pos The position to use for error reporting. 2974 * @param env The environment current at the constructor invocation. 2975 * @param site The type of class for which a constructor is searched. 2976 * The scope of this class has been touched in attribution. 2977 * @param argtypes The types of the constructor invocation's value 2978 * arguments. 2979 * @param typeargtypes The types of the constructor invocation's type 2980 * arguments. 2981 */ 2982 Symbol resolveDiamond(DiagnosticPosition pos, 2983 Env<AttrContext> env, 2984 Type site, 2985 List<Type> argtypes, 2986 List<Type> typeargtypes) { 2987 return lookupMethod(env, pos, site.tsym, resolveMethodCheck, 2988 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 2989 @Override 2990 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2991 return findDiamond(pos, env, site, argtypes, typeargtypes, 2992 phase.isBoxingRequired(), 2993 phase.isVarargsRequired()); 2994 } 2995 @Override 2996 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2997 if (sym.kind.isResolutionError()) { 2998 if (sym.kind != WRONG_MTH && 2999 sym.kind != WRONG_MTHS) { 3000 sym = super.access(env, pos, location, sym); 3001 } else { 3002 sym = new DiamondError(sym, currentResolutionContext); 3003 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); 3004 env.info.pendingResolutionPhase = currentResolutionContext.step; 3005 } 3006 } 3007 return sym; 3008 }}); 3009 } 3010 3011 /** Find the constructor using diamond inference and do some checks(deprecated and preview). 3012 * @param pos The position to use for error reporting. 3013 * @param env The environment current at the constructor invocation. 3014 * @param site The type of class for which a constructor is searched. 3015 * The scope of this class has been touched in attribution. 3016 * @param argtypes The types of the constructor invocation's value arguments. 3017 * @param typeargtypes The types of the constructor invocation's type arguments. 3018 * @param allowBoxing Allow boxing conversions of arguments. 3019 * @param useVarargs Box trailing arguments into an array for varargs. 3020 */ 3021 private Symbol findDiamond(DiagnosticPosition pos, 3022 Env<AttrContext> env, 3023 Type site, 3024 List<Type> argtypes, 3025 List<Type> typeargtypes, 3026 boolean allowBoxing, 3027 boolean useVarargs) { 3028 Symbol sym = findDiamond(env, site, argtypes, typeargtypes, allowBoxing, useVarargs); 3029 chk.checkDeprecated(pos, env.info.scope.owner, sym); 3030 chk.checkPreview(pos, env.info.scope.owner, sym); 3031 return sym; 3032 } 3033 3034 /** This method scans all the constructor symbol in a given class scope - 3035 * assuming that the original scope contains a constructor of the kind: 3036 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo, 3037 * a method check is executed against the modified constructor type: 3038 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond 3039 * inference. The inferred return type of the synthetic constructor IS 3040 * the inferred type for the diamond operator. 3041 */ 3042 private Symbol findDiamond(Env<AttrContext> env, 3043 Type site, 3044 List<Type> argtypes, 3045 List<Type> typeargtypes, 3046 boolean allowBoxing, 3047 boolean useVarargs) { 3048 Symbol bestSoFar = methodNotFound; 3049 TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym; 3050 for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) { 3051 //- System.out.println(" e " + e.sym); 3052 if (sym.kind == MTH && 3053 (sym.flags_field & SYNTHETIC) == 0) { 3054 List<Type> oldParams = sym.type.hasTag(FORALL) ? 3055 ((ForAll)sym.type).tvars : 3056 List.nil(); 3057 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), 3058 types.createMethodTypeWithReturn(sym.type.asMethodType(), site)); 3059 MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) { 3060 @Override 3061 public Symbol baseSymbol() { 3062 return sym; 3063 } 3064 }; 3065 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 3066 newConstr, 3067 bestSoFar, 3068 allowBoxing, 3069 useVarargs); 3070 } 3071 } 3072 return bestSoFar; 3073 } 3074 3075 Symbol getMemberReference(DiagnosticPosition pos, 3076 Env<AttrContext> env, 3077 JCMemberReference referenceTree, 3078 Type site, 3079 Name name) { 3080 3081 site = types.capture(site); 3082 3083 ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper( 3084 referenceTree, site, name, List.nil(), null, VARARITY); 3085 3086 Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup()); 3087 Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym, 3088 nilMethodCheck, lookupHelper); 3089 3090 env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase; 3091 3092 return sym; 3093 } 3094 3095 ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree, 3096 Type site, 3097 Name name, 3098 List<Type> argtypes, 3099 List<Type> typeargtypes, 3100 MethodResolutionPhase maxPhase) { 3101 if (!name.equals(names.init)) { 3102 //method reference 3103 return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); 3104 } else if (site.hasTag(ARRAY)) { 3105 //array constructor reference 3106 return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); 3107 } else { 3108 //class constructor reference 3109 return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); 3110 } 3111 } 3112 3113 /** 3114 * Resolution of member references is typically done as a single 3115 * overload resolution step, where the argument types A are inferred from 3116 * the target functional descriptor. 3117 * 3118 * If the member reference is a method reference with a type qualifier, 3119 * a two-step lookup process is performed. The first step uses the 3120 * expected argument list A, while the second step discards the first 3121 * type from A (which is treated as a receiver type). 3122 * 3123 * There are two cases in which inference is performed: (i) if the member 3124 * reference is a constructor reference and the qualifier type is raw - in 3125 * which case diamond inference is used to infer a parameterization for the 3126 * type qualifier; (ii) if the member reference is an unbound reference 3127 * where the type qualifier is raw - in that case, during the unbound lookup 3128 * the receiver argument type is used to infer an instantiation for the raw 3129 * qualifier type. 3130 * 3131 * When a multi-step resolution process is exploited, the process of picking 3132 * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}. 3133 * 3134 * This routine returns a pair (T,S), where S is the member reference symbol, 3135 * and T is the type of the class in which S is defined. This is necessary as 3136 * the type T might be dynamically inferred (i.e. if constructor reference 3137 * has a raw qualifier). 3138 */ 3139 Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env, 3140 JCMemberReference referenceTree, 3141 Type site, 3142 Name name, 3143 List<Type> argtypes, 3144 List<Type> typeargtypes, 3145 Type descriptor, 3146 MethodCheck methodCheck, 3147 InferenceContext inferenceContext, 3148 ReferenceChooser referenceChooser) { 3149 3150 //step 1 - bound lookup 3151 ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( 3152 referenceTree, site, name, argtypes, typeargtypes, VARARITY); 3153 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup()); 3154 MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext(); 3155 boundSearchResolveContext.methodCheck = methodCheck; 3156 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), 3157 site.tsym, boundSearchResolveContext, boundLookupHelper); 3158 boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names); 3159 ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext, isStaticSelector); 3160 if (dumpMethodReferenceSearchResults) { 3161 dumpMethodReferenceSearchResults(referenceTree, boundSearchResolveContext, boundSym, true); 3162 } 3163 3164 //step 2 - unbound lookup 3165 Symbol unboundSym = methodNotFound; 3166 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup()); 3167 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); 3168 ReferenceLookupResult unboundRes = referenceNotFound; 3169 if (unboundLookupHelper != null) { 3170 MethodResolutionContext unboundSearchResolveContext = 3171 new MethodResolutionContext(); 3172 unboundSearchResolveContext.methodCheck = methodCheck; 3173 unboundSym = lookupMethod(unboundEnv, env.tree.pos(), 3174 site.tsym, unboundSearchResolveContext, unboundLookupHelper); 3175 unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext, isStaticSelector); 3176 if (dumpMethodReferenceSearchResults) { 3177 dumpMethodReferenceSearchResults(referenceTree, unboundSearchResolveContext, unboundSym, false); 3178 } 3179 } 3180 3181 //merge results 3182 Pair<Symbol, ReferenceLookupHelper> res; 3183 ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes); 3184 res = new Pair<>(bestRes.sym, 3185 bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper); 3186 env.info.pendingResolutionPhase = bestRes == unboundRes ? 3187 unboundEnv.info.pendingResolutionPhase : 3188 boundEnv.info.pendingResolutionPhase; 3189 3190 if (!res.fst.kind.isResolutionError()) { 3191 //handle sigpoly method references 3192 MethodSymbol msym = (MethodSymbol)res.fst; 3193 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) { 3194 env.info.pendingResolutionPhase = BASIC; 3195 res = new Pair<>(findPolymorphicSignatureInstance(msym, descriptor), res.snd); 3196 } 3197 } 3198 3199 return res; 3200 } 3201 3202 private void dumpMethodReferenceSearchResults(JCMemberReference referenceTree, 3203 MethodResolutionContext resolutionContext, 3204 Symbol bestSoFar, 3205 boolean bound) { 3206 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>(); 3207 int pos = 0; 3208 int mostSpecificPos = -1; 3209 for (Candidate c : resolutionContext.candidates) { 3210 if (resolutionContext.step != c.step || !c.isApplicable()) { 3211 continue; 3212 } else { 3213 JCDiagnostic subDiag = null; 3214 if (c.sym.type.hasTag(FORALL)) { 3215 subDiag = diags.fragment(Fragments.PartialInstSig(c.mtype)); 3216 } 3217 3218 String key = subDiag == null ? 3219 "applicable.method.found.2" : 3220 "applicable.method.found.3"; 3221 subDiags.append(diags.fragment(key, pos, 3222 c.sym.isStatic() ? Fragments.Static : Fragments.NonStatic, c.sym, subDiag)); 3223 if (c.sym == bestSoFar) 3224 mostSpecificPos = pos; 3225 pos++; 3226 } 3227 } 3228 JCDiagnostic main = diags.note( 3229 log.currentSource(), 3230 referenceTree, 3231 "method.ref.search.results.multi", 3232 bound ? Fragments.Bound : Fragments.Unbound, 3233 referenceTree.toString(), mostSpecificPos); 3234 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); 3235 log.report(d); 3236 } 3237 3238 /** 3239 * This class is used to represent a method reference lookup result. It keeps track of two 3240 * things: (i) the symbol found during a method reference lookup and (ii) the static kind 3241 * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}). 3242 */ 3243 static class ReferenceLookupResult { 3244 3245 /** 3246 * Static kind associated with a method reference lookup. Erroneous lookups end up with 3247 * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC, 3248 * depending on whether all applicable candidates are static or non-static methods, 3249 * respectively. If a successful lookup has both static and non-static applicable methods, 3250 * its kind is set to BOTH. 3251 */ 3252 enum StaticKind { 3253 STATIC, 3254 NON_STATIC, 3255 BOTH, 3256 UNDEFINED; 3257 3258 /** 3259 * Retrieve the static kind associated with a given (method) symbol. 3260 */ 3261 static StaticKind from(Symbol s) { 3262 return s.isStatic() ? 3263 STATIC : NON_STATIC; 3264 } 3265 3266 /** 3267 * Merge two static kinds together. 3268 */ 3269 static StaticKind reduce(StaticKind sk1, StaticKind sk2) { 3270 if (sk1 == UNDEFINED) { 3271 return sk2; 3272 } else if (sk2 == UNDEFINED) { 3273 return sk1; 3274 } else { 3275 return sk1 == sk2 ? sk1 : BOTH; 3276 } 3277 } 3278 } 3279 3280 /** The static kind. */ 3281 StaticKind staticKind; 3282 3283 /** The lookup result. */ 3284 Symbol sym; 3285 3286 ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) { 3287 this(sym, staticKind(sym, resolutionContext, isStaticSelector)); 3288 } 3289 3290 private ReferenceLookupResult(Symbol sym, StaticKind staticKind) { 3291 this.staticKind = staticKind; 3292 this.sym = sym; 3293 } 3294 3295 private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) { 3296 if (sym.kind == MTH && !isStaticSelector) { 3297 return StaticKind.from(sym); 3298 } else if (sym.kind == MTH || sym.kind == AMBIGUOUS) { 3299 return resolutionContext.candidates.stream() 3300 .filter(c -> c.isApplicable() && c.step == resolutionContext.step) 3301 .map(c -> StaticKind.from(c.sym)) 3302 .reduce(StaticKind::reduce) 3303 .orElse(StaticKind.UNDEFINED); 3304 } else { 3305 return StaticKind.UNDEFINED; 3306 } 3307 } 3308 3309 /** 3310 * Does this result corresponds to a successful lookup (i.e. one where a method has been found?) 3311 */ 3312 boolean isSuccess() { 3313 return staticKind != StaticKind.UNDEFINED; 3314 } 3315 3316 /** 3317 * Does this result have given static kind? 3318 */ 3319 boolean hasKind(StaticKind sk) { 3320 return this.staticKind == sk; 3321 } 3322 3323 /** 3324 * Error recovery helper: can this lookup result be ignored (for the purpose of returning 3325 * some 'better' result) ? 3326 */ 3327 boolean canIgnore() { 3328 switch (sym.kind) { 3329 case ABSENT_MTH: 3330 return true; 3331 case WRONG_MTH: 3332 InapplicableSymbolError errSym = 3333 (InapplicableSymbolError)sym.baseSymbol(); 3334 return new Template(MethodCheckDiag.ARITY_MISMATCH.regex()) 3335 .matches(errSym.errCandidate().snd); 3336 case WRONG_MTHS: 3337 InapplicableSymbolsError errSyms = 3338 (InapplicableSymbolsError)sym.baseSymbol(); 3339 return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty(); 3340 default: 3341 return false; 3342 } 3343 } 3344 3345 static ReferenceLookupResult error(Symbol sym) { 3346 return new ReferenceLookupResult(sym, StaticKind.UNDEFINED); 3347 } 3348 } 3349 3350 /** 3351 * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup) 3352 * {@code ReferenceLookupResult} objects into a {@code Symbol}, which is then regarded as the 3353 * result of method reference resolution. 3354 */ 3355 abstract class ReferenceChooser { 3356 /** 3357 * Generate a result from a pair of lookup result objects. This method delegates to the 3358 * appropriate result generation routine. 3359 */ 3360 ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { 3361 return unboundRes != referenceNotFound ? 3362 unboundResult(boundRes, unboundRes) : 3363 boundResult(boundRes); 3364 } 3365 3366 /** 3367 * Generate a symbol from a given bound lookup result. 3368 */ 3369 abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes); 3370 3371 /** 3372 * Generate a symbol from a pair of bound/unbound lookup results. 3373 */ 3374 abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes); 3375 } 3376 3377 /** 3378 * This chooser implements the selection strategy used during a full lookup; this logic 3379 * is described in JLS SE 8 (15.3.2). 3380 */ 3381 ReferenceChooser basicReferenceChooser = new ReferenceChooser() { 3382 3383 @Override 3384 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) { 3385 return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ? 3386 boundRes : //the search produces a non-static method 3387 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false)); 3388 } 3389 3390 @Override 3391 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { 3392 if (boundRes.isSuccess() && boundRes.sym.isStatic() && 3393 (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) { 3394 //the first search produces a static method and no non-static method is applicable 3395 //during the second search 3396 return boundRes; 3397 } else if (unboundRes.isSuccess() && !unboundRes.sym.isStatic() && 3398 (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) { 3399 //the second search produces a non-static method and no static method is applicable 3400 //during the first search 3401 return unboundRes; 3402 } else if (boundRes.isSuccess() && unboundRes.isSuccess()) { 3403 //both searches produce some result; ambiguity (error recovery) 3404 return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym)); 3405 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) { 3406 //Both searches failed to produce a result with correct staticness (i.e. first search 3407 //produces an non-static method). Alternatively, a given search produced a result 3408 //with the right staticness, but the other search has applicable methods with wrong 3409 //staticness (error recovery) 3410 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ? 3411 boundRes.sym : unboundRes.sym, true)); 3412 } else { 3413 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery) 3414 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ? 3415 unboundRes : boundRes; 3416 } 3417 } 3418 }; 3419 3420 /** 3421 * This chooser implements the selection strategy used during an arity-based lookup; this logic 3422 * is described in JLS SE 8 (15.12.2.1). 3423 */ 3424 ReferenceChooser structuralReferenceChooser = new ReferenceChooser() { 3425 3426 @Override 3427 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) { 3428 return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ? 3429 boundRes : //the search has at least one applicable non-static method 3430 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false)); 3431 } 3432 3433 @Override 3434 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { 3435 if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) { 3436 //the first search has at least one applicable static method 3437 return boundRes; 3438 } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) { 3439 //the second search has at least one applicable non-static method 3440 return unboundRes; 3441 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) { 3442 //either the first search produces a non-static method, or second search produces 3443 //a non-static method (error recovery) 3444 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ? 3445 boundRes.sym : unboundRes.sym, true)); 3446 } else { 3447 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery) 3448 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ? 3449 unboundRes : boundRes; 3450 } 3451 } 3452 }; 3453 3454 /** 3455 * Helper for defining custom method-like lookup logic; a lookup helper 3456 * provides hooks for (i) the actual lookup logic and (ii) accessing the 3457 * lookup result (this step might result in compiler diagnostics to be generated) 3458 */ 3459 abstract class LookupHelper { 3460 3461 /** name of the symbol to lookup */ 3462 Name name; 3463 3464 /** location in which the lookup takes place */ 3465 Type site; 3466 3467 /** actual types used during the lookup */ 3468 List<Type> argtypes; 3469 3470 /** type arguments used during the lookup */ 3471 List<Type> typeargtypes; 3472 3473 /** Max overload resolution phase handled by this helper */ 3474 MethodResolutionPhase maxPhase; 3475 3476 LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3477 this.name = name; 3478 this.site = site; 3479 this.argtypes = argtypes; 3480 this.typeargtypes = typeargtypes; 3481 this.maxPhase = maxPhase; 3482 } 3483 3484 /** 3485 * Should lookup stop at given phase with given result 3486 */ 3487 final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { 3488 return phase.ordinal() > maxPhase.ordinal() || 3489 !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS || sym.kind == STATICERR; 3490 } 3491 3492 /** 3493 * Search for a symbol under a given overload resolution phase - this method 3494 * is usually called several times, once per each overload resolution phase 3495 */ 3496 abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase); 3497 3498 /** 3499 * Dump overload resolution info 3500 */ 3501 void debug(DiagnosticPosition pos, Symbol sym) { 3502 //do nothing 3503 } 3504 3505 /** 3506 * Validate the result of the lookup 3507 */ 3508 abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym); 3509 } 3510 3511 abstract class BasicLookupHelper extends LookupHelper { 3512 3513 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) { 3514 this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY); 3515 } 3516 3517 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3518 super(name, site, argtypes, typeargtypes, maxPhase); 3519 } 3520 3521 @Override 3522 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 3523 if (sym.kind.isResolutionError()) { 3524 //if nothing is found return the 'first' error 3525 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes); 3526 } 3527 return sym; 3528 } 3529 3530 @Override 3531 void debug(DiagnosticPosition pos, Symbol sym) { 3532 reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym); 3533 } 3534 } 3535 3536 /** 3537 * Helper class for member reference lookup. A reference lookup helper 3538 * defines the basic logic for member reference lookup; a method gives 3539 * access to an 'unbound' helper used to perform an unbound member 3540 * reference lookup. 3541 */ 3542 abstract class ReferenceLookupHelper extends LookupHelper { 3543 3544 /** The member reference tree */ 3545 JCMemberReference referenceTree; 3546 3547 ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 3548 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3549 super(name, site, argtypes, typeargtypes, maxPhase); 3550 this.referenceTree = referenceTree; 3551 } 3552 3553 /** 3554 * Returns an unbound version of this lookup helper. By default, this 3555 * method returns an dummy lookup helper. 3556 */ 3557 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3558 return null; 3559 } 3560 3561 /** 3562 * Get the kind of the member reference 3563 */ 3564 abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym); 3565 3566 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 3567 //skip error reporting 3568 return sym; 3569 } 3570 } 3571 3572 /** 3573 * Helper class for method reference lookup. The lookup logic is based 3574 * upon Resolve.findMethod; in certain cases, this helper class has a 3575 * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper). 3576 * In such cases, non-static lookup results are thrown away. 3577 */ 3578 class MethodReferenceLookupHelper extends ReferenceLookupHelper { 3579 3580 /** The original method reference lookup site. */ 3581 Type originalSite; 3582 3583 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 3584 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3585 super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase); 3586 this.originalSite = site; 3587 } 3588 3589 @Override 3590 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3591 return findMethod(env, site, name, argtypes, typeargtypes, 3592 phase.isBoxingRequired(), phase.isVarargsRequired()); 3593 } 3594 3595 @Override 3596 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3597 if (TreeInfo.isStaticSelector(referenceTree.expr, names)) { 3598 if (argtypes.nonEmpty() && 3599 (argtypes.head.hasTag(NONE) || 3600 types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) { 3601 return new UnboundMethodReferenceLookupHelper(referenceTree, name, 3602 originalSite, argtypes, typeargtypes, maxPhase); 3603 } else { 3604 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { 3605 @Override 3606 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3607 return this; 3608 } 3609 3610 @Override 3611 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3612 return methodNotFound; 3613 } 3614 3615 @Override 3616 ReferenceKind referenceKind(Symbol sym) { 3617 Assert.error(); 3618 return null; 3619 } 3620 }; 3621 } 3622 } else { 3623 return super.unboundLookup(inferenceContext); 3624 } 3625 } 3626 3627 @Override 3628 ReferenceKind referenceKind(Symbol sym) { 3629 if (sym.isStatic()) { 3630 return ReferenceKind.STATIC; 3631 } else { 3632 Name selName = TreeInfo.name(referenceTree.getQualifierExpression()); 3633 return selName != null && selName == names._super ? 3634 ReferenceKind.SUPER : 3635 ReferenceKind.BOUND; 3636 } 3637 } 3638 3639 @Override 3640 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 3641 if (originalSite.hasTag(TYPEVAR) && sym.kind == MTH) { 3642 sym = (sym.flags() & Flags.PRIVATE) != 0 ? 3643 new AccessError(env, site, sym) : 3644 sym; 3645 return accessBase(sym, pos, location, originalSite, name, true); 3646 } else { 3647 return super.access(env, pos, location, sym); 3648 } 3649 } 3650 } 3651 3652 /** 3653 * Helper class for unbound method reference lookup. Essentially the same 3654 * as the basic method reference lookup helper; main difference is that static 3655 * lookup results are thrown away. If qualifier type is raw, an attempt to 3656 * infer a parameterized type is made using the first actual argument (that 3657 * would otherwise be ignored during the lookup). 3658 */ 3659 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper { 3660 3661 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 3662 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3663 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase); 3664 if (site.isRaw() && !argtypes.head.hasTag(NONE)) { 3665 Type asSuperSite = types.asSuper(argtypes.head, site.tsym); 3666 this.site = types.skipTypeVars(asSuperSite, true); 3667 } 3668 } 3669 3670 @Override 3671 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3672 return this; 3673 } 3674 3675 @Override 3676 ReferenceKind referenceKind(Symbol sym) { 3677 return ReferenceKind.UNBOUND; 3678 } 3679 } 3680 3681 /** 3682 * Helper class for array constructor lookup; an array constructor lookup 3683 * is simulated by looking up a method that returns the array type specified 3684 * as qualifier, and that accepts a single int parameter (size of the array). 3685 */ 3686 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper { 3687 3688 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 3689 List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3690 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 3691 } 3692 3693 @Override 3694 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3695 WriteableScope sc = WriteableScope.create(syms.arrayClass); 3696 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); 3697 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass); 3698 sc.enter(arrayConstr); 3699 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false); 3700 } 3701 3702 @Override 3703 ReferenceKind referenceKind(Symbol sym) { 3704 return ReferenceKind.ARRAY_CTOR; 3705 } 3706 } 3707 3708 /** 3709 * Helper class for constructor reference lookup. The lookup logic is based 3710 * upon either Resolve.findMethod or Resolve.findDiamond - depending on 3711 * whether the constructor reference needs diamond inference (this is the case 3712 * if the qualifier type is raw). A special erroneous symbol is returned 3713 * if the lookup returns the constructor of an inner class and there's no 3714 * enclosing instance in scope. 3715 */ 3716 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper { 3717 3718 boolean needsInference; 3719 3720 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 3721 List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3722 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 3723 if (site.isRaw()) { 3724 this.site = new ClassType(site.getEnclosingType(), 3725 !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ? 3726 site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata()); 3727 needsInference = true; 3728 } 3729 } 3730 3731 @Override 3732 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3733 Symbol sym = needsInference ? 3734 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : 3735 findMethod(env, site, name, argtypes, typeargtypes, 3736 phase.isBoxingRequired(), phase.isVarargsRequired()); 3737 return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym; 3738 } 3739 3740 @Override 3741 ReferenceKind referenceKind(Symbol sym) { 3742 return site.getEnclosingType().hasTag(NONE) ? 3743 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER; 3744 } 3745 } 3746 3747 /** 3748 * Main overload resolution routine. On each overload resolution step, a 3749 * lookup helper class is used to perform the method/constructor lookup; 3750 * at the end of the lookup, the helper is used to validate the results 3751 * (this last step might trigger overload resolution diagnostics). 3752 */ 3753 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) { 3754 MethodResolutionContext resolveContext = new MethodResolutionContext(); 3755 resolveContext.methodCheck = methodCheck; 3756 return lookupMethod(env, pos, location, resolveContext, lookupHelper); 3757 } 3758 3759 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, 3760 MethodResolutionContext resolveContext, LookupHelper lookupHelper) { 3761 MethodResolutionContext prevResolutionContext = currentResolutionContext; 3762 try { 3763 Symbol bestSoFar = methodNotFound; 3764 currentResolutionContext = resolveContext; 3765 for (MethodResolutionPhase phase : methodResolutionSteps) { 3766 if (lookupHelper.shouldStop(bestSoFar, phase)) 3767 break; 3768 MethodResolutionPhase prevPhase = currentResolutionContext.step; 3769 Symbol prevBest = bestSoFar; 3770 currentResolutionContext.step = phase; 3771 Symbol sym = lookupHelper.lookup(env, phase); 3772 lookupHelper.debug(pos, sym); 3773 bestSoFar = phase.mergeResults(bestSoFar, sym); 3774 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase; 3775 } 3776 return lookupHelper.access(env, pos, location, bestSoFar); 3777 } finally { 3778 currentResolutionContext = prevResolutionContext; 3779 } 3780 } 3781 3782 /** 3783 * Resolve `c.name' where name == this or name == super. 3784 * @param pos The position to use for error reporting. 3785 * @param env The environment current at the expression. 3786 * @param c The qualifier. 3787 * @param name The identifier's name. 3788 */ 3789 Symbol resolveSelf(DiagnosticPosition pos, 3790 Env<AttrContext> env, 3791 TypeSymbol c, 3792 Name name) { 3793 Assert.check(name == names._this || name == names._super); 3794 Env<AttrContext> env1 = env; 3795 boolean staticOnly = false; 3796 while (env1.outer != null) { 3797 if (isStatic(env1)) staticOnly = true; 3798 if (env1.enclClass.sym == c) { 3799 Symbol sym = env1.info.scope.findFirst(name); 3800 if (sym != null) { 3801 if (staticOnly) 3802 sym = new StaticError(sym); 3803 else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) 3804 sym = new RefBeforeCtorCalledError(sym); 3805 return accessBase(sym, pos, env.enclClass.sym.type, 3806 name, true); 3807 } 3808 } 3809 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 3810 env1 = env1.outer; 3811 } 3812 if (c.isInterface() && 3813 name == names._super && !isStatic(env) && 3814 types.isDirectSuperInterface(c, env.enclClass.sym)) { 3815 //this might be a default super call if one of the superinterfaces is 'c' 3816 for (Type t : pruneInterfaces(env.enclClass.type)) { 3817 if (t.tsym == c) { 3818 if (env.info.ctorPrologue) 3819 log.error(pos, Errors.CantRefBeforeCtorCalled(name)); 3820 env.info.defaultSuperCallSite = t; 3821 return new VarSymbol(0, names._super, 3822 types.asSuper(env.enclClass.type, c), env.enclClass.sym); 3823 } 3824 } 3825 //find a direct supertype that is a subtype of 'c' 3826 for (Type i : types.directSupertypes(env.enclClass.type)) { 3827 if (i.tsym.isSubClass(c, types) && i.tsym != c) { 3828 log.error(pos, 3829 Errors.IllegalDefaultSuperCall(c, 3830 Fragments.RedundantSupertype(c, i))); 3831 return syms.errSymbol; 3832 } 3833 } 3834 Assert.error(); 3835 } 3836 log.error(pos, Errors.NotEnclClass(c)); 3837 return syms.errSymbol; 3838 } 3839 //where 3840 private List<Type> pruneInterfaces(Type t) { 3841 ListBuffer<Type> result = new ListBuffer<>(); 3842 for (Type t1 : types.interfaces(t)) { 3843 boolean shouldAdd = true; 3844 for (Type t2 : types.directSupertypes(t)) { 3845 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) { 3846 shouldAdd = false; 3847 } 3848 } 3849 if (shouldAdd) { 3850 result.append(t1); 3851 } 3852 } 3853 return result.toList(); 3854 } 3855 3856 /** 3857 * Determine if an early instance field reference may appear in a constructor prologue. 3858 * 3859 * <p> 3860 * This is only allowed when: 3861 * - The field is being assigned a value (i.e., written but not read) 3862 * - The field is not inherited from a superclass 3863 * - The assignment is not within a lambda, because that would require 3864 * capturing 'this' which is not allowed prior to super(). 3865 * 3866 * <p> 3867 * Note, this method doesn't catch all such scenarios, because this method 3868 * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42". 3869 * We also don't verify that the field has no initializer, which is required. 3870 * To catch those cases, we rely on similar logic in Attr.checkAssignable(). 3871 */ 3872 private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) { 3873 3874 // Check assumptions 3875 Assert.check(env.info.ctorPrologue); 3876 Assert.check((v.flags_field & STATIC) == 0); 3877 3878 // The symbol must appear in the LHS of an assignment statement 3879 if (!(env.tree instanceof JCAssign assign)) 3880 return false; 3881 3882 // The assignment statement must not be within a lambda 3883 if (env.info.isLambda) 3884 return false; 3885 3886 // Get the symbol's qualifier, if any 3887 JCExpression lhs = TreeInfo.skipParens(assign.lhs); 3888 JCExpression base; 3889 switch (lhs.getTag()) { 3890 case IDENT: 3891 base = null; 3892 break; 3893 case SELECT: 3894 JCFieldAccess select = (JCFieldAccess)lhs; 3895 base = select.selected; 3896 if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base)) 3897 return false; 3898 break; 3899 default: 3900 return false; 3901 } 3902 3903 // If an early reference, the field must not be declared in a superclass 3904 if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym) 3905 return false; 3906 3907 // The flexible constructors feature must be enabled 3908 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS); 3909 3910 // OK 3911 return true; 3912 } 3913 3914 /** 3915 * Determine if the variable appearance constitutes an early reference to the current class. 3916 * 3917 * <p> 3918 * This means the variable is an instance field of the current class and it appears 3919 * in an early initialization context of it (i.e., one of its constructor prologues). 3920 * 3921 * <p> 3922 * Such a reference is only allowed for assignments to non-initialized fields that are 3923 * not inherited from a superclass, though that is not enforced by this method. 3924 * 3925 * @param env The current environment 3926 * @param base Variable qualifier, if any, otherwise null 3927 * @param v The variable 3928 */ 3929 public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) { 3930 return env.info.ctorPrologue && 3931 (v.flags() & STATIC) == 0 && 3932 v.owner.kind == TYP && 3933 types.isSubtype(env.enclClass.type, v.owner.type) && 3934 (base == null || TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base)); 3935 } 3936 3937 /** 3938 * Resolve `c.this' for an enclosing class c that contains the 3939 * named member. 3940 * @param pos The position to use for error reporting. 3941 * @param env The environment current at the expression. 3942 * @param member The member that must be contained in the result. 3943 */ 3944 Symbol resolveSelfContaining(DiagnosticPosition pos, 3945 Env<AttrContext> env, 3946 Symbol member, 3947 boolean isSuperCall) { 3948 Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall); 3949 if (sym == null) { 3950 log.error(pos, Errors.EnclClassRequired(member)); 3951 return syms.errSymbol; 3952 } else { 3953 return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true); 3954 } 3955 } 3956 3957 boolean enclosingInstanceMissing(Env<AttrContext> env, Type type) { 3958 if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) { 3959 Symbol encl = resolveSelfContainingInternal(env, type.tsym, false); 3960 return encl == null || encl.kind.isResolutionError(); 3961 } 3962 return false; 3963 } 3964 3965 private Symbol resolveSelfContainingInternal(Env<AttrContext> env, 3966 Symbol member, 3967 boolean isSuperCall) { 3968 Name name = names._this; 3969 Env<AttrContext> env1 = isSuperCall ? env.outer : env; 3970 boolean staticOnly = false; 3971 if (env1 != null) { 3972 while (env1 != null && env1.outer != null) { 3973 if (isStatic(env1)) staticOnly = true; 3974 if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) { 3975 Symbol sym = env1.info.scope.findFirst(name); 3976 if (sym != null) { 3977 if (staticOnly) sym = new StaticError(sym); 3978 return sym; 3979 } 3980 } 3981 if ((env1.enclClass.sym.flags() & STATIC) != 0) 3982 staticOnly = true; 3983 env1 = env1.outer; 3984 } 3985 } 3986 return null; 3987 } 3988 3989 /** 3990 * Resolve an appropriate implicit this instance for t's container. 3991 * JLS 8.8.5.1 and 15.9.2 3992 */ 3993 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) { 3994 return resolveImplicitThis(pos, env, t, false); 3995 } 3996 3997 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) { 3998 Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH) 3999 ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) 4000 : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; 4001 if (env.info.ctorPrologue && thisType.tsym == env.enclClass.sym) { 4002 log.error(pos, Errors.CantRefBeforeCtorCalled(names._this)); 4003 } 4004 return thisType; 4005 } 4006 4007 /* *************************************************************************** 4008 * ResolveError classes, indicating error situations when accessing symbols 4009 ****************************************************************************/ 4010 4011 //used by TransTypes when checking target type of synthetic cast 4012 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) { 4013 AccessError error = new AccessError(env, env.enclClass.type, type.tsym); 4014 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null); 4015 } 4016 //where 4017 private void logResolveError(ResolveError error, 4018 DiagnosticPosition pos, 4019 Symbol location, 4020 Type site, 4021 Name name, 4022 List<Type> argtypes, 4023 List<Type> typeargtypes) { 4024 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 4025 pos, location, site, name, argtypes, typeargtypes); 4026 if (d != null) { 4027 d.setFlag(DiagnosticFlag.RESOLVE_ERROR); 4028 log.report(d); 4029 } 4030 } 4031 4032 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); 4033 4034 public Object methodArguments(List<Type> argtypes) { 4035 if (argtypes == null || argtypes.isEmpty()) { 4036 return noArgs; 4037 } else { 4038 ListBuffer<Object> diagArgs = new ListBuffer<>(); 4039 for (Type t : argtypes) { 4040 if (t.hasTag(DEFERRED)) { 4041 diagArgs.append(((DeferredAttr.DeferredType)t).tree); 4042 } else { 4043 diagArgs.append(t); 4044 } 4045 } 4046 return diagArgs; 4047 } 4048 } 4049 4050 /** check if a type is a subtype of Serializable, if that is available.*/ 4051 boolean isSerializable(Type t) { 4052 try { 4053 syms.serializableType.complete(); 4054 } 4055 catch (CompletionFailure e) { 4056 return false; 4057 } 4058 return types.isSubtype(t, syms.serializableType); 4059 } 4060 4061 /** 4062 * Root class for resolution errors. Subclass of ResolveError 4063 * represent a different kinds of resolution error - as such they must 4064 * specify how they map into concrete compiler diagnostics. 4065 */ 4066 abstract class ResolveError extends Symbol { 4067 4068 /** The name of the kind of error, for debugging only. */ 4069 final String debugName; 4070 4071 ResolveError(Kind kind, String debugName) { 4072 super(kind, 0, null, null, null); 4073 this.debugName = debugName; 4074 } 4075 4076 @Override @DefinedBy(Api.LANGUAGE_MODEL) 4077 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 4078 throw new AssertionError(); 4079 } 4080 4081 @Override 4082 public String toString() { 4083 return debugName; 4084 } 4085 4086 @Override 4087 public boolean exists() { 4088 return false; 4089 } 4090 4091 @Override 4092 public boolean isStatic() { 4093 return false; 4094 } 4095 4096 /** 4097 * Create an external representation for this erroneous symbol to be 4098 * used during attribution - by default this returns the symbol of a 4099 * brand new error type which stores the original type found 4100 * during resolution. 4101 * 4102 * @param name the name used during resolution 4103 * @param location the location from which the symbol is accessed 4104 */ 4105 protected Symbol access(Name name, TypeSymbol location) { 4106 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 4107 } 4108 4109 /** 4110 * Create a diagnostic representing this resolution error. 4111 * 4112 * @param dkind The kind of the diagnostic to be created (e.g error). 4113 * @param pos The position to be used for error reporting. 4114 * @param site The original type from where the selection took place. 4115 * @param name The name of the symbol to be resolved. 4116 * @param argtypes The invocation's value arguments, 4117 * if we looked for a method. 4118 * @param typeargtypes The invocation's type arguments, 4119 * if we looked for a method. 4120 */ 4121 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4122 DiagnosticPosition pos, 4123 Symbol location, 4124 Type site, 4125 Name name, 4126 List<Type> argtypes, 4127 List<Type> typeargtypes); 4128 } 4129 4130 /** 4131 * This class is the root class of all resolution errors caused by 4132 * an invalid symbol being found during resolution. 4133 */ 4134 abstract class InvalidSymbolError extends ResolveError { 4135 4136 /** The invalid symbol found during resolution */ 4137 Symbol sym; 4138 4139 InvalidSymbolError(Kind kind, Symbol sym, String debugName) { 4140 super(kind, debugName); 4141 this.sym = sym; 4142 } 4143 4144 @Override 4145 public boolean exists() { 4146 return true; 4147 } 4148 4149 @Override 4150 public String toString() { 4151 return super.toString() + " wrongSym=" + sym; 4152 } 4153 4154 @Override 4155 public Symbol access(Name name, TypeSymbol location) { 4156 if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP)) 4157 return types.createErrorType(name, location, sym.type).tsym; 4158 else 4159 return sym; 4160 } 4161 } 4162 4163 class BadRestrictedTypeError extends ResolveError { 4164 private final Name typeName; 4165 BadRestrictedTypeError(Name typeName) { 4166 super(Kind.BAD_RESTRICTED_TYPE, "bad var use"); 4167 this.typeName = typeName; 4168 } 4169 4170 @Override 4171 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4172 return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName); 4173 } 4174 } 4175 4176 /** 4177 * InvalidSymbolError error class indicating that a symbol matching a 4178 * given name does not exists in a given site. 4179 */ 4180 class SymbolNotFoundError extends ResolveError { 4181 4182 SymbolNotFoundError(Kind kind) { 4183 this(kind, "symbol not found error"); 4184 } 4185 4186 SymbolNotFoundError(Kind kind, String debugName) { 4187 super(kind, debugName); 4188 } 4189 4190 @Override 4191 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4192 DiagnosticPosition pos, 4193 Symbol location, 4194 Type site, 4195 Name name, 4196 List<Type> argtypes, 4197 List<Type> typeargtypes) { 4198 argtypes = argtypes == null ? List.nil() : argtypes; 4199 typeargtypes = typeargtypes == null ? List.nil() : typeargtypes; 4200 if (name == names.error) 4201 return null; 4202 4203 boolean hasLocation = false; 4204 if (location == null) { 4205 location = site.tsym; 4206 } 4207 if (!location.name.isEmpty()) { 4208 if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) { 4209 return diags.create(dkind, log.currentSource(), pos, 4210 "doesnt.exist", location); 4211 } 4212 hasLocation = !location.name.equals(names._this) && 4213 !location.name.equals(names._super); 4214 } 4215 boolean isConstructor = name == names.init; 4216 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind(); 4217 Name idname = isConstructor ? site.tsym.name : name; 4218 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); 4219 if (hasLocation) { 4220 return diags.create(dkind, log.currentSource(), pos, 4221 errKey, kindname, idname, //symbol kindname, name 4222 typeargtypes, args(argtypes), //type parameters and arguments (if any) 4223 getLocationDiag(location, site)); //location kindname, type 4224 } 4225 else { 4226 return diags.create(dkind, log.currentSource(), pos, 4227 errKey, kindname, idname, //symbol kindname, name 4228 typeargtypes, args(argtypes)); //type parameters and arguments (if any) 4229 } 4230 } 4231 //where 4232 private Object args(List<Type> args) { 4233 return args.isEmpty() ? args : methodArguments(args); 4234 } 4235 4236 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) { 4237 String key = "cant.resolve"; 4238 String suffix = hasLocation ? ".location" : ""; 4239 switch (kindname) { 4240 case METHOD: 4241 case CONSTRUCTOR: { 4242 suffix += ".args"; 4243 suffix += hasTypeArgs ? ".params" : ""; 4244 } 4245 } 4246 return key + suffix; 4247 } 4248 private JCDiagnostic getLocationDiag(Symbol location, Type site) { 4249 if (location.kind == VAR) { 4250 return diags.fragment(Fragments.Location1(kindName(location), 4251 location, 4252 location.type)); 4253 } else { 4254 return diags.fragment(Fragments.Location(typeKindName(site), 4255 site, 4256 null)); 4257 } 4258 } 4259 } 4260 4261 /** 4262 * InvalidSymbolError error class indicating that a given symbol 4263 * (either a method, a constructor or an operand) is not applicable 4264 * given an actual arguments/type argument list. 4265 */ 4266 class InapplicableSymbolError extends ResolveError { 4267 4268 protected MethodResolutionContext resolveContext; 4269 4270 InapplicableSymbolError(MethodResolutionContext context) { 4271 this(WRONG_MTH, "inapplicable symbol error", context); 4272 } 4273 4274 protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) { 4275 super(kind, debugName); 4276 this.resolveContext = context; 4277 } 4278 4279 @Override 4280 public String toString() { 4281 return super.toString(); 4282 } 4283 4284 @Override 4285 public boolean exists() { 4286 return true; 4287 } 4288 4289 @Override 4290 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4291 DiagnosticPosition pos, 4292 Symbol location, 4293 Type site, 4294 Name name, 4295 List<Type> argtypes, 4296 List<Type> typeargtypes) { 4297 if (name == names.error) 4298 return null; 4299 4300 Pair<Symbol, JCDiagnostic> c = errCandidate(); 4301 Symbol ws = c.fst.asMemberOf(site, types); 4302 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ? 4303 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null; 4304 4305 // If the problem is due to type arguments, then the method parameters aren't relevant, 4306 // so use the error message that omits them to avoid confusion. 4307 switch (c.snd.getCode()) { 4308 case "compiler.misc.wrong.number.type.args": 4309 case "compiler.misc.explicit.param.do.not.conform.to.bounds": 4310 return diags.create(dkind, log.currentSource(), pos, 4311 "cant.apply.symbol.noargs", 4312 rewriter, 4313 kindName(ws), 4314 ws.name == names.init ? ws.owner.name : ws.name, 4315 kindName(ws.owner), 4316 ws.owner.type, 4317 c.snd); 4318 default: 4319 // Avoid saying "constructor Array in class Array" 4320 if (ws.owner == syms.arrayClass && ws.name == names.init) { 4321 return diags.create(dkind, log.currentSource(), pos, 4322 "cant.apply.array.ctor", 4323 rewriter, 4324 methodArguments(ws.type.getParameterTypes()), 4325 methodArguments(argtypes), 4326 c.snd); 4327 } 4328 return diags.create(dkind, log.currentSource(), pos, 4329 "cant.apply.symbol", 4330 rewriter, 4331 kindName(ws), 4332 ws.name == names.init ? ws.owner.name : ws.name, 4333 methodArguments(ws.type.getParameterTypes()), 4334 methodArguments(argtypes), 4335 kindName(ws.owner), 4336 ws.owner.type, 4337 c.snd); 4338 } 4339 } 4340 4341 @Override 4342 public Symbol access(Name name, TypeSymbol location) { 4343 Pair<Symbol, JCDiagnostic> cand = errCandidate(); 4344 TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym; 4345 if (cand != null) { 4346 attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd); 4347 } 4348 return errSymbol; 4349 } 4350 4351 protected Pair<Symbol, JCDiagnostic> errCandidate() { 4352 Candidate bestSoFar = null; 4353 for (Candidate c : resolveContext.candidates) { 4354 if (c.isApplicable()) continue; 4355 bestSoFar = c; 4356 } 4357 Assert.checkNonNull(bestSoFar); 4358 return new Pair<>(bestSoFar.sym, bestSoFar.details); 4359 } 4360 } 4361 4362 /** 4363 * ResolveError error class indicating that a symbol (either methods, constructors or operand) 4364 * is not applicable given an actual arguments/type argument list. 4365 */ 4366 class InapplicableSymbolsError extends InapplicableSymbolError { 4367 4368 InapplicableSymbolsError(MethodResolutionContext context) { 4369 super(WRONG_MTHS, "inapplicable symbols", context); 4370 } 4371 4372 @Override 4373 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4374 DiagnosticPosition pos, 4375 Symbol location, 4376 Type site, 4377 Name name, 4378 List<Type> argtypes, 4379 List<Type> typeargtypes) { 4380 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates(); 4381 Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ? 4382 filterCandidates(candidatesMap) : 4383 mapCandidates(); 4384 if (filteredCandidates.isEmpty()) { 4385 filteredCandidates = candidatesMap; 4386 } 4387 boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size(); 4388 if (filteredCandidates.size() > 1) { 4389 JCDiagnostic err = diags.create(dkind, 4390 null, 4391 truncatedDiag ? 4392 EnumSet.of(DiagnosticFlag.COMPRESSED) : 4393 EnumSet.noneOf(DiagnosticFlag.class), 4394 log.currentSource(), 4395 pos, 4396 "cant.apply.symbols", 4397 name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(), 4398 name == names.init ? site.tsym.name : name, 4399 methodArguments(argtypes)); 4400 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site)); 4401 } else if (filteredCandidates.size() == 1) { 4402 Map.Entry<Symbol, JCDiagnostic> _e = 4403 filteredCandidates.entrySet().iterator().next(); 4404 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue()); 4405 JCDiagnostic d = new InapplicableSymbolError(resolveContext) { 4406 @Override 4407 protected Pair<Symbol, JCDiagnostic> errCandidate() { 4408 return p; 4409 } 4410 }.getDiagnostic(dkind, pos, 4411 location, site, name, argtypes, typeargtypes); 4412 if (truncatedDiag) { 4413 d.setFlag(DiagnosticFlag.COMPRESSED); 4414 } 4415 return d; 4416 } else { 4417 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, 4418 location, site, name, argtypes, typeargtypes); 4419 } 4420 } 4421 //where 4422 private Map<Symbol, JCDiagnostic> mapCandidates() { 4423 MostSpecificMap candidates = new MostSpecificMap(); 4424 for (Candidate c : resolveContext.candidates) { 4425 if (c.isApplicable()) continue; 4426 candidates.put(c); 4427 } 4428 return candidates; 4429 } 4430 4431 @SuppressWarnings("serial") 4432 private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> { 4433 private void put(Candidate c) { 4434 ListBuffer<Symbol> overridden = new ListBuffer<>(); 4435 for (Symbol s : keySet()) { 4436 if (s == c.sym) { 4437 continue; 4438 } 4439 if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) { 4440 overridden.add(s); 4441 } else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) { 4442 return; 4443 } 4444 } 4445 for (Symbol s : overridden) { 4446 remove(s); 4447 } 4448 put(c.sym, c.details); 4449 } 4450 } 4451 4452 Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) { 4453 Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>(); 4454 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) { 4455 JCDiagnostic d = _entry.getValue(); 4456 if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) { 4457 candidates.put(_entry.getKey(), d); 4458 } 4459 } 4460 return candidates; 4461 } 4462 4463 private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) { 4464 List<JCDiagnostic> details = List.nil(); 4465 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) { 4466 Symbol sym = _entry.getKey(); 4467 JCDiagnostic detailDiag = 4468 diags.fragment(Fragments.InapplicableMethod(Kinds.kindName(sym), 4469 sym.location(site, types), 4470 sym.asMemberOf(site, types), 4471 _entry.getValue())); 4472 details = details.prepend(detailDiag); 4473 } 4474 //typically members are visited in reverse order (see Scope) 4475 //so we need to reverse the candidate list so that candidates 4476 //conform to source order 4477 return details; 4478 } 4479 4480 @Override 4481 protected Pair<Symbol, JCDiagnostic> errCandidate() { 4482 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates(); 4483 Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap); 4484 if (filteredCandidates.size() == 1) { 4485 return Pair.of(filteredCandidates.keySet().iterator().next(), 4486 filteredCandidates.values().iterator().next()); 4487 } 4488 return null; 4489 } 4490 } 4491 4492 /** 4493 * DiamondError error class indicating that a constructor symbol is not applicable 4494 * given an actual arguments/type argument list using diamond inference. 4495 */ 4496 class DiamondError extends InapplicableSymbolError { 4497 4498 Symbol sym; 4499 4500 public DiamondError(Symbol sym, MethodResolutionContext context) { 4501 super(sym.kind, "diamondError", context); 4502 this.sym = sym; 4503 } 4504 4505 JCDiagnostic getDetails() { 4506 return (sym.kind == WRONG_MTH) ? 4507 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd : 4508 null; 4509 } 4510 4511 @Override 4512 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 4513 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4514 JCDiagnostic details = getDetails(); 4515 if (details != null && compactMethodDiags) { 4516 JCDiagnostic simpleDiag = 4517 MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details); 4518 if (simpleDiag != null) { 4519 return simpleDiag; 4520 } 4521 } 4522 String key = details == null ? 4523 "cant.apply.diamond" : 4524 "cant.apply.diamond.1"; 4525 return diags.create(dkind, log.currentSource(), pos, key, 4526 Fragments.Diamond(site.tsym), details); 4527 } 4528 } 4529 4530 /** 4531 * An InvalidSymbolError error class indicating that a symbol is not 4532 * accessible from a given site 4533 */ 4534 class AccessError extends InvalidSymbolError { 4535 4536 private Env<AttrContext> env; 4537 private Type site; 4538 4539 AccessError(Env<AttrContext> env, Type site, Symbol sym) { 4540 super(HIDDEN, sym, "access error"); 4541 this.env = env; 4542 this.site = site; 4543 } 4544 4545 @Override 4546 public boolean exists() { 4547 return false; 4548 } 4549 4550 @Override 4551 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4552 DiagnosticPosition pos, 4553 Symbol location, 4554 Type site, 4555 Name name, 4556 List<Type> argtypes, 4557 List<Type> typeargtypes) { 4558 if (sym.name == names.init && sym.owner != site.tsym) { 4559 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, 4560 pos, location, site, name, argtypes, typeargtypes); 4561 } 4562 else if ((sym.flags() & PUBLIC) != 0 4563 || (env != null && this.site != null 4564 && !isAccessible(env, this.site))) { 4565 if (sym.owner.kind == PCK) { 4566 return diags.create(dkind, log.currentSource(), 4567 pos, "not.def.access.package.cant.access", 4568 sym, sym.location(), inaccessiblePackageReason(env, sym.packge())); 4569 } else if ( sym.packge() != syms.rootPackage 4570 && !symbolPackageVisible(env, sym)) { 4571 return diags.create(dkind, log.currentSource(), 4572 pos, "not.def.access.class.intf.cant.access.reason", 4573 sym, sym.location(), sym.location().packge(), 4574 inaccessiblePackageReason(env, sym.packge())); 4575 } else { 4576 return diags.create(dkind, log.currentSource(), 4577 pos, "not.def.access.class.intf.cant.access", 4578 sym, sym.location()); 4579 } 4580 } 4581 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { 4582 return diags.create(dkind, log.currentSource(), 4583 pos, "report.access", sym, 4584 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 4585 sym.location()); 4586 } 4587 else { 4588 return diags.create(dkind, log.currentSource(), 4589 pos, "not.def.public.cant.access", sym, sym.location()); 4590 } 4591 } 4592 4593 private String toString(Type type) { 4594 StringBuilder sb = new StringBuilder(); 4595 sb.append(type); 4596 if (type != null) { 4597 sb.append("[tsym:").append(type.tsym); 4598 if (type.tsym != null) 4599 sb.append("packge:").append(type.tsym.packge()); 4600 sb.append("]"); 4601 } 4602 return sb.toString(); 4603 } 4604 } 4605 4606 class InvisibleSymbolError extends InvalidSymbolError { 4607 4608 private final Env<AttrContext> env; 4609 private final boolean suppressError; 4610 4611 InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) { 4612 super(HIDDEN, sym, "invisible class error"); 4613 this.env = env; 4614 this.suppressError = suppressError; 4615 this.name = sym.name; 4616 } 4617 4618 @Override 4619 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4620 DiagnosticPosition pos, 4621 Symbol location, 4622 Type site, 4623 Name name, 4624 List<Type> argtypes, 4625 List<Type> typeargtypes) { 4626 if (suppressError) 4627 return null; 4628 4629 if (sym.kind == PCK) { 4630 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge()); 4631 return diags.create(dkind, log.currentSource(), 4632 pos, "package.not.visible", sym, details); 4633 } 4634 4635 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge()); 4636 4637 if (pos.getTree() != null) { 4638 Symbol o = sym; 4639 JCTree tree = pos.getTree(); 4640 4641 while (o.kind != PCK && tree.hasTag(SELECT)) { 4642 o = o.owner; 4643 tree = ((JCFieldAccess) tree).selected; 4644 } 4645 4646 if (o.kind == PCK) { 4647 pos = tree.pos(); 4648 4649 return diags.create(dkind, log.currentSource(), 4650 pos, "package.not.visible", o, details); 4651 } 4652 } 4653 4654 return diags.create(dkind, log.currentSource(), 4655 pos, "not.def.access.package.cant.access", sym, sym.packge(), details); 4656 } 4657 } 4658 4659 JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) { 4660 //no dependency: 4661 if (!env.toplevel.modle.readModules.contains(sym.modle)) { 4662 //does not read: 4663 if (sym.modle != syms.unnamedModule) { 4664 if (env.toplevel.modle != syms.unnamedModule) { 4665 return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle, 4666 sym, 4667 sym.modle)); 4668 } else { 4669 return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym, 4670 sym.modle)); 4671 } 4672 } else { 4673 return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym, 4674 env.toplevel.modle)); 4675 } 4676 } else { 4677 if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) { 4678 //not exported to this module: 4679 if (env.toplevel.modle != syms.unnamedModule) { 4680 return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym, 4681 sym.modle, 4682 env.toplevel.modle)); 4683 } else { 4684 return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym, 4685 sym.modle)); 4686 } 4687 } else { 4688 //not exported: 4689 if (env.toplevel.modle != syms.unnamedModule) { 4690 return diags.fragment(Fragments.NotDefAccessNotExported(sym, 4691 sym.modle)); 4692 } else { 4693 return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym, 4694 sym.modle)); 4695 } 4696 } 4697 } 4698 } 4699 4700 /** 4701 * InvalidSymbolError error class indicating that an instance member 4702 * has erroneously been accessed from a static context. 4703 */ 4704 class StaticError extends InvalidSymbolError { 4705 4706 StaticError(Symbol sym) { 4707 this(sym, "static error"); 4708 } 4709 4710 StaticError(Symbol sym, String debugName) { 4711 super(STATICERR, sym, debugName); 4712 } 4713 4714 @Override 4715 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4716 DiagnosticPosition pos, 4717 Symbol location, 4718 Type site, 4719 Name name, 4720 List<Type> argtypes, 4721 List<Type> typeargtypes) { 4722 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS)) 4723 ? types.erasure(sym.type).tsym 4724 : sym); 4725 return diags.create(dkind, log.currentSource(), pos, 4726 "non-static.cant.be.ref", kindName(sym), errSym); 4727 } 4728 } 4729 4730 /** 4731 * Specialization of {@link InvalidSymbolError} for illegal 4732 * early accesses within a constructor prologue. 4733 */ 4734 class RefBeforeCtorCalledError extends StaticError { 4735 4736 RefBeforeCtorCalledError(Symbol sym) { 4737 super(sym, "prologue error"); 4738 } 4739 4740 @Override 4741 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4742 DiagnosticPosition pos, 4743 Symbol location, 4744 Type site, 4745 Name name, 4746 List<Type> argtypes, 4747 List<Type> typeargtypes) { 4748 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS)) 4749 ? types.erasure(sym.type).tsym 4750 : sym); 4751 return diags.create(dkind, log.currentSource(), pos, 4752 "cant.ref.before.ctor.called", errSym); 4753 } 4754 } 4755 4756 /** 4757 * InvalidSymbolError error class indicating that a pair of symbols 4758 * (either methods, constructors or operands) are ambiguous 4759 * given an actual arguments/type argument list. 4760 */ 4761 class AmbiguityError extends ResolveError { 4762 4763 /** The other maximally specific symbol */ 4764 List<Symbol> ambiguousSyms = List.nil(); 4765 4766 @Override 4767 public boolean exists() { 4768 return true; 4769 } 4770 4771 AmbiguityError(Symbol sym1, Symbol sym2) { 4772 super(AMBIGUOUS, "ambiguity error"); 4773 ambiguousSyms = flatten(sym2).appendList(flatten(sym1)); 4774 } 4775 4776 private List<Symbol> flatten(Symbol sym) { 4777 if (sym.kind == AMBIGUOUS) { 4778 return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms; 4779 } else { 4780 return List.of(sym); 4781 } 4782 } 4783 4784 AmbiguityError addAmbiguousSymbol(Symbol s) { 4785 ambiguousSyms = ambiguousSyms.prepend(s); 4786 return this; 4787 } 4788 4789 @Override 4790 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4791 DiagnosticPosition pos, 4792 Symbol location, 4793 Type site, 4794 Name name, 4795 List<Type> argtypes, 4796 List<Type> typeargtypes) { 4797 List<Symbol> diagSyms = ambiguousSyms.reverse(); 4798 Symbol s1 = diagSyms.head; 4799 Symbol s2 = diagSyms.tail.head; 4800 Name sname = s1.name; 4801 if (sname == names.init) sname = s1.owner.name; 4802 return diags.create(dkind, log.currentSource(), 4803 pos, "ref.ambiguous", sname, 4804 kindName(s1), 4805 s1, 4806 s1.location(site, types), 4807 kindName(s2), 4808 s2, 4809 s2.location(site, types)); 4810 } 4811 4812 /** 4813 * If multiple applicable methods are found during overload and none of them 4814 * is more specific than the others, attempt to merge their signatures. 4815 */ 4816 Symbol mergeAbstracts(Type site) { 4817 List<Symbol> ambiguousInOrder = ambiguousSyms.reverse(); 4818 return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this); 4819 } 4820 4821 @Override 4822 protected Symbol access(Name name, TypeSymbol location) { 4823 Symbol firstAmbiguity = ambiguousSyms.last(); 4824 return firstAmbiguity.kind == TYP ? 4825 types.createErrorType(name, location, firstAmbiguity.type).tsym : 4826 firstAmbiguity; 4827 } 4828 } 4829 4830 class BadVarargsMethod extends ResolveError { 4831 4832 ResolveError delegatedError; 4833 4834 BadVarargsMethod(ResolveError delegatedError) { 4835 super(delegatedError.kind, "badVarargs"); 4836 this.delegatedError = delegatedError; 4837 } 4838 4839 @Override 4840 public Symbol baseSymbol() { 4841 return delegatedError.baseSymbol(); 4842 } 4843 4844 @Override 4845 protected Symbol access(Name name, TypeSymbol location) { 4846 return delegatedError.access(name, location); 4847 } 4848 4849 @Override 4850 public boolean exists() { 4851 return true; 4852 } 4853 4854 @Override 4855 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4856 return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes); 4857 } 4858 } 4859 4860 /** 4861 * BadMethodReferenceError error class indicating that a method reference symbol has been found, 4862 * but with the wrong staticness. 4863 */ 4864 class BadMethodReferenceError extends StaticError { 4865 4866 boolean unboundLookup; 4867 4868 public BadMethodReferenceError(Symbol sym, boolean unboundLookup) { 4869 super(sym, "bad method ref error"); 4870 this.unboundLookup = unboundLookup; 4871 } 4872 4873 @Override 4874 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4875 final String key; 4876 if (!unboundLookup) { 4877 key = "bad.static.method.in.bound.lookup"; 4878 } else if (sym.isStatic()) { 4879 key = "bad.static.method.in.unbound.lookup"; 4880 } else { 4881 key = "bad.instance.method.in.unbound.lookup"; 4882 } 4883 return sym.kind.isResolutionError() ? 4884 ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) : 4885 diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym); 4886 } 4887 } 4888 4889 /** 4890 * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found, 4891 * but pointing to a class for which an enclosing instance is not available. 4892 */ 4893 class BadConstructorReferenceError extends InvalidSymbolError { 4894 4895 public BadConstructorReferenceError(Symbol sym) { 4896 super(MISSING_ENCL, sym, "BadConstructorReferenceError"); 4897 } 4898 4899 @Override 4900 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4901 return diags.create(dkind, log.currentSource(), pos, 4902 "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); 4903 } 4904 } 4905 4906 class BadClassFileError extends InvalidSymbolError { 4907 4908 private final CompletionFailure ex; 4909 4910 public BadClassFileError(CompletionFailure ex) { 4911 super(HIDDEN, ex.sym, "BadClassFileError"); 4912 this.name = sym.name; 4913 this.ex = ex; 4914 } 4915 4916 @Override 4917 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4918 JCDiagnostic d = diags.create(dkind, log.currentSource(), pos, 4919 "cant.access", ex.sym, ex.getDetailValue()); 4920 4921 d.setFlag(DiagnosticFlag.NON_DEFERRABLE); 4922 return d; 4923 } 4924 4925 } 4926 4927 /** 4928 * Helper class for method resolution diagnostic simplification. 4929 * Certain resolution diagnostic are rewritten as simpler diagnostic 4930 * where the enclosing resolution diagnostic (i.e. 'inapplicable method') 4931 * is stripped away, as it doesn't carry additional info. The logic 4932 * for matching a given diagnostic is given in terms of a template 4933 * hierarchy: a diagnostic template can be specified programmatically, 4934 * so that only certain diagnostics are matched. Each templete is then 4935 * associated with a rewriter object that carries out the task of rewtiting 4936 * the diagnostic to a simpler one. 4937 */ 4938 static class MethodResolutionDiagHelper { 4939 4940 /** 4941 * A diagnostic rewriter transforms a method resolution diagnostic 4942 * into a simpler one 4943 */ 4944 interface DiagnosticRewriter { 4945 JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, 4946 DiagnosticPosition preferredPos, DiagnosticSource preferredSource, 4947 DiagnosticType preferredKind, JCDiagnostic d); 4948 } 4949 4950 /** 4951 * A diagnostic template is made up of two ingredients: (i) a regular 4952 * expression for matching a diagnostic key and (ii) a list of sub-templates 4953 * for matching diagnostic arguments. 4954 */ 4955 static class Template { 4956 4957 /** regex used to match diag key */ 4958 String regex; 4959 4960 /** templates used to match diagnostic args */ 4961 Template[] subTemplates; 4962 4963 Template(String key, Template... subTemplates) { 4964 this.regex = key; 4965 this.subTemplates = subTemplates; 4966 } 4967 4968 /** 4969 * Returns true if the regex matches the diagnostic key and if 4970 * all diagnostic arguments are matches by corresponding sub-templates. 4971 */ 4972 boolean matches(Object o) { 4973 JCDiagnostic d = (JCDiagnostic)o; 4974 Object[] args = d.getArgs(); 4975 if (!d.getCode().matches(regex) || 4976 subTemplates.length != d.getArgs().length) { 4977 return false; 4978 } 4979 for (int i = 0; i < args.length ; i++) { 4980 if (!subTemplates[i].matches(args[i])) { 4981 return false; 4982 } 4983 } 4984 return true; 4985 } 4986 } 4987 4988 /** 4989 * Common rewriter for all argument mismatch simplifications. 4990 */ 4991 static class ArgMismatchRewriter implements DiagnosticRewriter { 4992 4993 /** the index of the subdiagnostic to be used as primary. */ 4994 int causeIndex; 4995 4996 public ArgMismatchRewriter(int causeIndex) { 4997 this.causeIndex = causeIndex; 4998 } 4999 5000 @Override 5001 public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, 5002 DiagnosticPosition preferredPos, DiagnosticSource preferredSource, 5003 DiagnosticType preferredKind, JCDiagnostic d) { 5004 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex]; 5005 DiagnosticPosition pos = d.getDiagnosticPosition(); 5006 if (pos == null) { 5007 pos = preferredPos; 5008 } 5009 return diags.create(preferredKind, preferredSource, pos, 5010 "prob.found.req", cause); 5011 } 5012 } 5013 5014 /** a dummy template that match any diagnostic argument */ 5015 static final Template skip = new Template("") { 5016 @Override 5017 boolean matches(Object d) { 5018 return true; 5019 } 5020 }; 5021 5022 /** template for matching inference-free arguments mismatch failures */ 5023 static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip); 5024 5025 /** template for matching inference related arguments mismatch failures */ 5026 static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) { 5027 @Override 5028 boolean matches(Object o) { 5029 if (!super.matches(o)) { 5030 return false; 5031 } 5032 JCDiagnostic d = (JCDiagnostic)o; 5033 @SuppressWarnings("unchecked") 5034 List<Type> tvars = (List<Type>)d.getArgs()[0]; 5035 return !containsAny(d, tvars); 5036 } 5037 5038 BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> { 5039 if (o instanceof Type type) { 5040 return type.containsAny(ts); 5041 } else if (o instanceof JCDiagnostic diagnostic) { 5042 return containsAny(diagnostic, ts); 5043 } else { 5044 return false; 5045 } 5046 }; 5047 5048 boolean containsAny(JCDiagnostic d, List<Type> ts) { 5049 return Stream.of(d.getArgs()) 5050 .anyMatch(o -> containsPredicate.test(o, ts)); 5051 } 5052 }; 5053 5054 /** rewriter map used for method resolution simplification */ 5055 static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>(); 5056 5057 static { 5058 rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0)); 5059 rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1)); 5060 } 5061 5062 /** 5063 * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it, 5064 * and rewrite it accordingly. 5065 */ 5066 static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source, 5067 DiagnosticType dkind, JCDiagnostic d) { 5068 for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) { 5069 if (_entry.getKey().matches(d)) { 5070 JCDiagnostic simpleDiag = 5071 _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d); 5072 simpleDiag.setFlag(DiagnosticFlag.COMPRESSED); 5073 return simpleDiag; 5074 } 5075 } 5076 return null; 5077 } 5078 } 5079 5080 enum MethodResolutionPhase { 5081 BASIC(false, false), 5082 BOX(true, false), 5083 VARARITY(true, true) { 5084 @Override 5085 public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { 5086 //Check invariants (see {@code LookupHelper.shouldStop}) 5087 Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS); 5088 if (!sym.kind.isResolutionError()) { 5089 //varargs resolution successful 5090 return sym; 5091 } else { 5092 //pick best error 5093 switch (bestSoFar.kind) { 5094 case WRONG_MTH: 5095 case WRONG_MTHS: 5096 //Override previous errors if they were caused by argument mismatch. 5097 //This generally means preferring current symbols - but we need to pay 5098 //attention to the fact that the varargs lookup returns 'less' candidates 5099 //than the previous rounds, and adjust that accordingly. 5100 switch (sym.kind) { 5101 case WRONG_MTH: 5102 //if the previous round matched more than one method, return that 5103 //result instead 5104 return bestSoFar.kind == WRONG_MTHS ? 5105 bestSoFar : sym; 5106 case ABSENT_MTH: 5107 //do not override erroneous symbol if the arity lookup did not 5108 //match any method 5109 return bestSoFar; 5110 case WRONG_MTHS: 5111 default: 5112 //safe to override 5113 return sym; 5114 } 5115 default: 5116 //otherwise, return first error 5117 return bestSoFar; 5118 } 5119 } 5120 } 5121 }; 5122 5123 final boolean isBoxingRequired; 5124 final boolean isVarargsRequired; 5125 5126 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { 5127 this.isBoxingRequired = isBoxingRequired; 5128 this.isVarargsRequired = isVarargsRequired; 5129 } 5130 5131 public boolean isBoxingRequired() { 5132 return isBoxingRequired; 5133 } 5134 5135 public boolean isVarargsRequired() { 5136 return isVarargsRequired; 5137 } 5138 5139 public Symbol mergeResults(Symbol prev, Symbol sym) { 5140 return sym; 5141 } 5142 } 5143 5144 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); 5145 5146 /** 5147 * A resolution context is used to keep track of intermediate results of 5148 * overload resolution, such as list of method that are not applicable 5149 * (used to generate more precise diagnostics) and so on. Resolution contexts 5150 * can be nested - this means that when each overload resolution routine should 5151 * work within the resolution context it created. 5152 */ 5153 class MethodResolutionContext { 5154 5155 private List<Candidate> candidates = List.nil(); 5156 5157 MethodResolutionPhase step = null; 5158 5159 MethodCheck methodCheck = resolveMethodCheck; 5160 5161 private boolean internalResolution = false; 5162 private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE; 5163 5164 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { 5165 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); 5166 candidates = candidates.append(c); 5167 } 5168 5169 void addApplicableCandidate(Symbol sym, Type mtype) { 5170 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype); 5171 candidates = candidates.append(c); 5172 } 5173 5174 DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) { 5175 DeferredAttrContext parent = (pendingResult == null) 5176 ? deferredAttr.emptyDeferredAttrContext 5177 : pendingResult.checkContext.deferredAttrContext(); 5178 return deferredAttr.new DeferredAttrContext(attrMode, sym, step, 5179 inferenceContext, parent, warn); 5180 } 5181 5182 /** 5183 * This class represents an overload resolution candidate. There are two 5184 * kinds of candidates: applicable methods and inapplicable methods; 5185 * applicable methods have a pointer to the instantiated method type, 5186 * while inapplicable candidates contain further details about the 5187 * reason why the method has been considered inapplicable. 5188 */ 5189 @SuppressWarnings("overrides") 5190 class Candidate { 5191 5192 final MethodResolutionPhase step; 5193 final Symbol sym; 5194 final JCDiagnostic details; 5195 final Type mtype; 5196 5197 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) { 5198 this.step = step; 5199 this.sym = sym; 5200 this.details = details; 5201 this.mtype = mtype; 5202 } 5203 5204 boolean isApplicable() { 5205 return mtype != null; 5206 } 5207 } 5208 5209 DeferredAttr.AttrMode attrMode() { 5210 return attrMode; 5211 } 5212 5213 boolean internal() { 5214 return internalResolution; 5215 } 5216 } 5217 5218 MethodResolutionContext currentResolutionContext = null; 5219 }