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