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