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