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