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