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