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