1 /* 2 * Copyright (c) 1999, 2013, 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.Symbol.*; 31 import com.sun.tools.javac.code.Type.*; 32 import com.sun.tools.javac.comp.Attr.ResultInfo; 33 import com.sun.tools.javac.comp.Check.CheckContext; 34 import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 35 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; 36 import com.sun.tools.javac.comp.DeferredAttr.DeferredType; 37 import com.sun.tools.javac.comp.Infer.InferenceContext; 38 import com.sun.tools.javac.comp.Infer.FreeTypeListener; 39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; 40 import com.sun.tools.javac.jvm.*; 41 import com.sun.tools.javac.tree.*; 42 import com.sun.tools.javac.tree.JCTree.*; 43 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; 44 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; 45 import com.sun.tools.javac.util.*; 46 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 47 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 48 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 49 50 import java.util.Arrays; 51 import java.util.Collection; 52 import java.util.EnumMap; 53 import java.util.EnumSet; 54 import java.util.Iterator; 55 import java.util.LinkedHashMap; 56 import java.util.LinkedHashSet; 57 import java.util.Map; 58 59 import javax.lang.model.element.ElementVisitor; 60 61 import static com.sun.tools.javac.code.Flags.*; 62 import static com.sun.tools.javac.code.Flags.BLOCK; 63 import static com.sun.tools.javac.code.Kinds.*; 64 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; 65 import static com.sun.tools.javac.code.TypeTag.*; 66 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; 67 import static com.sun.tools.javac.tree.JCTree.Tag.*; 68 69 /** Helper class for name resolution, used mostly by the attribution phase. 70 * 71 * <p><b>This is NOT part of any supported API. 72 * If you write code that depends on this, you do so at your own risk. 73 * This code and its internal interfaces are subject to change or 74 * deletion without notice.</b> 75 */ 76 public class Resolve { 77 protected static final Context.Key<Resolve> resolveKey = 78 new Context.Key<Resolve>(); 79 80 Names names; 81 Log log; 82 Symtab syms; 83 Attr attr; 84 DeferredAttr deferredAttr; 85 Check chk; 86 Infer infer; 87 ClassReader reader; 88 TreeInfo treeinfo; 89 Types types; 90 JCDiagnostic.Factory diags; 91 public final boolean boxingEnabled; // = source.allowBoxing(); 92 public final boolean varargsEnabled; // = source.allowVarargs(); 93 public final boolean allowMethodHandles; 94 public final boolean allowDefaultMethods; 95 public final boolean allowStructuralMostSpecific; 96 private final boolean debugResolve; 97 final EnumSet<VerboseResolutionMode> verboseResolutionMode; 98 99 Scope polymorphicSignatureScope; 100 101 protected Resolve(Context context) { 102 context.put(resolveKey, this); 103 syms = Symtab.instance(context); 104 105 varNotFound = new 106 SymbolNotFoundError(ABSENT_VAR); 107 methodNotFound = new 108 SymbolNotFoundError(ABSENT_MTH); 109 typeNotFound = new 110 SymbolNotFoundError(ABSENT_TYP); 111 112 names = Names.instance(context); 113 log = Log.instance(context); 114 attr = Attr.instance(context); 115 deferredAttr = DeferredAttr.instance(context); 116 chk = Check.instance(context); 117 infer = Infer.instance(context); 118 reader = ClassReader.instance(context); 119 treeinfo = TreeInfo.instance(context); 120 types = Types.instance(context); 121 diags = JCDiagnostic.Factory.instance(context); 122 Source source = Source.instance(context); 123 boxingEnabled = source.allowBoxing(); 124 varargsEnabled = source.allowVarargs(); 125 Options options = Options.instance(context); 126 debugResolve = options.isSet("debugresolve"); 127 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); 128 Target target = Target.instance(context); 129 allowMethodHandles = target.hasMethodHandles(); 130 allowDefaultMethods = source.allowDefaultMethods(); 131 allowStructuralMostSpecific = source.allowStructuralMostSpecific(); 132 polymorphicSignatureScope = new Scope(syms.noSymbol); 133 134 inapplicableMethodException = new InapplicableMethodException(diags); 135 } 136 137 /** error symbols, which are returned when resolution fails 138 */ 139 private final SymbolNotFoundError varNotFound; 140 private final SymbolNotFoundError methodNotFound; 141 private final SymbolNotFoundError typeNotFound; 142 143 public static Resolve instance(Context context) { 144 Resolve instance = context.get(resolveKey); 145 if (instance == null) 146 instance = new Resolve(context); 147 return instance; 148 } 149 150 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support"> 151 enum VerboseResolutionMode { 152 SUCCESS("success"), 153 FAILURE("failure"), 154 APPLICABLE("applicable"), 155 INAPPLICABLE("inapplicable"), 156 DEFERRED_INST("deferred-inference"), 157 PREDEF("predef"), 158 OBJECT_INIT("object-init"), 159 INTERNAL("internal"); 160 161 final String opt; 162 163 private VerboseResolutionMode(String opt) { 164 this.opt = opt; 165 } 166 167 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) { 168 String s = opts.get("verboseResolution"); 169 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class); 170 if (s == null) return res; 171 if (s.contains("all")) { 172 res = EnumSet.allOf(VerboseResolutionMode.class); 173 } 174 Collection<String> args = Arrays.asList(s.split(",")); 175 for (VerboseResolutionMode mode : values()) { 176 if (args.contains(mode.opt)) { 177 res.add(mode); 178 } else if (args.contains("-" + mode.opt)) { 179 res.remove(mode); 180 } 181 } 182 return res; 183 } 184 } 185 186 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, 187 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) { 188 boolean success = bestSoFar.kind < ERRONEOUS; 189 190 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { 191 return; 192 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { 193 return; 194 } 195 196 if (bestSoFar.name == names.init && 197 bestSoFar.owner == syms.objectType.tsym && 198 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { 199 return; //skip diags for Object constructor resolution 200 } else if (site == syms.predefClass.type && 201 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { 202 return; //skip spurious diags for predef symbols (i.e. operators) 203 } else if (currentResolutionContext.internalResolution && 204 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { 205 return; 206 } 207 208 int pos = 0; 209 int mostSpecificPos = -1; 210 ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb(); 211 for (Candidate c : currentResolutionContext.candidates) { 212 if (currentResolutionContext.step != c.step || 213 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || 214 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) { 215 continue; 216 } else { 217 subDiags.append(c.isApplicable() ? 218 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) : 219 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details)); 220 if (c.sym == bestSoFar) 221 mostSpecificPos = pos; 222 pos++; 223 } 224 } 225 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; 226 List<Type> argtypes2 = Type.map(argtypes, 227 deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step)); 228 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, 229 site.tsym, mostSpecificPos, currentResolutionContext.step, 230 methodArguments(argtypes2), 231 methodArguments(typeargtypes)); 232 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); 233 log.report(d); 234 } 235 236 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) { 237 JCDiagnostic subDiag = null; 238 if (sym.type.hasTag(FORALL)) { 239 subDiag = diags.fragment("partial.inst.sig", inst); 240 } 241 242 String key = subDiag == null ? 243 "applicable.method.found" : 244 "applicable.method.found.1"; 245 246 return diags.fragment(key, pos, sym, subDiag); 247 } 248 249 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) { 250 return diags.fragment("not.applicable.method.found", pos, sym, subDiag); 251 } 252 // </editor-fold> 253 254 /* ************************************************************************ 255 * Identifier resolution 256 *************************************************************************/ 257 258 /** An environment is "static" if its static level is greater than 259 * the one of its outer environment 260 */ 261 protected static boolean isStatic(Env<AttrContext> env) { 262 return env.info.staticLevel > env.outer.info.staticLevel; 263 } 264 265 /** An environment is an "initializer" if it is a constructor or 266 * an instance initializer. 267 */ 268 static boolean isInitializer(Env<AttrContext> env) { 269 Symbol owner = env.info.scope.owner; 270 return owner.isConstructor() || 271 owner.owner.kind == TYP && 272 (owner.kind == VAR || 273 owner.kind == MTH && (owner.flags() & BLOCK) != 0) && 274 (owner.flags() & STATIC) == 0; 275 } 276 277 /** Is class accessible in given evironment? 278 * @param env The current environment. 279 * @param c The class whose accessibility is checked. 280 */ 281 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) { 282 return isAccessible(env, c, false); 283 } 284 285 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) { 286 boolean isAccessible = false; 287 switch ((short)(c.flags() & AccessFlags)) { 288 case PRIVATE: 289 isAccessible = 290 env.enclClass.sym.outermostClass() == 291 c.owner.outermostClass(); 292 break; 293 case 0: 294 isAccessible = 295 env.toplevel.packge == c.owner // fast special case 296 || 297 env.toplevel.packge == c.packge() 298 || 299 // Hack: this case is added since synthesized default constructors 300 // of anonymous classes should be allowed to access 301 // classes which would be inaccessible otherwise. 302 env.enclMethod != null && 303 (env.enclMethod.mods.flags & ANONCONSTR) != 0; 304 break; 305 default: // error recovery 306 case PUBLIC: 307 isAccessible = true; 308 break; 309 case PROTECTED: 310 isAccessible = 311 env.toplevel.packge == c.owner // fast special case 312 || 313 env.toplevel.packge == c.packge() 314 || 315 isInnerSubClass(env.enclClass.sym, c.owner); 316 break; 317 } 318 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ? 319 isAccessible : 320 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner); 321 } 322 //where 323 /** Is given class a subclass of given base class, or an inner class 324 * of a subclass? 325 * Return null if no such class exists. 326 * @param c The class which is the subclass or is contained in it. 327 * @param base The base class 328 */ 329 private boolean isInnerSubClass(ClassSymbol c, Symbol base) { 330 while (c != null && !c.isSubClass(base, types)) { 331 c = c.owner.enclClass(); 332 } 333 return c != null; 334 } 335 336 boolean isAccessible(Env<AttrContext> env, Type t) { 337 return isAccessible(env, t, false); 338 } 339 340 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { 341 return (t.hasTag(ARRAY)) 342 ? isAccessible(env, types.elemtype(t)) 343 : isAccessible(env, t.tsym, checkInner); 344 } 345 346 /** Is symbol accessible as a member of given type in given evironment? 347 * @param env The current environment. 348 * @param site The type of which the tested symbol is regarded 349 * as a member. 350 * @param sym The symbol. 351 */ 352 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) { 353 return isAccessible(env, site, sym, false); 354 } 355 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) { 356 if (sym.name == names.init && sym.owner != site.tsym) return false; 357 switch ((short)(sym.flags() & AccessFlags)) { 358 case PRIVATE: 359 return 360 (env.enclClass.sym == sym.owner // fast special case 361 || 362 env.enclClass.sym.outermostClass() == 363 sym.owner.outermostClass()) 364 && 365 sym.isInheritedIn(site.tsym, types); 366 case 0: 367 return 368 (env.toplevel.packge == sym.owner.owner // fast special case 369 || 370 env.toplevel.packge == sym.packge()) 371 && 372 isAccessible(env, site, checkInner) 373 && 374 sym.isInheritedIn(site.tsym, types) 375 && 376 notOverriddenIn(site, sym); 377 case PROTECTED: 378 return 379 (env.toplevel.packge == sym.owner.owner // fast special case 380 || 381 env.toplevel.packge == sym.packge() 382 || 383 isProtectedAccessible(sym, env.enclClass.sym, site) 384 || 385 // OK to select instance method or field from 'super' or type name 386 // (but type names should be disallowed elsewhere!) 387 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) 388 && 389 isAccessible(env, site, checkInner) 390 && 391 notOverriddenIn(site, sym); 392 default: // this case includes erroneous combinations as well 393 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym); 394 } 395 } 396 //where 397 /* `sym' is accessible only if not overridden by 398 * another symbol which is a member of `site' 399 * (because, if it is overridden, `sym' is not strictly 400 * speaking a member of `site'). A polymorphic signature method 401 * cannot be overridden (e.g. MH.invokeExact(Object[])). 402 */ 403 private boolean notOverriddenIn(Type site, Symbol sym) { 404 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) 405 return true; 406 else { 407 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 408 return (s2 == null || s2 == sym || sym.owner == s2.owner || 409 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); 410 } 411 } 412 //where 413 /** Is given protected symbol accessible if it is selected from given site 414 * and the selection takes place in given class? 415 * @param sym The symbol with protected access 416 * @param c The class where the access takes place 417 * @site The type of the qualifier 418 */ 419 private 420 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { 421 while (c != null && 422 !(c.isSubClass(sym.owner, types) && 423 (c.flags() & INTERFACE) == 0 && 424 // In JLS 2e 6.6.2.1, the subclass restriction applies 425 // only to instance fields and methods -- types are excluded 426 // regardless of whether they are declared 'static' or not. 427 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) 428 c = c.owner.enclClass(); 429 return c != null; 430 } 431 432 /** 433 * Performs a recursive scan of a type looking for accessibility problems 434 * from current attribution environment 435 */ 436 void checkAccessibleType(Env<AttrContext> env, Type t) { 437 accessibilityChecker.visit(t, env); 438 } 439 440 /** 441 * Accessibility type-visitor 442 */ 443 Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker = 444 new Types.SimpleVisitor<Void, Env<AttrContext>>() { 445 446 void visit(List<Type> ts, Env<AttrContext> env) { 447 for (Type t : ts) { 448 visit(t, env); 449 } 450 } 451 452 public Void visitType(Type t, Env<AttrContext> env) { 453 return null; 454 } 455 456 @Override 457 public Void visitArrayType(ArrayType t, Env<AttrContext> env) { 458 visit(t.elemtype, env); 459 return null; 460 } 461 462 @Override 463 public Void visitClassType(ClassType t, Env<AttrContext> env) { 464 visit(t.getTypeArguments(), env); 465 if (!isAccessible(env, t, true)) { 466 accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true); 467 } 468 return null; 469 } 470 471 @Override 472 public Void visitWildcardType(WildcardType t, Env<AttrContext> env) { 473 visit(t.type, env); 474 return null; 475 } 476 477 @Override 478 public Void visitMethodType(MethodType t, Env<AttrContext> env) { 479 visit(t.getParameterTypes(), env); 480 visit(t.getReturnType(), env); 481 visit(t.getThrownTypes(), env); 482 return null; 483 } 484 }; 485 486 /** Try to instantiate the type of a method so that it fits 487 * given type arguments and argument types. If succesful, return 488 * the method's instantiated type, else return null. 489 * The instantiation will take into account an additional leading 490 * formal parameter if the method is an instance method seen as a member 491 * of un underdetermined site In this case, we treat site as an additional 492 * parameter and the parameters of the class containing the method as 493 * additional type variables that get instantiated. 494 * 495 * @param env The current environment 496 * @param site The type of which the method is a member. 497 * @param m The method symbol. 498 * @param argtypes The invocation's given value arguments. 499 * @param typeargtypes The invocation's given type arguments. 500 * @param allowBoxing Allow boxing conversions of arguments. 501 * @param useVarargs Box trailing arguments into an array for varargs. 502 */ 503 Type rawInstantiate(Env<AttrContext> env, 504 Type site, 505 Symbol m, 506 ResultInfo resultInfo, 507 List<Type> argtypes, 508 List<Type> typeargtypes, 509 boolean allowBoxing, 510 boolean useVarargs, 511 Warner warn) throws Infer.InferenceException { 512 513 Type mt = types.memberType(site, m); 514 // tvars is the list of formal type variables for which type arguments 515 // need to inferred. 516 List<Type> tvars = List.nil(); 517 if (typeargtypes == null) typeargtypes = List.nil(); 518 if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) { 519 // This is not a polymorphic method, but typeargs are supplied 520 // which is fine, see JLS 15.12.2.1 521 } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) { 522 ForAll pmt = (ForAll) mt; 523 if (typeargtypes.length() != pmt.tvars.length()) 524 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args 525 // Check type arguments are within bounds 526 List<Type> formals = pmt.tvars; 527 List<Type> actuals = typeargtypes; 528 while (formals.nonEmpty() && actuals.nonEmpty()) { 529 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head), 530 pmt.tvars, typeargtypes); 531 for (; bounds.nonEmpty(); bounds = bounds.tail) 532 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) 533 throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds); 534 formals = formals.tail; 535 actuals = actuals.tail; 536 } 537 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes); 538 } else if (mt.hasTag(FORALL)) { 539 ForAll pmt = (ForAll) mt; 540 List<Type> tvars1 = types.newInstances(pmt.tvars); 541 tvars = tvars.appendList(tvars1); 542 mt = types.subst(pmt.qtype, pmt.tvars, tvars1); 543 } 544 545 // find out whether we need to go the slow route via infer 546 boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/ 547 for (List<Type> l = argtypes; 548 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded; 549 l = l.tail) { 550 if (l.head.hasTag(FORALL)) instNeeded = true; 551 } 552 553 if (instNeeded) 554 return infer.instantiateMethod(env, 555 tvars, 556 (MethodType)mt, 557 resultInfo, 558 m, 559 argtypes, 560 allowBoxing, 561 useVarargs, 562 currentResolutionContext, 563 warn); 564 565 currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn), 566 argtypes, mt.getParameterTypes(), warn); 567 return mt; 568 } 569 570 Type checkMethod(Env<AttrContext> env, 571 Type site, 572 Symbol m, 573 ResultInfo resultInfo, 574 List<Type> argtypes, 575 List<Type> typeargtypes, 576 Warner warn) { 577 MethodResolutionContext prevContext = currentResolutionContext; 578 try { 579 currentResolutionContext = new MethodResolutionContext(); 580 currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK; 581 MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase; 582 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, 583 step.isBoxingRequired(), step.isVarargsRequired(), warn); 584 } 585 finally { 586 currentResolutionContext = prevContext; 587 } 588 } 589 590 /** Same but returns null instead throwing a NoInstanceException 591 */ 592 Type instantiate(Env<AttrContext> env, 593 Type site, 594 Symbol m, 595 ResultInfo resultInfo, 596 List<Type> argtypes, 597 List<Type> typeargtypes, 598 boolean allowBoxing, 599 boolean useVarargs, 600 Warner warn) { 601 try { 602 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, 603 allowBoxing, useVarargs, warn); 604 } catch (InapplicableMethodException ex) { 605 return null; 606 } 607 } 608 609 /** 610 * This interface defines an entry point that should be used to perform a 611 * method check. A method check usually consist in determining as to whether 612 * a set of types (actuals) is compatible with another set of types (formals). 613 * Since the notion of compatibility can vary depending on the circumstances, 614 * this interfaces allows to easily add new pluggable method check routines. 615 */ 616 interface MethodCheck { 617 /** 618 * Main method check routine. A method check usually consist in determining 619 * as to whether a set of types (actuals) is compatible with another set of 620 * types (formals). If an incompatibility is found, an unchecked exception 621 * is assumed to be thrown. 622 */ 623 void argumentsAcceptable(Env<AttrContext> env, 624 DeferredAttrContext deferredAttrContext, 625 List<Type> argtypes, 626 List<Type> formals, 627 Warner warn); 628 629 /** 630 * Retrieve the method check object that will be used during a 631 * most specific check. 632 */ 633 MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict); 634 } 635 636 /** 637 * Helper enum defining all method check diagnostics (used by resolveMethodCheck). 638 */ 639 enum MethodCheckDiag { 640 /** 641 * Actuals and formals differs in length. 642 */ 643 ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"), 644 /** 645 * An actual is incompatible with a formal. 646 */ 647 ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"), 648 /** 649 * An actual is incompatible with the varargs element type. 650 */ 651 VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"), 652 /** 653 * The varargs element type is inaccessible. 654 */ 655 INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type"); 656 657 final String basicKey; 658 final String inferKey; 659 660 MethodCheckDiag(String basicKey, String inferKey) { 661 this.basicKey = basicKey; 662 this.inferKey = inferKey; 663 } 664 } 665 666 /** 667 * Dummy method check object. All methods are deemed applicable, regardless 668 * of their formal parameter types. 669 */ 670 MethodCheck nilMethodCheck = new MethodCheck() { 671 public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) { 672 //do nothing - method always applicable regardless of actuals 673 } 674 675 public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) { 676 return this; 677 } 678 }; 679 680 /** 681 * Base class for 'real' method checks. The class defines the logic for 682 * iterating through formals and actuals and provides and entry point 683 * that can be used by subclasses in order to define the actual check logic. 684 */ 685 abstract class AbstractMethodCheck implements MethodCheck { 686 @Override 687 public void argumentsAcceptable(final Env<AttrContext> env, 688 DeferredAttrContext deferredAttrContext, 689 List<Type> argtypes, 690 List<Type> formals, 691 Warner warn) { 692 //should we expand formals? 693 boolean useVarargs = deferredAttrContext.phase.isVarargsRequired(); 694 695 //inference context used during this method check 696 InferenceContext inferenceContext = deferredAttrContext.inferenceContext; 697 698 Type varargsFormal = useVarargs ? formals.last() : null; 699 700 if (varargsFormal == null && 701 argtypes.size() != formals.size()) { 702 reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 703 } 704 705 while (argtypes.nonEmpty() && formals.head != varargsFormal) { 706 checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn); 707 argtypes = argtypes.tail; 708 formals = formals.tail; 709 } 710 711 if (formals.head != varargsFormal) { 712 reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 713 } 714 715 if (useVarargs) { 716 //note: if applicability check is triggered by most specific test, 717 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) 718 final Type elt = types.elemtype(varargsFormal); 719 while (argtypes.nonEmpty()) { 720 checkArg(true, argtypes.head, elt, deferredAttrContext, warn); 721 argtypes = argtypes.tail; 722 } 723 } 724 } 725 726 /** 727 * Does the actual argument conforms to the corresponding formal? 728 */ 729 abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn); 730 731 protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { 732 boolean inferDiag = inferenceContext != infer.emptyContext; 733 InapplicableMethodException ex = inferDiag ? 734 infer.inferenceException : inapplicableMethodException; 735 if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) { 736 Object[] args2 = new Object[args.length + 1]; 737 System.arraycopy(args, 0, args2, 1, args.length); 738 args2[0] = inferenceContext.inferenceVars(); 739 args = args2; 740 } 741 throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args); 742 } 743 744 public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) { 745 return nilMethodCheck; 746 } 747 } 748 749 /** 750 * Arity-based method check. A method is applicable if the number of actuals 751 * supplied conforms to the method signature. 752 */ 753 MethodCheck arityMethodCheck = new AbstractMethodCheck() { 754 @Override 755 void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 756 //do nothing - actual always compatible to formals 757 } 758 }; 759 760 /** 761 * Main method applicability routine. Given a list of actual types A, 762 * a list of formal types F, determines whether the types in A are 763 * compatible (by method invocation conversion) with the types in F. 764 * 765 * Since this routine is shared between overload resolution and method 766 * type-inference, a (possibly empty) inference context is used to convert 767 * formal types to the corresponding 'undet' form ahead of a compatibility 768 * check so that constraints can be propagated and collected. 769 * 770 * Moreover, if one or more types in A is a deferred type, this routine uses 771 * DeferredAttr in order to perform deferred attribution. If one or more actual 772 * deferred types are stuck, they are placed in a queue and revisited later 773 * after the remainder of the arguments have been seen. If this is not sufficient 774 * to 'unstuck' the argument, a cyclic inference error is called out. 775 * 776 * A method check handler (see above) is used in order to report errors. 777 */ 778 MethodCheck resolveMethodCheck = new AbstractMethodCheck() { 779 780 @Override 781 void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 782 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); 783 mresult.check(null, actual); 784 } 785 786 @Override 787 public void argumentsAcceptable(final Env<AttrContext> env, 788 DeferredAttrContext deferredAttrContext, 789 List<Type> argtypes, 790 List<Type> formals, 791 Warner warn) { 792 super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn); 793 //should we expand formals? 794 if (deferredAttrContext.phase.isVarargsRequired()) { 795 //check varargs element type accessibility 796 varargsAccessible(env, types.elemtype(formals.last()), 797 deferredAttrContext.inferenceContext); 798 } 799 } 800 801 private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) { 802 if (inferenceContext.free(t)) { 803 inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() { 804 @Override 805 public void typesInferred(InferenceContext inferenceContext) { 806 varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext); 807 } 808 }); 809 } else { 810 if (!isAccessible(env, t)) { 811 Symbol location = env.enclClass.sym; 812 reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); 813 } 814 } 815 } 816 817 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, 818 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { 819 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { 820 MethodCheckDiag methodDiag = varargsCheck ? 821 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; 822 823 @Override 824 public void report(DiagnosticPosition pos, JCDiagnostic details) { 825 reportMC(methodDiag, deferredAttrContext.inferenceContext, details); 826 } 827 }; 828 return new MethodResultInfo(to, checkContext); 829 } 830 831 @Override 832 public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) { 833 return new MostSpecificCheck(strict, actuals); 834 } 835 }; 836 837 /** 838 * Check context to be used during method applicability checks. A method check 839 * context might contain inference variables. 840 */ 841 abstract class MethodCheckContext implements CheckContext { 842 843 boolean strict; 844 DeferredAttrContext deferredAttrContext; 845 Warner rsWarner; 846 847 public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) { 848 this.strict = strict; 849 this.deferredAttrContext = deferredAttrContext; 850 this.rsWarner = rsWarner; 851 } 852 853 public boolean compatible(Type found, Type req, Warner warn) { 854 return strict ? 855 types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req), warn) : 856 types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req), warn); 857 } 858 859 public void report(DiagnosticPosition pos, JCDiagnostic details) { 860 throw inapplicableMethodException.setMessage(details); 861 } 862 863 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) { 864 return rsWarner; 865 } 866 867 public InferenceContext inferenceContext() { 868 return deferredAttrContext.inferenceContext; 869 } 870 871 public DeferredAttrContext deferredAttrContext() { 872 return deferredAttrContext; 873 } 874 } 875 876 /** 877 * ResultInfo class to be used during method applicability checks. Check 878 * for deferred types goes through special path. 879 */ 880 class MethodResultInfo extends ResultInfo { 881 882 public MethodResultInfo(Type pt, CheckContext checkContext) { 883 attr.super(VAL, pt, checkContext); 884 } 885 886 @Override 887 protected Type check(DiagnosticPosition pos, Type found) { 888 if (found.hasTag(DEFERRED)) { 889 DeferredType dt = (DeferredType)found; 890 return dt.check(this); 891 } else { 892 return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType())))); 893 } 894 } 895 896 @Override 897 protected MethodResultInfo dup(Type newPt) { 898 return new MethodResultInfo(newPt, checkContext); 899 } 900 901 @Override 902 protected ResultInfo dup(CheckContext newContext) { 903 return new MethodResultInfo(pt, newContext); 904 } 905 } 906 907 /** 908 * Most specific method applicability routine. Given a list of actual types A, 909 * a list of formal types F1, and a list of formal types F2, the routine determines 910 * as to whether the types in F1 can be considered more specific than those in F2 w.r.t. 911 * argument types A. 912 */ 913 class MostSpecificCheck implements MethodCheck { 914 915 boolean strict; 916 List<Type> actuals; 917 918 MostSpecificCheck(boolean strict, List<Type> actuals) { 919 this.strict = strict; 920 this.actuals = actuals; 921 } 922 923 @Override 924 public void argumentsAcceptable(final Env<AttrContext> env, 925 DeferredAttrContext deferredAttrContext, 926 List<Type> formals1, 927 List<Type> formals2, 928 Warner warn) { 929 formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired()); 930 while (formals2.nonEmpty()) { 931 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head); 932 mresult.check(null, formals1.head); 933 formals1 = formals1.tail; 934 formals2 = formals2.tail; 935 actuals = actuals.isEmpty() ? actuals : actuals.tail; 936 } 937 } 938 939 /** 940 * Create a method check context to be used during the most specific applicability check 941 */ 942 ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext, 943 Warner rsWarner, Type actual) { 944 return attr.new ResultInfo(Kinds.VAL, to, 945 new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual)); 946 } 947 948 /** 949 * Subclass of method check context class that implements most specific 950 * method conversion. If the actual type under analysis is a deferred type 951 * a full blown structural analysis is carried out. 952 */ 953 class MostSpecificCheckContext extends MethodCheckContext { 954 955 Type actual; 956 957 public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) { 958 super(strict, deferredAttrContext, rsWarner); 959 this.actual = actual; 960 } 961 962 public boolean compatible(Type found, Type req, Warner warn) { 963 if (!allowStructuralMostSpecific || actual == null) { 964 return super.compatible(found, req, warn); 965 } else { 966 switch (actual.getTag()) { 967 case DEFERRED: 968 DeferredType dt = (DeferredType) actual; 969 DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase); 970 return (e == null || e.speculativeTree == deferredAttr.stuckTree) 971 ? false : mostSpecific(found, req, e.speculativeTree, warn); 972 default: 973 return standaloneMostSpecific(found, req, actual, warn); 974 } 975 } 976 } 977 978 private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) { 979 MostSpecificChecker msc = new MostSpecificChecker(t, s, warn); 980 msc.scan(tree); 981 return msc.result; 982 } 983 984 boolean polyMostSpecific(Type t1, Type t2, Warner warn) { 985 return (!t1.isPrimitive() && t2.isPrimitive()) 986 ? true : super.compatible(t1, t2, warn); 987 } 988 989 boolean standaloneMostSpecific(Type t1, Type t2, Type exprType, Warner warn) { 990 return (exprType.isPrimitive() == t1.isPrimitive() 991 && exprType.isPrimitive() != t2.isPrimitive()) 992 ? true : super.compatible(t1, t2, warn); 993 } 994 995 /** 996 * Structural checker for most specific. 997 */ 998 class MostSpecificChecker extends DeferredAttr.PolyScanner { 999 1000 final Type t; 1001 final Type s; 1002 final Warner warn; 1003 boolean result; 1004 1005 MostSpecificChecker(Type t, Type s, Warner warn) { 1006 this.t = t; 1007 this.s = s; 1008 this.warn = warn; 1009 result = true; 1010 } 1011 1012 @Override 1013 void skip(JCTree tree) { 1014 result &= standaloneMostSpecific(t, s, tree.type, warn); 1015 } 1016 1017 @Override 1018 public void visitConditional(JCConditional tree) { 1019 if (tree.polyKind == PolyKind.STANDALONE) { 1020 result &= standaloneMostSpecific(t, s, tree.type, warn); 1021 } else { 1022 super.visitConditional(tree); 1023 } 1024 } 1025 1026 @Override 1027 public void visitApply(JCMethodInvocation tree) { 1028 result &= (tree.polyKind == PolyKind.STANDALONE) 1029 ? standaloneMostSpecific(t, s, tree.type, warn) 1030 : polyMostSpecific(t, s, warn); 1031 } 1032 1033 @Override 1034 public void visitNewClass(JCNewClass tree) { 1035 result &= (tree.polyKind == PolyKind.STANDALONE) 1036 ? standaloneMostSpecific(t, s, tree.type, warn) 1037 : polyMostSpecific(t, s, warn); 1038 } 1039 1040 @Override 1041 public void visitReference(JCMemberReference tree) { 1042 if (types.isFunctionalInterface(t.tsym) && 1043 types.isFunctionalInterface(s.tsym) && 1044 types.asSuper(t, s.tsym) == null && 1045 types.asSuper(s, t.tsym) == null) { 1046 Type desc_t = types.findDescriptorType(t); 1047 Type desc_s = types.findDescriptorType(s); 1048 if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) { 1049 if (!desc_s.getReturnType().hasTag(VOID)) { 1050 //perform structural comparison 1051 Type ret_t = desc_t.getReturnType(); 1052 Type ret_s = desc_s.getReturnType(); 1053 result &= ((tree.refPolyKind == PolyKind.STANDALONE) 1054 ? standaloneMostSpecific(ret_t, ret_s, tree.sym.type.getReturnType(), warn) 1055 : polyMostSpecific(ret_t, ret_s, warn)); 1056 } else { 1057 return; 1058 } 1059 } else { 1060 result &= false; 1061 } 1062 } else { 1063 result &= MostSpecificCheckContext.super.compatible(t, s, warn); 1064 } 1065 } 1066 1067 @Override 1068 public void visitLambda(JCLambda tree) { 1069 if (types.isFunctionalInterface(t.tsym) && 1070 types.isFunctionalInterface(s.tsym) && 1071 types.asSuper(t, s.tsym) == null && 1072 types.asSuper(s, t.tsym) == null) { 1073 Type desc_t = types.findDescriptorType(t); 1074 Type desc_s = types.findDescriptorType(s); 1075 if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT 1076 || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) { 1077 if (!desc_s.getReturnType().hasTag(VOID)) { 1078 //perform structural comparison 1079 Type ret_t = desc_t.getReturnType(); 1080 Type ret_s = desc_s.getReturnType(); 1081 scanLambdaBody(tree, ret_t, ret_s); 1082 } else { 1083 return; 1084 } 1085 } else { 1086 result &= false; 1087 } 1088 } else { 1089 result &= MostSpecificCheckContext.super.compatible(t, s, warn); 1090 } 1091 } 1092 //where 1093 1094 void scanLambdaBody(JCLambda lambda, final Type t, final Type s) { 1095 if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { 1096 result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn); 1097 } else { 1098 DeferredAttr.LambdaReturnScanner lambdaScanner = 1099 new DeferredAttr.LambdaReturnScanner() { 1100 @Override 1101 public void visitReturn(JCReturn tree) { 1102 if (tree.expr != null) { 1103 result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn); 1104 } 1105 } 1106 }; 1107 lambdaScanner.scan(lambda.body); 1108 } 1109 } 1110 } 1111 } 1112 1113 public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) { 1114 Assert.error("Cannot get here!"); 1115 return null; 1116 } 1117 } 1118 1119 public static class InapplicableMethodException extends RuntimeException { 1120 private static final long serialVersionUID = 0; 1121 1122 JCDiagnostic diagnostic; 1123 JCDiagnostic.Factory diags; 1124 1125 InapplicableMethodException(JCDiagnostic.Factory diags) { 1126 this.diagnostic = null; 1127 this.diags = diags; 1128 } 1129 InapplicableMethodException setMessage() { 1130 return setMessage((JCDiagnostic)null); 1131 } 1132 InapplicableMethodException setMessage(String key) { 1133 return setMessage(key != null ? diags.fragment(key) : null); 1134 } 1135 InapplicableMethodException setMessage(String key, Object... args) { 1136 return setMessage(key != null ? diags.fragment(key, args) : null); 1137 } 1138 InapplicableMethodException setMessage(JCDiagnostic diag) { 1139 this.diagnostic = diag; 1140 return this; 1141 } 1142 1143 public JCDiagnostic getDiagnostic() { 1144 return diagnostic; 1145 } 1146 } 1147 private final InapplicableMethodException inapplicableMethodException; 1148 1149 /* *************************************************************************** 1150 * Symbol lookup 1151 * the following naming conventions for arguments are used 1152 * 1153 * env is the environment where the symbol was mentioned 1154 * site is the type of which the symbol is a member 1155 * name is the symbol's name 1156 * if no arguments are given 1157 * argtypes are the value arguments, if we search for a method 1158 * 1159 * If no symbol was found, a ResolveError detailing the problem is returned. 1160 ****************************************************************************/ 1161 1162 /** Find field. Synthetic fields are always skipped. 1163 * @param env The current environment. 1164 * @param site The original type from where the selection takes place. 1165 * @param name The name of the field. 1166 * @param c The class to search for the field. This is always 1167 * a superclass or implemented interface of site's class. 1168 */ 1169 Symbol findField(Env<AttrContext> env, 1170 Type site, 1171 Name name, 1172 TypeSymbol c) { 1173 while (c.type.hasTag(TYPEVAR)) 1174 c = c.type.getUpperBound().tsym; 1175 Symbol bestSoFar = varNotFound; 1176 Symbol sym; 1177 Scope.Entry e = c.members().lookup(name); 1178 while (e.scope != null) { 1179 if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) { 1180 return isAccessible(env, site, e.sym) 1181 ? e.sym : new AccessError(env, site, e.sym); 1182 } 1183 e = e.next(); 1184 } 1185 Type st = types.supertype(c.type); 1186 if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) { 1187 sym = findField(env, site, name, st.tsym); 1188 if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1189 } 1190 for (List<Type> l = types.interfaces(c.type); 1191 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1192 l = l.tail) { 1193 sym = findField(env, site, name, l.head.tsym); 1194 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 1195 sym.owner != bestSoFar.owner) 1196 bestSoFar = new AmbiguityError(bestSoFar, sym); 1197 else if (sym.kind < bestSoFar.kind) 1198 bestSoFar = sym; 1199 } 1200 return bestSoFar; 1201 } 1202 1203 /** Resolve a field identifier, throw a fatal error if not found. 1204 * @param pos The position to use for error reporting. 1205 * @param env The environment current at the method invocation. 1206 * @param site The type of the qualifying expression, in which 1207 * identifier is searched. 1208 * @param name The identifier's name. 1209 */ 1210 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env, 1211 Type site, Name name) { 1212 Symbol sym = findField(env, site, name, site.tsym); 1213 if (sym.kind == VAR) return (VarSymbol)sym; 1214 else throw new FatalError( 1215 diags.fragment("fatal.err.cant.locate.field", 1216 name)); 1217 } 1218 1219 /** Find unqualified variable or field with given name. 1220 * Synthetic fields always skipped. 1221 * @param env The current environment. 1222 * @param name The name of the variable or field. 1223 */ 1224 Symbol findVar(Env<AttrContext> env, Name name) { 1225 Symbol bestSoFar = varNotFound; 1226 Symbol sym; 1227 Env<AttrContext> env1 = env; 1228 boolean staticOnly = false; 1229 while (env1.outer != null) { 1230 if (isStatic(env1)) staticOnly = true; 1231 Scope.Entry e = env1.info.scope.lookup(name); 1232 while (e.scope != null && 1233 (e.sym.kind != VAR || 1234 (e.sym.flags_field & SYNTHETIC) != 0)) 1235 e = e.next(); 1236 sym = (e.scope != null) 1237 ? e.sym 1238 : findField( 1239 env1, env1.enclClass.sym.type, name, env1.enclClass.sym); 1240 if (sym.exists()) { 1241 if (staticOnly && 1242 sym.kind == VAR && 1243 sym.owner.kind == TYP && 1244 (sym.flags() & STATIC) == 0) 1245 return new StaticError(sym); 1246 else 1247 return sym; 1248 } else if (sym.kind < bestSoFar.kind) { 1249 bestSoFar = sym; 1250 } 1251 1252 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1253 env1 = env1.outer; 1254 } 1255 1256 sym = findField(env, syms.predefClass.type, name, syms.predefClass); 1257 if (sym.exists()) 1258 return sym; 1259 if (bestSoFar.exists()) 1260 return bestSoFar; 1261 1262 Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 1263 for (; e.scope != null; e = e.next()) { 1264 sym = e.sym; 1265 Type origin = e.getOrigin().owner.type; 1266 if (sym.kind == VAR) { 1267 if (e.sym.owner.type != origin) 1268 sym = sym.clone(e.getOrigin().owner); 1269 return isAccessible(env, origin, sym) 1270 ? sym : new AccessError(env, origin, sym); 1271 } 1272 } 1273 1274 Symbol origin = null; 1275 e = env.toplevel.starImportScope.lookup(name); 1276 for (; e.scope != null; e = e.next()) { 1277 sym = e.sym; 1278 if (sym.kind != VAR) 1279 continue; 1280 // invariant: sym.kind == VAR 1281 if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner) 1282 return new AmbiguityError(bestSoFar, sym); 1283 else if (bestSoFar.kind >= VAR) { 1284 origin = e.getOrigin().owner; 1285 bestSoFar = isAccessible(env, origin.type, sym) 1286 ? sym : new AccessError(env, origin.type, sym); 1287 } 1288 } 1289 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type) 1290 return bestSoFar.clone(origin); 1291 else 1292 return bestSoFar; 1293 } 1294 1295 Warner noteWarner = new Warner(); 1296 1297 /** Select the best method for a call site among two choices. 1298 * @param env The current environment. 1299 * @param site The original type from where the 1300 * selection takes place. 1301 * @param argtypes The invocation's value arguments, 1302 * @param typeargtypes The invocation's type arguments, 1303 * @param sym Proposed new best match. 1304 * @param bestSoFar Previously found best match. 1305 * @param allowBoxing Allow boxing conversions of arguments. 1306 * @param useVarargs Box trailing arguments into an array for varargs. 1307 */ 1308 @SuppressWarnings("fallthrough") 1309 Symbol selectBest(Env<AttrContext> env, 1310 Type site, 1311 List<Type> argtypes, 1312 List<Type> typeargtypes, 1313 Symbol sym, 1314 Symbol bestSoFar, 1315 boolean allowBoxing, 1316 boolean useVarargs, 1317 boolean operator) { 1318 if (sym.kind == ERR || 1319 !sym.isInheritedIn(site.tsym, types)) { 1320 return bestSoFar; 1321 } else if (useVarargs && (sym.flags() & VARARGS) == 0) { 1322 return bestSoFar.kind >= ERRONEOUS ? 1323 new BadVarargsMethod((ResolveError)bestSoFar) : 1324 bestSoFar; 1325 } 1326 Assert.check(sym.kind < AMBIGUOUS); 1327 try { 1328 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, 1329 allowBoxing, useVarargs, types.noWarnings); 1330 if (!operator) 1331 currentResolutionContext.addApplicableCandidate(sym, mt); 1332 } catch (InapplicableMethodException ex) { 1333 if (!operator) 1334 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); 1335 switch (bestSoFar.kind) { 1336 case ABSENT_MTH: 1337 return new InapplicableSymbolError(currentResolutionContext); 1338 case WRONG_MTH: 1339 if (operator) return bestSoFar; 1340 bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1341 default: 1342 return bestSoFar; 1343 } 1344 } 1345 if (!isAccessible(env, site, sym)) { 1346 return (bestSoFar.kind == ABSENT_MTH) 1347 ? new AccessError(env, site, sym) 1348 : bestSoFar; 1349 } 1350 return (bestSoFar.kind > AMBIGUOUS) 1351 ? sym 1352 : mostSpecific(argtypes, sym, bestSoFar, env, site, 1353 allowBoxing && operator, useVarargs); 1354 } 1355 1356 /* Return the most specific of the two methods for a call, 1357 * given that both are accessible and applicable. 1358 * @param m1 A new candidate for most specific. 1359 * @param m2 The previous most specific candidate. 1360 * @param env The current environment. 1361 * @param site The original type from where the selection 1362 * takes place. 1363 * @param allowBoxing Allow boxing conversions of arguments. 1364 * @param useVarargs Box trailing arguments into an array for varargs. 1365 */ 1366 Symbol mostSpecific(List<Type> argtypes, Symbol m1, 1367 Symbol m2, 1368 Env<AttrContext> env, 1369 final Type site, 1370 boolean allowBoxing, 1371 boolean useVarargs) { 1372 switch (m2.kind) { 1373 case MTH: 1374 if (m1 == m2) return m1; 1375 boolean m1SignatureMoreSpecific = 1376 signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs); 1377 boolean m2SignatureMoreSpecific = 1378 signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs); 1379 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 1380 Type mt1 = types.memberType(site, m1); 1381 Type mt2 = types.memberType(site, m2); 1382 if (!types.overrideEquivalent(mt1, mt2)) 1383 return ambiguityError(m1, m2); 1384 1385 // same signature; select (a) the non-bridge method, or 1386 // (b) the one that overrides the other, or (c) the concrete 1387 // one, or (d) merge both abstract signatures 1388 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) 1389 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 1390 1391 // if one overrides or hides the other, use it 1392 TypeSymbol m1Owner = (TypeSymbol)m1.owner; 1393 TypeSymbol m2Owner = (TypeSymbol)m2.owner; 1394 if (types.asSuper(m1Owner.type, m2Owner) != null && 1395 ((m1.owner.flags_field & INTERFACE) == 0 || 1396 (m2.owner.flags_field & INTERFACE) != 0) && 1397 m1.overrides(m2, m1Owner, types, false)) 1398 return m1; 1399 if (types.asSuper(m2Owner.type, m1Owner) != null && 1400 ((m2.owner.flags_field & INTERFACE) == 0 || 1401 (m1.owner.flags_field & INTERFACE) != 0) && 1402 m2.overrides(m1, m2Owner, types, false)) 1403 return m2; 1404 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; 1405 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; 1406 if (m1Abstract && !m2Abstract) return m2; 1407 if (m2Abstract && !m1Abstract) return m1; 1408 // both abstract or both concrete 1409 return ambiguityError(m1, m2); 1410 } 1411 if (m1SignatureMoreSpecific) return m1; 1412 if (m2SignatureMoreSpecific) return m2; 1413 return ambiguityError(m1, m2); 1414 case AMBIGUOUS: 1415 //check if m1 is more specific than all ambiguous methods in m2 1416 AmbiguityError e = (AmbiguityError)m2; 1417 for (Symbol s : e.ambiguousSyms) { 1418 if (mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs) != m1) { 1419 return e.addAmbiguousSymbol(m1); 1420 } 1421 } 1422 return m1; 1423 default: 1424 throw new AssertionError(); 1425 } 1426 } 1427 //where 1428 private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) { 1429 noteWarner.clear(); 1430 int maxLength = Math.max( 1431 Math.max(m1.type.getParameterTypes().length(), actuals.length()), 1432 m2.type.getParameterTypes().length()); 1433 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1434 try { 1435 currentResolutionContext = new MethodResolutionContext(); 1436 currentResolutionContext.step = prevResolutionContext.step; 1437 currentResolutionContext.methodCheck = 1438 prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing); 1439 Type mst = instantiate(env, site, m2, null, 1440 adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null, 1441 allowBoxing, useVarargs, noteWarner); 1442 return mst != null && 1443 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); 1444 } finally { 1445 currentResolutionContext = prevResolutionContext; 1446 } 1447 } 1448 private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) { 1449 if ((msym.flags() & VARARGS) != 0 && allowVarargs) { 1450 Type varargsElem = types.elemtype(args.last()); 1451 if (varargsElem == null) { 1452 Assert.error("Bad varargs = " + args.last() + " " + msym); 1453 } 1454 List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse(); 1455 while (newArgs.length() < length) { 1456 newArgs = newArgs.append(newArgs.last()); 1457 } 1458 return newArgs; 1459 } else { 1460 return args; 1461 } 1462 } 1463 //where 1464 Type mostSpecificReturnType(Type mt1, Type mt2) { 1465 Type rt1 = mt1.getReturnType(); 1466 Type rt2 = mt2.getReturnType(); 1467 1468 if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) { 1469 //if both are generic methods, adjust return type ahead of subtyping check 1470 rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments()); 1471 } 1472 //first use subtyping, then return type substitutability 1473 if (types.isSubtype(rt1, rt2)) { 1474 return mt1; 1475 } else if (types.isSubtype(rt2, rt1)) { 1476 return mt2; 1477 } else if (types.returnTypeSubstitutable(mt1, mt2)) { 1478 return mt1; 1479 } else if (types.returnTypeSubstitutable(mt2, mt1)) { 1480 return mt2; 1481 } else { 1482 return null; 1483 } 1484 } 1485 //where 1486 Symbol ambiguityError(Symbol m1, Symbol m2) { 1487 if (((m1.flags() | m2.flags()) & CLASH) != 0) { 1488 return (m1.flags() & CLASH) == 0 ? m1 : m2; 1489 } else { 1490 return new AmbiguityError(m1, m2); 1491 } 1492 } 1493 1494 Symbol findMethodInScope(Env<AttrContext> env, 1495 Type site, 1496 Name name, 1497 List<Type> argtypes, 1498 List<Type> typeargtypes, 1499 Scope sc, 1500 Symbol bestSoFar, 1501 boolean allowBoxing, 1502 boolean useVarargs, 1503 boolean operator, 1504 boolean abstractok) { 1505 for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) { 1506 bestSoFar = selectBest(env, site, argtypes, typeargtypes, s, 1507 bestSoFar, allowBoxing, useVarargs, operator); 1508 } 1509 return bestSoFar; 1510 } 1511 //where 1512 class LookupFilter implements Filter<Symbol> { 1513 1514 boolean abstractOk; 1515 1516 LookupFilter(boolean abstractOk) { 1517 this.abstractOk = abstractOk; 1518 } 1519 1520 public boolean accepts(Symbol s) { 1521 long flags = s.flags(); 1522 return s.kind == MTH && 1523 (flags & SYNTHETIC) == 0 && 1524 (abstractOk || 1525 (flags & DEFAULT) != 0 || 1526 (flags & ABSTRACT) == 0); 1527 } 1528 }; 1529 1530 /** Find best qualified method matching given name, type and value 1531 * arguments. 1532 * @param env The current environment. 1533 * @param site The original type from where the selection 1534 * takes place. 1535 * @param name The method's name. 1536 * @param argtypes The method's value arguments. 1537 * @param typeargtypes The method's type arguments 1538 * @param allowBoxing Allow boxing conversions of arguments. 1539 * @param useVarargs Box trailing arguments into an array for varargs. 1540 */ 1541 Symbol findMethod(Env<AttrContext> env, 1542 Type site, 1543 Name name, 1544 List<Type> argtypes, 1545 List<Type> typeargtypes, 1546 boolean allowBoxing, 1547 boolean useVarargs, 1548 boolean operator) { 1549 Symbol bestSoFar = methodNotFound; 1550 bestSoFar = findMethod(env, 1551 site, 1552 name, 1553 argtypes, 1554 typeargtypes, 1555 site.tsym.type, 1556 bestSoFar, 1557 allowBoxing, 1558 useVarargs, 1559 operator); 1560 reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar); 1561 return bestSoFar; 1562 } 1563 // where 1564 private Symbol findMethod(Env<AttrContext> env, 1565 Type site, 1566 Name name, 1567 List<Type> argtypes, 1568 List<Type> typeargtypes, 1569 Type intype, 1570 Symbol bestSoFar, 1571 boolean allowBoxing, 1572 boolean useVarargs, 1573 boolean operator) { 1574 @SuppressWarnings({"unchecked","rawtypes"}) 1575 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() }; 1576 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK; 1577 for (TypeSymbol s : superclasses(intype)) { 1578 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1579 s.members(), bestSoFar, allowBoxing, useVarargs, operator, true); 1580 if (name == names.init) return bestSoFar; 1581 iphase = (iphase == null) ? null : iphase.update(s, this); 1582 if (iphase != null) { 1583 for (Type itype : types.interfaces(s.type)) { 1584 itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]); 1585 } 1586 } 1587 } 1588 1589 Symbol concrete = bestSoFar.kind < ERR && 1590 (bestSoFar.flags() & ABSTRACT) == 0 ? 1591 bestSoFar : methodNotFound; 1592 1593 for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) { 1594 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && !allowDefaultMethods) break; 1595 //keep searching for abstract methods 1596 for (Type itype : itypes[iphase2.ordinal()]) { 1597 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure()) 1598 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && 1599 (itype.tsym.flags() & DEFAULT) == 0) continue; 1600 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1601 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true); 1602 if (concrete != bestSoFar && 1603 concrete.kind < ERR && bestSoFar.kind < ERR && 1604 types.isSubSignature(concrete.type, bestSoFar.type)) { 1605 //this is an hack - as javac does not do full membership checks 1606 //most specific ends up comparing abstract methods that might have 1607 //been implemented by some concrete method in a subclass and, 1608 //because of raw override, it is possible for an abstract method 1609 //to be more specific than the concrete method - so we need 1610 //to explicitly call that out (see CR 6178365) 1611 bestSoFar = concrete; 1612 } 1613 } 1614 } 1615 return bestSoFar; 1616 } 1617 1618 enum InterfaceLookupPhase { 1619 ABSTRACT_OK() { 1620 @Override 1621 InterfaceLookupPhase update(Symbol s, Resolve rs) { 1622 //We should not look for abstract methods if receiver is a concrete class 1623 //(as concrete classes are expected to implement all abstracts coming 1624 //from superinterfaces) 1625 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) { 1626 return this; 1627 } else if (rs.allowDefaultMethods) { 1628 return DEFAULT_OK; 1629 } else { 1630 return null; 1631 } 1632 } 1633 }, 1634 DEFAULT_OK() { 1635 @Override 1636 InterfaceLookupPhase update(Symbol s, Resolve rs) { 1637 return this; 1638 } 1639 }; 1640 1641 abstract InterfaceLookupPhase update(Symbol s, Resolve rs); 1642 } 1643 1644 /** 1645 * Return an Iterable object to scan the superclasses of a given type. 1646 * It's crucial that the scan is done lazily, as we don't want to accidentally 1647 * access more supertypes than strictly needed (as this could trigger completion 1648 * errors if some of the not-needed supertypes are missing/ill-formed). 1649 */ 1650 Iterable<TypeSymbol> superclasses(final Type intype) { 1651 return new Iterable<TypeSymbol>() { 1652 public Iterator<TypeSymbol> iterator() { 1653 return new Iterator<TypeSymbol>() { 1654 1655 List<TypeSymbol> seen = List.nil(); 1656 TypeSymbol currentSym = symbolFor(intype); 1657 TypeSymbol prevSym = null; 1658 1659 public boolean hasNext() { 1660 if (currentSym == syms.noSymbol) { 1661 currentSym = symbolFor(types.supertype(prevSym.type)); 1662 } 1663 return currentSym != null; 1664 } 1665 1666 public TypeSymbol next() { 1667 prevSym = currentSym; 1668 currentSym = syms.noSymbol; 1669 Assert.check(prevSym != null || prevSym != syms.noSymbol); 1670 return prevSym; 1671 } 1672 1673 public void remove() { 1674 throw new UnsupportedOperationException(); 1675 } 1676 1677 TypeSymbol symbolFor(Type t) { 1678 if (!t.hasTag(CLASS) && 1679 !t.hasTag(TYPEVAR)) { 1680 return null; 1681 } 1682 while (t.hasTag(TYPEVAR)) 1683 t = t.getUpperBound(); 1684 if (seen.contains(t.tsym)) { 1685 //degenerate case in which we have a circular 1686 //class hierarchy - because of ill-formed classfiles 1687 return null; 1688 } 1689 seen = seen.prepend(t.tsym); 1690 return t.tsym; 1691 } 1692 }; 1693 } 1694 }; 1695 } 1696 1697 /** Find unqualified method matching given name, type and value arguments. 1698 * @param env The current environment. 1699 * @param name The method's name. 1700 * @param argtypes The method's value arguments. 1701 * @param typeargtypes The method's type arguments. 1702 * @param allowBoxing Allow boxing conversions of arguments. 1703 * @param useVarargs Box trailing arguments into an array for varargs. 1704 */ 1705 Symbol findFun(Env<AttrContext> env, Name name, 1706 List<Type> argtypes, List<Type> typeargtypes, 1707 boolean allowBoxing, boolean useVarargs) { 1708 Symbol bestSoFar = methodNotFound; 1709 Symbol sym; 1710 Env<AttrContext> env1 = env; 1711 boolean staticOnly = false; 1712 while (env1.outer != null) { 1713 if (isStatic(env1)) staticOnly = true; 1714 sym = findMethod( 1715 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 1716 allowBoxing, useVarargs, false); 1717 if (sym.exists()) { 1718 if (staticOnly && 1719 sym.kind == MTH && 1720 sym.owner.kind == TYP && 1721 (sym.flags() & STATIC) == 0) return new StaticError(sym); 1722 else return sym; 1723 } else if (sym.kind < bestSoFar.kind) { 1724 bestSoFar = sym; 1725 } 1726 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1727 env1 = env1.outer; 1728 } 1729 1730 sym = findMethod(env, syms.predefClass.type, name, argtypes, 1731 typeargtypes, allowBoxing, useVarargs, false); 1732 if (sym.exists()) 1733 return sym; 1734 1735 Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 1736 for (; e.scope != null; e = e.next()) { 1737 sym = e.sym; 1738 Type origin = e.getOrigin().owner.type; 1739 if (sym.kind == MTH) { 1740 if (e.sym.owner.type != origin) 1741 sym = sym.clone(e.getOrigin().owner); 1742 if (!isAccessible(env, origin, sym)) 1743 sym = new AccessError(env, origin, sym); 1744 bestSoFar = selectBest(env, origin, 1745 argtypes, typeargtypes, 1746 sym, bestSoFar, 1747 allowBoxing, useVarargs, false); 1748 } 1749 } 1750 if (bestSoFar.exists()) 1751 return bestSoFar; 1752 1753 e = env.toplevel.starImportScope.lookup(name); 1754 for (; e.scope != null; e = e.next()) { 1755 sym = e.sym; 1756 Type origin = e.getOrigin().owner.type; 1757 if (sym.kind == MTH) { 1758 if (e.sym.owner.type != origin) 1759 sym = sym.clone(e.getOrigin().owner); 1760 if (!isAccessible(env, origin, sym)) 1761 sym = new AccessError(env, origin, sym); 1762 bestSoFar = selectBest(env, origin, 1763 argtypes, typeargtypes, 1764 sym, bestSoFar, 1765 allowBoxing, useVarargs, false); 1766 } 1767 } 1768 return bestSoFar; 1769 } 1770 1771 /** Load toplevel or member class with given fully qualified name and 1772 * verify that it is accessible. 1773 * @param env The current environment. 1774 * @param name The fully qualified name of the class to be loaded. 1775 */ 1776 Symbol loadClass(Env<AttrContext> env, Name name) { 1777 try { 1778 ClassSymbol c = reader.loadClass(name); 1779 return isAccessible(env, c) ? c : new AccessError(c); 1780 } catch (ClassReader.BadClassFile err) { 1781 throw err; 1782 } catch (CompletionFailure ex) { 1783 return typeNotFound; 1784 } 1785 } 1786 1787 1788 /** 1789 * Find a type declared in a scope (not inherited). Return null 1790 * if none is found. 1791 * @param env The current environment. 1792 * @param site The original type from where the selection takes 1793 * place. 1794 * @param name The type's name. 1795 * @param c The class to search for the member type. This is 1796 * always a superclass or implemented interface of 1797 * site's class. 1798 */ 1799 Symbol findImmediateMemberType(Env<AttrContext> env, 1800 Type site, 1801 Name name, 1802 TypeSymbol c) { 1803 Scope.Entry e = c.members().lookup(name); 1804 while (e.scope != null) { 1805 if (e.sym.kind == TYP) { 1806 return isAccessible(env, site, e.sym) 1807 ? e.sym 1808 : new AccessError(env, site, e.sym); 1809 } 1810 e = e.next(); 1811 } 1812 return null; 1813 } 1814 1815 /** Find a member type inherited from a superclass or interface. 1816 * @param env The current environment. 1817 * @param site The original type from where the selection takes 1818 * place. 1819 * @param name The type's name. 1820 * @param c The class to search for the member type. This is 1821 * always a superclass or implemented interface of 1822 * site's class. 1823 */ 1824 Symbol findInheritedMemberType(Env<AttrContext> env, 1825 Type site, 1826 Name name, 1827 TypeSymbol c) { 1828 Symbol bestSoFar = typeNotFound; 1829 Symbol sym; 1830 Type st = types.supertype(c.type); 1831 if (st != null && st.hasTag(CLASS)) { 1832 sym = findMemberType(env, site, name, st.tsym); 1833 if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1834 } 1835 for (List<Type> l = types.interfaces(c.type); 1836 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1837 l = l.tail) { 1838 sym = findMemberType(env, site, name, l.head.tsym); 1839 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 1840 sym.owner != bestSoFar.owner) 1841 bestSoFar = new AmbiguityError(bestSoFar, sym); 1842 else if (sym.kind < bestSoFar.kind) 1843 bestSoFar = sym; 1844 } 1845 return bestSoFar; 1846 } 1847 1848 /** Find qualified member type. 1849 * @param env The current environment. 1850 * @param site The original type from where the selection takes 1851 * place. 1852 * @param name The type's name. 1853 * @param c The class to search for the member type. This is 1854 * always a superclass or implemented interface of 1855 * site's class. 1856 */ 1857 Symbol findMemberType(Env<AttrContext> env, 1858 Type site, 1859 Name name, 1860 TypeSymbol c) { 1861 Symbol sym = findImmediateMemberType(env, site, name, c); 1862 1863 if (sym != null) 1864 return sym; 1865 1866 return findInheritedMemberType(env, site, name, c); 1867 1868 } 1869 1870 /** Find a global type in given scope and load corresponding class. 1871 * @param env The current environment. 1872 * @param scope The scope in which to look for the type. 1873 * @param name The type's name. 1874 */ 1875 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) { 1876 Symbol bestSoFar = typeNotFound; 1877 for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) { 1878 Symbol sym = loadClass(env, e.sym.flatName()); 1879 if (bestSoFar.kind == TYP && sym.kind == TYP && 1880 bestSoFar != sym) 1881 return new AmbiguityError(bestSoFar, sym); 1882 else if (sym.kind < bestSoFar.kind) 1883 bestSoFar = sym; 1884 } 1885 return bestSoFar; 1886 } 1887 1888 /** Find an unqualified type symbol. 1889 * @param env The current environment. 1890 * @param name The type's name. 1891 */ 1892 Symbol findType(Env<AttrContext> env, Name name) { 1893 Symbol bestSoFar = typeNotFound; 1894 Symbol sym; 1895 boolean staticOnly = false; 1896 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) { 1897 // First, try the members declared in the class 1898 sym = findImmediateMemberType(env1, env1.enclClass.sym.type, 1899 name, env1.enclClass.sym); 1900 // Then try the type parameters 1901 if (sym == null) { 1902 if (isStatic(env1)) staticOnly = true; 1903 for (Scope.Entry e = env1.info.scope.lookup(name); 1904 e.scope != null; 1905 e = e.next()) { 1906 if (e.sym.kind == TYP) { 1907 if (staticOnly && 1908 e.sym.type.hasTag(TYPEVAR) && 1909 e.sym.owner.kind == TYP) 1910 return new StaticError(e.sym); 1911 return e.sym; 1912 } 1913 } 1914 sym = findInheritedMemberType(env1, env1.enclClass.sym.type, 1915 name, env1.enclClass.sym); 1916 } 1917 1918 if (staticOnly && sym.kind == TYP && 1919 sym.type.hasTag(CLASS) && 1920 sym.type.getEnclosingType().hasTag(CLASS) && 1921 env1.enclClass.sym.type.isParameterized() && 1922 sym.type.getEnclosingType().isParameterized()) 1923 return new StaticError(sym); 1924 else if (sym.exists()) return sym; 1925 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1926 1927 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass; 1928 if ((encl.sym.flags() & STATIC) != 0) 1929 staticOnly = true; 1930 } 1931 1932 if (!env.tree.hasTag(IMPORT)) { 1933 sym = findGlobalType(env, env.toplevel.namedImportScope, name); 1934 if (sym.exists()) return sym; 1935 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1936 1937 sym = findGlobalType(env, env.toplevel.packge.members(), name); 1938 if (sym.exists()) return sym; 1939 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1940 1941 sym = findGlobalType(env, env.toplevel.starImportScope, name); 1942 if (sym.exists()) return sym; 1943 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1944 } 1945 1946 return bestSoFar; 1947 } 1948 1949 /** Find an unqualified identifier which matches a specified kind set. 1950 * @param env The current environment. 1951 * @param name The identifier's name. 1952 * @param kind Indicates the possible symbol kinds 1953 * (a subset of VAL, TYP, PCK). 1954 */ 1955 Symbol findIdent(Env<AttrContext> env, Name name, int kind) { 1956 Symbol bestSoFar = typeNotFound; 1957 Symbol sym; 1958 1959 if ((kind & VAR) != 0) { 1960 sym = findVar(env, name); 1961 if (sym.exists()) return sym; 1962 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1963 } 1964 1965 if ((kind & TYP) != 0) { 1966 sym = findType(env, name); 1967 if (sym.kind==TYP) { 1968 reportDependence(env.enclClass.sym, sym); 1969 } 1970 if (sym.exists()) return sym; 1971 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1972 } 1973 1974 if ((kind & PCK) != 0) return reader.enterPackage(name); 1975 else return bestSoFar; 1976 } 1977 1978 /** Report dependencies. 1979 * @param from The enclosing class sym 1980 * @param to The found identifier that the class depends on. 1981 */ 1982 public void reportDependence(Symbol from, Symbol to) { 1983 // Override if you want to collect the reported dependencies. 1984 } 1985 1986 /** Find an identifier in a package which matches a specified kind set. 1987 * @param env The current environment. 1988 * @param name The identifier's name. 1989 * @param kind Indicates the possible symbol kinds 1990 * (a nonempty subset of TYP, PCK). 1991 */ 1992 Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck, 1993 Name name, int kind) { 1994 Name fullname = TypeSymbol.formFullName(name, pck); 1995 Symbol bestSoFar = typeNotFound; 1996 PackageSymbol pack = null; 1997 if ((kind & PCK) != 0) { 1998 pack = reader.enterPackage(fullname); 1999 if (pack.exists()) return pack; 2000 } 2001 if ((kind & TYP) != 0) { 2002 Symbol sym = loadClass(env, fullname); 2003 if (sym.exists()) { 2004 // don't allow programs to use flatnames 2005 if (name == sym.name) return sym; 2006 } 2007 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 2008 } 2009 return (pack != null) ? pack : bestSoFar; 2010 } 2011 2012 /** Find an identifier among the members of a given type `site'. 2013 * @param env The current environment. 2014 * @param site The type containing the symbol to be found. 2015 * @param name The identifier's name. 2016 * @param kind Indicates the possible symbol kinds 2017 * (a subset of VAL, TYP). 2018 */ 2019 Symbol findIdentInType(Env<AttrContext> env, Type site, 2020 Name name, int kind) { 2021 Symbol bestSoFar = typeNotFound; 2022 Symbol sym; 2023 if ((kind & VAR) != 0) { 2024 sym = findField(env, site, name, site.tsym); 2025 if (sym.exists()) return sym; 2026 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 2027 } 2028 2029 if ((kind & TYP) != 0) { 2030 sym = findMemberType(env, site, name, site.tsym); 2031 if (sym.exists()) return sym; 2032 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 2033 } 2034 return bestSoFar; 2035 } 2036 2037 /* *************************************************************************** 2038 * Access checking 2039 * The following methods convert ResolveErrors to ErrorSymbols, issuing 2040 * an error message in the process 2041 ****************************************************************************/ 2042 2043 /** If `sym' is a bad symbol: report error and return errSymbol 2044 * else pass through unchanged, 2045 * additional arguments duplicate what has been used in trying to find the 2046 * symbol {@literal (--> flyweight pattern)}. This improves performance since we 2047 * expect misses to happen frequently. 2048 * 2049 * @param sym The symbol that was found, or a ResolveError. 2050 * @param pos The position to use for error reporting. 2051 * @param location The symbol the served as a context for this lookup 2052 * @param site The original type from where the selection took place. 2053 * @param name The symbol's name. 2054 * @param qualified Did we get here through a qualified expression resolution? 2055 * @param argtypes The invocation's value arguments, 2056 * if we looked for a method. 2057 * @param typeargtypes The invocation's type arguments, 2058 * if we looked for a method. 2059 * @param logResolveHelper helper class used to log resolve errors 2060 */ 2061 Symbol accessInternal(Symbol sym, 2062 DiagnosticPosition pos, 2063 Symbol location, 2064 Type site, 2065 Name name, 2066 boolean qualified, 2067 List<Type> argtypes, 2068 List<Type> typeargtypes, 2069 LogResolveHelper logResolveHelper) { 2070 if (sym.kind >= AMBIGUOUS) { 2071 ResolveError errSym = (ResolveError)sym; 2072 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol); 2073 argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes); 2074 if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) { 2075 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes); 2076 } 2077 } 2078 return sym; 2079 } 2080 2081 /** 2082 * Variant of the generalized access routine, to be used for generating method 2083 * resolution diagnostics 2084 */ 2085 Symbol accessMethod(Symbol sym, 2086 DiagnosticPosition pos, 2087 Symbol location, 2088 Type site, 2089 Name name, 2090 boolean qualified, 2091 List<Type> argtypes, 2092 List<Type> typeargtypes) { 2093 return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper); 2094 } 2095 2096 /** Same as original accessMethod(), but without location. 2097 */ 2098 Symbol accessMethod(Symbol sym, 2099 DiagnosticPosition pos, 2100 Type site, 2101 Name name, 2102 boolean qualified, 2103 List<Type> argtypes, 2104 List<Type> typeargtypes) { 2105 return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes); 2106 } 2107 2108 /** 2109 * Variant of the generalized access routine, to be used for generating variable, 2110 * type resolution diagnostics 2111 */ 2112 Symbol accessBase(Symbol sym, 2113 DiagnosticPosition pos, 2114 Symbol location, 2115 Type site, 2116 Name name, 2117 boolean qualified) { 2118 return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper); 2119 } 2120 2121 /** Same as original accessBase(), but without location. 2122 */ 2123 Symbol accessBase(Symbol sym, 2124 DiagnosticPosition pos, 2125 Type site, 2126 Name name, 2127 boolean qualified) { 2128 return accessBase(sym, pos, site.tsym, site, name, qualified); 2129 } 2130 2131 interface LogResolveHelper { 2132 boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes); 2133 List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes); 2134 } 2135 2136 LogResolveHelper basicLogResolveHelper = new LogResolveHelper() { 2137 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2138 return !site.isErroneous(); 2139 } 2140 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2141 return argtypes; 2142 } 2143 }; 2144 2145 LogResolveHelper methodLogResolveHelper = new LogResolveHelper() { 2146 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2147 return !site.isErroneous() && 2148 !Type.isErroneous(argtypes) && 2149 (typeargtypes == null || !Type.isErroneous(typeargtypes)); 2150 } 2151 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2152 return (syms.operatorNames.contains(name)) ? 2153 argtypes : 2154 Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym)); 2155 } 2156 2157 class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap { 2158 2159 public ResolveDeferredRecoveryMap(Symbol msym) { 2160 deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step); 2161 } 2162 2163 @Override 2164 protected Type typeOf(DeferredType dt) { 2165 Type res = super.typeOf(dt); 2166 if (!res.isErroneous()) { 2167 switch (TreeInfo.skipParens(dt.tree).getTag()) { 2168 case LAMBDA: 2169 case REFERENCE: 2170 return dt; 2171 case CONDEXPR: 2172 return res == Type.recoveryType ? 2173 dt : res; 2174 } 2175 } 2176 return res; 2177 } 2178 } 2179 }; 2180 2181 /** Check that sym is not an abstract method. 2182 */ 2183 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { 2184 if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0) 2185 log.error(pos, "abstract.cant.be.accessed.directly", 2186 kindName(sym), sym, sym.location()); 2187 } 2188 2189 /* *************************************************************************** 2190 * Debugging 2191 ****************************************************************************/ 2192 2193 /** print all scopes starting with scope s and proceeding outwards. 2194 * used for debugging. 2195 */ 2196 public void printscopes(Scope s) { 2197 while (s != null) { 2198 if (s.owner != null) 2199 System.err.print(s.owner + ": "); 2200 for (Scope.Entry e = s.elems; e != null; e = e.sibling) { 2201 if ((e.sym.flags() & ABSTRACT) != 0) 2202 System.err.print("abstract "); 2203 System.err.print(e.sym + " "); 2204 } 2205 System.err.println(); 2206 s = s.next; 2207 } 2208 } 2209 2210 void printscopes(Env<AttrContext> env) { 2211 while (env.outer != null) { 2212 System.err.println("------------------------------"); 2213 printscopes(env.info.scope); 2214 env = env.outer; 2215 } 2216 } 2217 2218 public void printscopes(Type t) { 2219 while (t.hasTag(CLASS)) { 2220 printscopes(t.tsym.members()); 2221 t = types.supertype(t); 2222 } 2223 } 2224 2225 /* *************************************************************************** 2226 * Name resolution 2227 * Naming conventions are as for symbol lookup 2228 * Unlike the find... methods these methods will report access errors 2229 ****************************************************************************/ 2230 2231 /** Resolve an unqualified (non-method) identifier. 2232 * @param pos The position to use for error reporting. 2233 * @param env The environment current at the identifier use. 2234 * @param name The identifier's name. 2235 * @param kind The set of admissible symbol kinds for the identifier. 2236 */ 2237 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env, 2238 Name name, int kind) { 2239 return accessBase( 2240 findIdent(env, name, kind), 2241 pos, env.enclClass.sym.type, name, false); 2242 } 2243 2244 /** Resolve an unqualified method identifier. 2245 * @param pos The position to use for error reporting. 2246 * @param env The environment current at the method invocation. 2247 * @param name The identifier's name. 2248 * @param argtypes The types of the invocation's value arguments. 2249 * @param typeargtypes The types of the invocation's type arguments. 2250 */ 2251 Symbol resolveMethod(DiagnosticPosition pos, 2252 Env<AttrContext> env, 2253 Name name, 2254 List<Type> argtypes, 2255 List<Type> typeargtypes) { 2256 return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck, 2257 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) { 2258 @Override 2259 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2260 return findFun(env, name, argtypes, typeargtypes, 2261 phase.isBoxingRequired(), 2262 phase.isVarargsRequired()); 2263 }}); 2264 } 2265 2266 /** Resolve a qualified method identifier 2267 * @param pos The position to use for error reporting. 2268 * @param env The environment current at the method invocation. 2269 * @param site The type of the qualifying expression, in which 2270 * identifier is searched. 2271 * @param name The identifier's name. 2272 * @param argtypes The types of the invocation's value arguments. 2273 * @param typeargtypes The types of the invocation's type arguments. 2274 */ 2275 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 2276 Type site, Name name, List<Type> argtypes, 2277 List<Type> typeargtypes) { 2278 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes); 2279 } 2280 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 2281 Symbol location, Type site, Name name, List<Type> argtypes, 2282 List<Type> typeargtypes) { 2283 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes); 2284 } 2285 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext, 2286 DiagnosticPosition pos, Env<AttrContext> env, 2287 Symbol location, Type site, Name name, List<Type> argtypes, 2288 List<Type> typeargtypes) { 2289 return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) { 2290 @Override 2291 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2292 return findMethod(env, site, name, argtypes, typeargtypes, 2293 phase.isBoxingRequired(), 2294 phase.isVarargsRequired(), false); 2295 } 2296 @Override 2297 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2298 if (sym.kind >= AMBIGUOUS) { 2299 sym = super.access(env, pos, location, sym); 2300 } else if (allowMethodHandles) { 2301 MethodSymbol msym = (MethodSymbol)sym; 2302 if (msym.isSignaturePolymorphic(types)) { 2303 return findPolymorphicSignatureInstance(env, sym, argtypes); 2304 } 2305 } 2306 return sym; 2307 } 2308 }); 2309 } 2310 2311 /** Find or create an implicit method of exactly the given type (after erasure). 2312 * Searches in a side table, not the main scope of the site. 2313 * This emulates the lookup process required by JSR 292 in JVM. 2314 * @param env Attribution environment 2315 * @param spMethod signature polymorphic method - i.e. MH.invokeExact 2316 * @param argtypes The required argument types 2317 */ 2318 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, 2319 final Symbol spMethod, 2320 List<Type> argtypes) { 2321 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, 2322 (MethodSymbol)spMethod, currentResolutionContext, argtypes); 2323 for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) { 2324 if (types.isSameType(mtype, sym.type)) { 2325 return sym; 2326 } 2327 } 2328 2329 // create the desired method 2330 long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags; 2331 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) { 2332 @Override 2333 public Symbol baseSymbol() { 2334 return spMethod; 2335 } 2336 }; 2337 polymorphicSignatureScope.enter(msym); 2338 return msym; 2339 } 2340 2341 /** Resolve a qualified method identifier, throw a fatal error if not 2342 * found. 2343 * @param pos The position to use for error reporting. 2344 * @param env The environment current at the method invocation. 2345 * @param site The type of the qualifying expression, in which 2346 * identifier is searched. 2347 * @param name The identifier's name. 2348 * @param argtypes The types of the invocation's value arguments. 2349 * @param typeargtypes The types of the invocation's type arguments. 2350 */ 2351 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env, 2352 Type site, Name name, 2353 List<Type> argtypes, 2354 List<Type> typeargtypes) { 2355 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2356 resolveContext.internalResolution = true; 2357 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym, 2358 site, name, argtypes, typeargtypes); 2359 if (sym.kind == MTH) return (MethodSymbol)sym; 2360 else throw new FatalError( 2361 diags.fragment("fatal.err.cant.locate.meth", 2362 name)); 2363 } 2364 2365 /** Resolve constructor. 2366 * @param pos The position to use for error reporting. 2367 * @param env The environment current at the constructor invocation. 2368 * @param site The type of class for which a constructor is searched. 2369 * @param argtypes The types of the constructor invocation's value 2370 * arguments. 2371 * @param typeargtypes The types of the constructor invocation's type 2372 * arguments. 2373 */ 2374 Symbol resolveConstructor(DiagnosticPosition pos, 2375 Env<AttrContext> env, 2376 Type site, 2377 List<Type> argtypes, 2378 List<Type> typeargtypes) { 2379 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); 2380 } 2381 2382 private Symbol resolveConstructor(MethodResolutionContext resolveContext, 2383 final DiagnosticPosition pos, 2384 Env<AttrContext> env, 2385 Type site, 2386 List<Type> argtypes, 2387 List<Type> typeargtypes) { 2388 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 2389 @Override 2390 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2391 return findConstructor(pos, env, site, argtypes, typeargtypes, 2392 phase.isBoxingRequired(), 2393 phase.isVarargsRequired()); 2394 } 2395 }); 2396 } 2397 2398 /** Resolve a constructor, throw a fatal error if not found. 2399 * @param pos The position to use for error reporting. 2400 * @param env The environment current at the method invocation. 2401 * @param site The type to be constructed. 2402 * @param argtypes The types of the invocation's value arguments. 2403 * @param typeargtypes The types of the invocation's type arguments. 2404 */ 2405 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 2406 Type site, 2407 List<Type> argtypes, 2408 List<Type> typeargtypes) { 2409 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2410 resolveContext.internalResolution = true; 2411 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 2412 if (sym.kind == MTH) return (MethodSymbol)sym; 2413 else throw new FatalError( 2414 diags.fragment("fatal.err.cant.locate.ctor", site)); 2415 } 2416 2417 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 2418 Type site, List<Type> argtypes, 2419 List<Type> typeargtypes, 2420 boolean allowBoxing, 2421 boolean useVarargs) { 2422 Symbol sym = findMethod(env, site, 2423 names.init, argtypes, 2424 typeargtypes, allowBoxing, 2425 useVarargs, false); 2426 chk.checkDeprecated(pos, env.info.scope.owner, sym); 2427 return sym; 2428 } 2429 2430 /** Resolve constructor using diamond inference. 2431 * @param pos The position to use for error reporting. 2432 * @param env The environment current at the constructor invocation. 2433 * @param site The type of class for which a constructor is searched. 2434 * The scope of this class has been touched in attribution. 2435 * @param argtypes The types of the constructor invocation's value 2436 * arguments. 2437 * @param typeargtypes The types of the constructor invocation's type 2438 * arguments. 2439 */ 2440 Symbol resolveDiamond(DiagnosticPosition pos, 2441 Env<AttrContext> env, 2442 Type site, 2443 List<Type> argtypes, 2444 List<Type> typeargtypes) { 2445 return lookupMethod(env, pos, site.tsym, resolveMethodCheck, 2446 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 2447 @Override 2448 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2449 return findDiamond(env, site, argtypes, typeargtypes, 2450 phase.isBoxingRequired(), 2451 phase.isVarargsRequired()); 2452 } 2453 @Override 2454 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2455 if (sym.kind >= AMBIGUOUS) { 2456 final JCDiagnostic details = sym.kind == WRONG_MTH ? 2457 ((InapplicableSymbolError)sym).errCandidate().details : 2458 null; 2459 sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) { 2460 @Override 2461 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 2462 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 2463 String key = details == null ? 2464 "cant.apply.diamond" : 2465 "cant.apply.diamond.1"; 2466 return diags.create(dkind, log.currentSource(), pos, key, 2467 diags.fragment("diamond", site.tsym), details); 2468 } 2469 }; 2470 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); 2471 env.info.pendingResolutionPhase = currentResolutionContext.step; 2472 } 2473 return sym; 2474 }}); 2475 } 2476 2477 /** This method scans all the constructor symbol in a given class scope - 2478 * assuming that the original scope contains a constructor of the kind: 2479 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo, 2480 * a method check is executed against the modified constructor type: 2481 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond 2482 * inference. The inferred return type of the synthetic constructor IS 2483 * the inferred type for the diamond operator. 2484 */ 2485 private Symbol findDiamond(Env<AttrContext> env, 2486 Type site, 2487 List<Type> argtypes, 2488 List<Type> typeargtypes, 2489 boolean allowBoxing, 2490 boolean useVarargs) { 2491 Symbol bestSoFar = methodNotFound; 2492 for (Scope.Entry e = site.tsym.members().lookup(names.init); 2493 e.scope != null; 2494 e = e.next()) { 2495 final Symbol sym = e.sym; 2496 //- System.out.println(" e " + e.sym); 2497 if (sym.kind == MTH && 2498 (sym.flags_field & SYNTHETIC) == 0) { 2499 List<Type> oldParams = e.sym.type.hasTag(FORALL) ? 2500 ((ForAll)sym.type).tvars : 2501 List.<Type>nil(); 2502 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), 2503 types.createMethodTypeWithReturn(sym.type.asMethodType(), site)); 2504 MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) { 2505 @Override 2506 public Symbol baseSymbol() { 2507 return sym; 2508 } 2509 }; 2510 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 2511 newConstr, 2512 bestSoFar, 2513 allowBoxing, 2514 useVarargs, 2515 false); 2516 } 2517 } 2518 return bestSoFar; 2519 } 2520 2521 2522 2523 /** Resolve operator. 2524 * @param pos The position to use for error reporting. 2525 * @param optag The tag of the operation tree. 2526 * @param env The environment current at the operation. 2527 * @param argtypes The types of the operands. 2528 */ 2529 Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, 2530 Env<AttrContext> env, List<Type> argtypes) { 2531 MethodResolutionContext prevResolutionContext = currentResolutionContext; 2532 try { 2533 currentResolutionContext = new MethodResolutionContext(); 2534 Name name = treeinfo.operatorName(optag); 2535 env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC; 2536 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 2537 null, false, false, true); 2538 if (boxingEnabled && sym.kind >= WRONG_MTHS) 2539 env.info.pendingResolutionPhase = currentResolutionContext.step = BOX; 2540 sym = findMethod(env, syms.predefClass.type, name, argtypes, 2541 null, true, false, true); 2542 return accessMethod(sym, pos, env.enclClass.sym.type, name, 2543 false, argtypes, null); 2544 } 2545 finally { 2546 currentResolutionContext = prevResolutionContext; 2547 } 2548 } 2549 2550 /** Resolve operator. 2551 * @param pos The position to use for error reporting. 2552 * @param optag The tag of the operation tree. 2553 * @param env The environment current at the operation. 2554 * @param arg The type of the operand. 2555 */ 2556 Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) { 2557 return resolveOperator(pos, optag, env, List.of(arg)); 2558 } 2559 2560 /** Resolve binary operator. 2561 * @param pos The position to use for error reporting. 2562 * @param optag The tag of the operation tree. 2563 * @param env The environment current at the operation. 2564 * @param left The types of the left operand. 2565 * @param right The types of the right operand. 2566 */ 2567 Symbol resolveBinaryOperator(DiagnosticPosition pos, 2568 JCTree.Tag optag, 2569 Env<AttrContext> env, 2570 Type left, 2571 Type right) { 2572 return resolveOperator(pos, optag, env, List.of(left, right)); 2573 } 2574 2575 /** 2576 * Resolution of member references is typically done as a single 2577 * overload resolution step, where the argument types A are inferred from 2578 * the target functional descriptor. 2579 * 2580 * If the member reference is a method reference with a type qualifier, 2581 * a two-step lookup process is performed. The first step uses the 2582 * expected argument list A, while the second step discards the first 2583 * type from A (which is treated as a receiver type). 2584 * 2585 * There are two cases in which inference is performed: (i) if the member 2586 * reference is a constructor reference and the qualifier type is raw - in 2587 * which case diamond inference is used to infer a parameterization for the 2588 * type qualifier; (ii) if the member reference is an unbound reference 2589 * where the type qualifier is raw - in that case, during the unbound lookup 2590 * the receiver argument type is used to infer an instantiation for the raw 2591 * qualifier type. 2592 * 2593 * When a multi-step resolution process is exploited, it is an error 2594 * if two candidates are found (ambiguity). 2595 * 2596 * This routine returns a pair (T,S), where S is the member reference symbol, 2597 * and T is the type of the class in which S is defined. This is necessary as 2598 * the type T might be dynamically inferred (i.e. if constructor reference 2599 * has a raw qualifier). 2600 */ 2601 Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos, 2602 Env<AttrContext> env, 2603 JCMemberReference referenceTree, 2604 Type site, 2605 Name name, List<Type> argtypes, 2606 List<Type> typeargtypes, 2607 boolean boxingAllowed, 2608 MethodCheck methodCheck) { 2609 MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; 2610 2611 ReferenceLookupHelper boundLookupHelper; 2612 if (!name.equals(names.init)) { 2613 //method reference 2614 boundLookupHelper = 2615 new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); 2616 } else if (site.hasTag(ARRAY)) { 2617 //array constructor reference 2618 boundLookupHelper = 2619 new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); 2620 } else { 2621 //class constructor reference 2622 boundLookupHelper = 2623 new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); 2624 } 2625 2626 //step 1 - bound lookup 2627 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup()); 2628 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper); 2629 2630 //step 2 - unbound lookup 2631 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(); 2632 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup()); 2633 Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper); 2634 2635 //merge results 2636 Pair<Symbol, ReferenceLookupHelper> res; 2637 if (!lookupSuccess(unboundSym)) { 2638 res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper); 2639 env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase; 2640 } else if (lookupSuccess(boundSym)) { 2641 res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper); 2642 env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase; 2643 } else { 2644 res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper); 2645 env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase; 2646 } 2647 2648 return res; 2649 } 2650 //private 2651 boolean lookupSuccess(Symbol s) { 2652 return s.kind == MTH || s.kind == AMBIGUOUS; 2653 } 2654 2655 /** 2656 * Helper for defining custom method-like lookup logic; a lookup helper 2657 * provides hooks for (i) the actual lookup logic and (ii) accessing the 2658 * lookup result (this step might result in compiler diagnostics to be generated) 2659 */ 2660 abstract class LookupHelper { 2661 2662 /** name of the symbol to lookup */ 2663 Name name; 2664 2665 /** location in which the lookup takes place */ 2666 Type site; 2667 2668 /** actual types used during the lookup */ 2669 List<Type> argtypes; 2670 2671 /** type arguments used during the lookup */ 2672 List<Type> typeargtypes; 2673 2674 /** Max overload resolution phase handled by this helper */ 2675 MethodResolutionPhase maxPhase; 2676 2677 LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 2678 this.name = name; 2679 this.site = site; 2680 this.argtypes = argtypes; 2681 this.typeargtypes = typeargtypes; 2682 this.maxPhase = maxPhase; 2683 } 2684 2685 /** 2686 * Should lookup stop at given phase with given result 2687 */ 2688 protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { 2689 return phase.ordinal() > maxPhase.ordinal() || 2690 sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS; 2691 } 2692 2693 /** 2694 * Search for a symbol under a given overload resolution phase - this method 2695 * is usually called several times, once per each overload resolution phase 2696 */ 2697 abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase); 2698 2699 /** 2700 * Validate the result of the lookup 2701 */ 2702 abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym); 2703 } 2704 2705 abstract class BasicLookupHelper extends LookupHelper { 2706 2707 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) { 2708 super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY); 2709 } 2710 2711 @Override 2712 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2713 if (sym.kind == AMBIGUOUS) { 2714 AmbiguityError a_err = (AmbiguityError)sym; 2715 sym = a_err.mergeAbstracts(site); 2716 } 2717 if (sym.kind >= AMBIGUOUS) { 2718 //if nothing is found return the 'first' error 2719 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes); 2720 } 2721 return sym; 2722 } 2723 } 2724 2725 /** 2726 * Helper class for member reference lookup. A reference lookup helper 2727 * defines the basic logic for member reference lookup; a method gives 2728 * access to an 'unbound' helper used to perform an unbound member 2729 * reference lookup. 2730 */ 2731 abstract class ReferenceLookupHelper extends LookupHelper { 2732 2733 /** The member reference tree */ 2734 JCMemberReference referenceTree; 2735 2736 ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 2737 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 2738 super(name, site, argtypes, typeargtypes, maxPhase); 2739 this.referenceTree = referenceTree; 2740 2741 } 2742 2743 /** 2744 * Returns an unbound version of this lookup helper. By default, this 2745 * method returns an dummy lookup helper. 2746 */ 2747 ReferenceLookupHelper unboundLookup() { 2748 //dummy loopkup helper that always return 'methodNotFound' 2749 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { 2750 @Override 2751 ReferenceLookupHelper unboundLookup() { 2752 return this; 2753 } 2754 @Override 2755 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2756 return methodNotFound; 2757 } 2758 @Override 2759 ReferenceKind referenceKind(Symbol sym) { 2760 Assert.error(); 2761 return null; 2762 } 2763 }; 2764 } 2765 2766 /** 2767 * Get the kind of the member reference 2768 */ 2769 abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym); 2770 2771 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2772 if (sym.kind == AMBIGUOUS) { 2773 AmbiguityError a_err = (AmbiguityError)sym; 2774 sym = a_err.mergeAbstracts(site); 2775 } 2776 //skip error reporting 2777 return sym; 2778 } 2779 } 2780 2781 /** 2782 * Helper class for method reference lookup. The lookup logic is based 2783 * upon Resolve.findMethod; in certain cases, this helper class has a 2784 * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper). 2785 * In such cases, non-static lookup results are thrown away. 2786 */ 2787 class MethodReferenceLookupHelper extends ReferenceLookupHelper { 2788 2789 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 2790 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 2791 super(referenceTree, name, site, argtypes, typeargtypes, maxPhase); 2792 } 2793 2794 @Override 2795 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2796 return findMethod(env, site, name, argtypes, typeargtypes, 2797 phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); 2798 } 2799 2800 @Override 2801 ReferenceLookupHelper unboundLookup() { 2802 if (TreeInfo.isStaticSelector(referenceTree.expr, names) && 2803 argtypes.nonEmpty() && 2804 (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) { 2805 return new UnboundMethodReferenceLookupHelper(referenceTree, name, 2806 site, argtypes, typeargtypes, maxPhase); 2807 } else { 2808 return super.unboundLookup(); 2809 } 2810 } 2811 2812 @Override 2813 ReferenceKind referenceKind(Symbol sym) { 2814 if (sym.isStatic()) { 2815 return ReferenceKind.STATIC; 2816 } else { 2817 Name selName = TreeInfo.name(referenceTree.getQualifierExpression()); 2818 return selName != null && selName == names._super ? 2819 ReferenceKind.SUPER : 2820 ReferenceKind.BOUND; 2821 } 2822 } 2823 } 2824 2825 /** 2826 * Helper class for unbound method reference lookup. Essentially the same 2827 * as the basic method reference lookup helper; main difference is that static 2828 * lookup results are thrown away. If qualifier type is raw, an attempt to 2829 * infer a parameterized type is made using the first actual argument (that 2830 * would otherwise be ignored during the lookup). 2831 */ 2832 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper { 2833 2834 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 2835 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 2836 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase); 2837 if (site.isRaw() && !argtypes.head.hasTag(NONE)) { 2838 Type asSuperSite = types.asSuper(argtypes.head, site.tsym); 2839 this.site = asSuperSite; 2840 } 2841 } 2842 2843 @Override 2844 ReferenceLookupHelper unboundLookup() { 2845 return this; 2846 } 2847 2848 @Override 2849 ReferenceKind referenceKind(Symbol sym) { 2850 return ReferenceKind.UNBOUND; 2851 } 2852 } 2853 2854 /** 2855 * Helper class for array constructor lookup; an array constructor lookup 2856 * is simulated by looking up a method that returns the array type specified 2857 * as qualifier, and that accepts a single int parameter (size of the array). 2858 */ 2859 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper { 2860 2861 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 2862 List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 2863 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 2864 } 2865 2866 @Override 2867 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2868 Scope sc = new Scope(syms.arrayClass); 2869 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); 2870 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass); 2871 sc.enter(arrayConstr); 2872 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false); 2873 } 2874 2875 @Override 2876 ReferenceKind referenceKind(Symbol sym) { 2877 return ReferenceKind.ARRAY_CTOR; 2878 } 2879 } 2880 2881 /** 2882 * Helper class for constructor reference lookup. The lookup logic is based 2883 * upon either Resolve.findMethod or Resolve.findDiamond - depending on 2884 * whether the constructor reference needs diamond inference (this is the case 2885 * if the qualifier type is raw). A special erroneous symbol is returned 2886 * if the lookup returns the constructor of an inner class and there's no 2887 * enclosing instance in scope. 2888 */ 2889 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper { 2890 2891 boolean needsInference; 2892 2893 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 2894 List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 2895 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 2896 if (site.isRaw()) { 2897 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym); 2898 needsInference = true; 2899 } 2900 } 2901 2902 @Override 2903 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2904 Symbol sym = needsInference ? 2905 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : 2906 findMethod(env, site, name, argtypes, typeargtypes, 2907 phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); 2908 return sym.kind != MTH || 2909 site.getEnclosingType().hasTag(NONE) || 2910 hasEnclosingInstance(env, site) ? 2911 sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) { 2912 @Override 2913 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 2914 return diags.create(dkind, log.currentSource(), pos, 2915 "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); 2916 } 2917 }; 2918 } 2919 2920 @Override 2921 ReferenceKind referenceKind(Symbol sym) { 2922 return site.getEnclosingType().hasTag(NONE) ? 2923 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER; 2924 } 2925 } 2926 2927 /** 2928 * Main overload resolution routine. On each overload resolution step, a 2929 * lookup helper class is used to perform the method/constructor lookup; 2930 * at the end of the lookup, the helper is used to validate the results 2931 * (this last step might trigger overload resolution diagnostics). 2932 */ 2933 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) { 2934 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2935 resolveContext.methodCheck = methodCheck; 2936 return lookupMethod(env, pos, location, resolveContext, lookupHelper); 2937 } 2938 2939 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, 2940 MethodResolutionContext resolveContext, LookupHelper lookupHelper) { 2941 MethodResolutionContext prevResolutionContext = currentResolutionContext; 2942 try { 2943 Symbol bestSoFar = methodNotFound; 2944 currentResolutionContext = resolveContext; 2945 for (MethodResolutionPhase phase : methodResolutionSteps) { 2946 if (!phase.isApplicable(boxingEnabled, varargsEnabled) || 2947 lookupHelper.shouldStop(bestSoFar, phase)) break; 2948 MethodResolutionPhase prevPhase = currentResolutionContext.step; 2949 Symbol prevBest = bestSoFar; 2950 currentResolutionContext.step = phase; 2951 bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase)); 2952 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase; 2953 } 2954 return lookupHelper.access(env, pos, location, bestSoFar); 2955 } finally { 2956 currentResolutionContext = prevResolutionContext; 2957 } 2958 } 2959 2960 /** 2961 * Resolve `c.name' where name == this or name == super. 2962 * @param pos The position to use for error reporting. 2963 * @param env The environment current at the expression. 2964 * @param c The qualifier. 2965 * @param name The identifier's name. 2966 */ 2967 Symbol resolveSelf(DiagnosticPosition pos, 2968 Env<AttrContext> env, 2969 TypeSymbol c, 2970 Name name) { 2971 Env<AttrContext> env1 = env; 2972 boolean staticOnly = false; 2973 while (env1.outer != null) { 2974 if (isStatic(env1)) staticOnly = true; 2975 if (env1.enclClass.sym == c) { 2976 Symbol sym = env1.info.scope.lookup(name).sym; 2977 if (sym != null) { 2978 if (staticOnly) sym = new StaticError(sym); 2979 return accessBase(sym, pos, env.enclClass.sym.type, 2980 name, true); 2981 } 2982 } 2983 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 2984 env1 = env1.outer; 2985 } 2986 if (allowDefaultMethods && c.isInterface() && 2987 name == names._super && !isStatic(env) && 2988 types.isDirectSuperInterface(c, env.enclClass.sym)) { 2989 //this might be a default super call if one of the superinterfaces is 'c' 2990 for (Type t : pruneInterfaces(env.enclClass.type)) { 2991 if (t.tsym == c) { 2992 env.info.defaultSuperCallSite = t; 2993 return new VarSymbol(0, names._super, 2994 types.asSuper(env.enclClass.type, c), env.enclClass.sym); 2995 } 2996 } 2997 //find a direct superinterface that is a subtype of 'c' 2998 for (Type i : types.interfaces(env.enclClass.type)) { 2999 if (i.tsym.isSubClass(c, types) && i.tsym != c) { 3000 log.error(pos, "illegal.default.super.call", c, 3001 diags.fragment("redundant.supertype", c, i)); 3002 return syms.errSymbol; 3003 } 3004 } 3005 Assert.error(); 3006 } 3007 log.error(pos, "not.encl.class", c); 3008 return syms.errSymbol; 3009 } 3010 //where 3011 private List<Type> pruneInterfaces(Type t) { 3012 ListBuffer<Type> result = ListBuffer.lb(); 3013 for (Type t1 : types.interfaces(t)) { 3014 boolean shouldAdd = true; 3015 for (Type t2 : types.interfaces(t)) { 3016 if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) { 3017 shouldAdd = false; 3018 } 3019 } 3020 if (shouldAdd) { 3021 result.append(t1); 3022 } 3023 } 3024 return result.toList(); 3025 } 3026 3027 3028 /** 3029 * Resolve `c.this' for an enclosing class c that contains the 3030 * named member. 3031 * @param pos The position to use for error reporting. 3032 * @param env The environment current at the expression. 3033 * @param member The member that must be contained in the result. 3034 */ 3035 Symbol resolveSelfContaining(DiagnosticPosition pos, 3036 Env<AttrContext> env, 3037 Symbol member, 3038 boolean isSuperCall) { 3039 Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall); 3040 if (sym == null) { 3041 log.error(pos, "encl.class.required", member); 3042 return syms.errSymbol; 3043 } else { 3044 return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true); 3045 } 3046 } 3047 3048 boolean hasEnclosingInstance(Env<AttrContext> env, Type type) { 3049 Symbol encl = resolveSelfContainingInternal(env, type.tsym, false); 3050 return encl != null && encl.kind < ERRONEOUS; 3051 } 3052 3053 private Symbol resolveSelfContainingInternal(Env<AttrContext> env, 3054 Symbol member, 3055 boolean isSuperCall) { 3056 Name name = names._this; 3057 Env<AttrContext> env1 = isSuperCall ? env.outer : env; 3058 boolean staticOnly = false; 3059 if (env1 != null) { 3060 while (env1 != null && env1.outer != null) { 3061 if (isStatic(env1)) staticOnly = true; 3062 if (env1.enclClass.sym.isSubClass(member.owner, types)) { 3063 Symbol sym = env1.info.scope.lookup(name).sym; 3064 if (sym != null) { 3065 if (staticOnly) sym = new StaticError(sym); 3066 return sym; 3067 } 3068 } 3069 if ((env1.enclClass.sym.flags() & STATIC) != 0) 3070 staticOnly = true; 3071 env1 = env1.outer; 3072 } 3073 } 3074 return null; 3075 } 3076 3077 /** 3078 * Resolve an appropriate implicit this instance for t's container. 3079 * JLS 8.8.5.1 and 15.9.2 3080 */ 3081 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) { 3082 return resolveImplicitThis(pos, env, t, false); 3083 } 3084 3085 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) { 3086 Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0) 3087 ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) 3088 : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; 3089 if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) 3090 log.error(pos, "cant.ref.before.ctor.called", "this"); 3091 return thisType; 3092 } 3093 3094 /* *************************************************************************** 3095 * ResolveError classes, indicating error situations when accessing symbols 3096 ****************************************************************************/ 3097 3098 //used by TransTypes when checking target type of synthetic cast 3099 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) { 3100 AccessError error = new AccessError(env, env.enclClass.type, type.tsym); 3101 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null); 3102 } 3103 //where 3104 private void logResolveError(ResolveError error, 3105 DiagnosticPosition pos, 3106 Symbol location, 3107 Type site, 3108 Name name, 3109 List<Type> argtypes, 3110 List<Type> typeargtypes) { 3111 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 3112 pos, location, site, name, argtypes, typeargtypes); 3113 if (d != null) { 3114 d.setFlag(DiagnosticFlag.RESOLVE_ERROR); 3115 log.report(d); 3116 } 3117 } 3118 3119 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); 3120 3121 public Object methodArguments(List<Type> argtypes) { 3122 if (argtypes == null || argtypes.isEmpty()) { 3123 return noArgs; 3124 } else { 3125 ListBuffer<Object> diagArgs = ListBuffer.lb(); 3126 for (Type t : argtypes) { 3127 if (t.hasTag(DEFERRED)) { 3128 diagArgs.append(((DeferredAttr.DeferredType)t).tree); 3129 } else { 3130 diagArgs.append(t); 3131 } 3132 } 3133 return diagArgs; 3134 } 3135 } 3136 3137 /** 3138 * Root class for resolution errors. Subclass of ResolveError 3139 * represent a different kinds of resolution error - as such they must 3140 * specify how they map into concrete compiler diagnostics. 3141 */ 3142 abstract class ResolveError extends Symbol { 3143 3144 /** The name of the kind of error, for debugging only. */ 3145 final String debugName; 3146 3147 ResolveError(int kind, String debugName) { 3148 super(kind, 0, null, null, null); 3149 this.debugName = debugName; 3150 } 3151 3152 @Override 3153 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 3154 throw new AssertionError(); 3155 } 3156 3157 @Override 3158 public String toString() { 3159 return debugName; 3160 } 3161 3162 @Override 3163 public boolean exists() { 3164 return false; 3165 } 3166 3167 /** 3168 * Create an external representation for this erroneous symbol to be 3169 * used during attribution - by default this returns the symbol of a 3170 * brand new error type which stores the original type found 3171 * during resolution. 3172 * 3173 * @param name the name used during resolution 3174 * @param location the location from which the symbol is accessed 3175 */ 3176 protected Symbol access(Name name, TypeSymbol location) { 3177 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 3178 } 3179 3180 /** 3181 * Create a diagnostic representing this resolution error. 3182 * 3183 * @param dkind The kind of the diagnostic to be created (e.g error). 3184 * @param pos The position to be used for error reporting. 3185 * @param site The original type from where the selection took place. 3186 * @param name The name of the symbol to be resolved. 3187 * @param argtypes The invocation's value arguments, 3188 * if we looked for a method. 3189 * @param typeargtypes The invocation's type arguments, 3190 * if we looked for a method. 3191 */ 3192 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3193 DiagnosticPosition pos, 3194 Symbol location, 3195 Type site, 3196 Name name, 3197 List<Type> argtypes, 3198 List<Type> typeargtypes); 3199 } 3200 3201 /** 3202 * This class is the root class of all resolution errors caused by 3203 * an invalid symbol being found during resolution. 3204 */ 3205 abstract class InvalidSymbolError extends ResolveError { 3206 3207 /** The invalid symbol found during resolution */ 3208 Symbol sym; 3209 3210 InvalidSymbolError(int kind, Symbol sym, String debugName) { 3211 super(kind, debugName); 3212 this.sym = sym; 3213 } 3214 3215 @Override 3216 public boolean exists() { 3217 return true; 3218 } 3219 3220 @Override 3221 public String toString() { 3222 return super.toString() + " wrongSym=" + sym; 3223 } 3224 3225 @Override 3226 public Symbol access(Name name, TypeSymbol location) { 3227 if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0) 3228 return types.createErrorType(name, location, sym.type).tsym; 3229 else 3230 return sym; 3231 } 3232 } 3233 3234 /** 3235 * InvalidSymbolError error class indicating that a symbol matching a 3236 * given name does not exists in a given site. 3237 */ 3238 class SymbolNotFoundError extends ResolveError { 3239 3240 SymbolNotFoundError(int kind) { 3241 super(kind, "symbol not found error"); 3242 } 3243 3244 @Override 3245 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3246 DiagnosticPosition pos, 3247 Symbol location, 3248 Type site, 3249 Name name, 3250 List<Type> argtypes, 3251 List<Type> typeargtypes) { 3252 argtypes = argtypes == null ? List.<Type>nil() : argtypes; 3253 typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes; 3254 if (name == names.error) 3255 return null; 3256 3257 if (syms.operatorNames.contains(name)) { 3258 boolean isUnaryOp = argtypes.size() == 1; 3259 String key = argtypes.size() == 1 ? 3260 "operator.cant.be.applied" : 3261 "operator.cant.be.applied.1"; 3262 Type first = argtypes.head; 3263 Type second = !isUnaryOp ? argtypes.tail.head : null; 3264 return diags.create(dkind, log.currentSource(), pos, 3265 key, name, first, second); 3266 } 3267 boolean hasLocation = false; 3268 if (location == null) { 3269 location = site.tsym; 3270 } 3271 if (!location.name.isEmpty()) { 3272 if (location.kind == PCK && !site.tsym.exists()) { 3273 return diags.create(dkind, log.currentSource(), pos, 3274 "doesnt.exist", location); 3275 } 3276 hasLocation = !location.name.equals(names._this) && 3277 !location.name.equals(names._super); 3278 } 3279 boolean isConstructor = kind == ABSENT_MTH && name == names.init; 3280 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind); 3281 Name idname = isConstructor ? site.tsym.name : name; 3282 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); 3283 if (hasLocation) { 3284 return diags.create(dkind, log.currentSource(), pos, 3285 errKey, kindname, idname, //symbol kindname, name 3286 typeargtypes, args(argtypes), //type parameters and arguments (if any) 3287 getLocationDiag(location, site)); //location kindname, type 3288 } 3289 else { 3290 return diags.create(dkind, log.currentSource(), pos, 3291 errKey, kindname, idname, //symbol kindname, name 3292 typeargtypes, args(argtypes)); //type parameters and arguments (if any) 3293 } 3294 } 3295 //where 3296 private Object args(List<Type> args) { 3297 return args.isEmpty() ? args : methodArguments(args); 3298 } 3299 3300 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) { 3301 String key = "cant.resolve"; 3302 String suffix = hasLocation ? ".location" : ""; 3303 switch (kindname) { 3304 case METHOD: 3305 case CONSTRUCTOR: { 3306 suffix += ".args"; 3307 suffix += hasTypeArgs ? ".params" : ""; 3308 } 3309 } 3310 return key + suffix; 3311 } 3312 private JCDiagnostic getLocationDiag(Symbol location, Type site) { 3313 if (location.kind == VAR) { 3314 return diags.fragment("location.1", 3315 kindName(location), 3316 location, 3317 location.type); 3318 } else { 3319 return diags.fragment("location", 3320 typeKindName(site), 3321 site, 3322 null); 3323 } 3324 } 3325 } 3326 3327 /** 3328 * InvalidSymbolError error class indicating that a given symbol 3329 * (either a method, a constructor or an operand) is not applicable 3330 * given an actual arguments/type argument list. 3331 */ 3332 class InapplicableSymbolError extends ResolveError { 3333 3334 protected MethodResolutionContext resolveContext; 3335 3336 InapplicableSymbolError(MethodResolutionContext context) { 3337 this(WRONG_MTH, "inapplicable symbol error", context); 3338 } 3339 3340 protected InapplicableSymbolError(int kind, String debugName, MethodResolutionContext context) { 3341 super(kind, debugName); 3342 this.resolveContext = context; 3343 } 3344 3345 @Override 3346 public String toString() { 3347 return super.toString(); 3348 } 3349 3350 @Override 3351 public boolean exists() { 3352 return true; 3353 } 3354 3355 @Override 3356 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3357 DiagnosticPosition pos, 3358 Symbol location, 3359 Type site, 3360 Name name, 3361 List<Type> argtypes, 3362 List<Type> typeargtypes) { 3363 if (name == names.error) 3364 return null; 3365 3366 if (syms.operatorNames.contains(name)) { 3367 boolean isUnaryOp = argtypes.size() == 1; 3368 String key = argtypes.size() == 1 ? 3369 "operator.cant.be.applied" : 3370 "operator.cant.be.applied.1"; 3371 Type first = argtypes.head; 3372 Type second = !isUnaryOp ? argtypes.tail.head : null; 3373 return diags.create(dkind, log.currentSource(), pos, 3374 key, name, first, second); 3375 } 3376 else { 3377 Candidate c = errCandidate(); 3378 Symbol ws = c.sym.asMemberOf(site, types); 3379 return diags.create(dkind, log.currentSource(), pos, 3380 "cant.apply.symbol", 3381 kindName(ws), 3382 ws.name == names.init ? ws.owner.name : ws.name, 3383 methodArguments(ws.type.getParameterTypes()), 3384 methodArguments(argtypes), 3385 kindName(ws.owner), 3386 ws.owner.type, 3387 c.details); 3388 } 3389 } 3390 3391 @Override 3392 public Symbol access(Name name, TypeSymbol location) { 3393 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 3394 } 3395 3396 private Candidate errCandidate() { 3397 Candidate bestSoFar = null; 3398 for (Candidate c : resolveContext.candidates) { 3399 if (c.isApplicable()) continue; 3400 bestSoFar = c; 3401 } 3402 Assert.checkNonNull(bestSoFar); 3403 return bestSoFar; 3404 } 3405 } 3406 3407 /** 3408 * ResolveError error class indicating that a set of symbols 3409 * (either methods, constructors or operands) is not applicable 3410 * given an actual arguments/type argument list. 3411 */ 3412 class InapplicableSymbolsError extends InapplicableSymbolError { 3413 3414 InapplicableSymbolsError(MethodResolutionContext context) { 3415 super(WRONG_MTHS, "inapplicable symbols", context); 3416 } 3417 3418 @Override 3419 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3420 DiagnosticPosition pos, 3421 Symbol location, 3422 Type site, 3423 Name name, 3424 List<Type> argtypes, 3425 List<Type> typeargtypes) { 3426 if (!resolveContext.candidates.isEmpty()) { 3427 JCDiagnostic err = diags.create(dkind, 3428 log.currentSource(), 3429 pos, 3430 "cant.apply.symbols", 3431 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), 3432 name == names.init ? site.tsym.name : name, 3433 methodArguments(argtypes)); 3434 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); 3435 } else { 3436 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, 3437 location, site, name, argtypes, typeargtypes); 3438 } 3439 } 3440 3441 //where 3442 List<JCDiagnostic> candidateDetails(Type site) { 3443 Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>(); 3444 for (Candidate c : resolveContext.candidates) { 3445 if (c.isApplicable()) continue; 3446 JCDiagnostic detailDiag = diags.fragment("inapplicable.method", 3447 Kinds.kindName(c.sym), 3448 c.sym.location(site, types), 3449 c.sym.asMemberOf(site, types), 3450 c.details); 3451 details.put(c.sym, detailDiag); 3452 } 3453 return List.from(details.values()); 3454 } 3455 } 3456 3457 /** 3458 * An InvalidSymbolError error class indicating that a symbol is not 3459 * accessible from a given site 3460 */ 3461 class AccessError extends InvalidSymbolError { 3462 3463 private Env<AttrContext> env; 3464 private Type site; 3465 3466 AccessError(Symbol sym) { 3467 this(null, null, sym); 3468 } 3469 3470 AccessError(Env<AttrContext> env, Type site, Symbol sym) { 3471 super(HIDDEN, sym, "access error"); 3472 this.env = env; 3473 this.site = site; 3474 if (debugResolve) 3475 log.error("proc.messager", sym + " @ " + site + " is inaccessible."); 3476 } 3477 3478 @Override 3479 public boolean exists() { 3480 return false; 3481 } 3482 3483 @Override 3484 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3485 DiagnosticPosition pos, 3486 Symbol location, 3487 Type site, 3488 Name name, 3489 List<Type> argtypes, 3490 List<Type> typeargtypes) { 3491 if (sym.owner.type.hasTag(ERROR)) 3492 return null; 3493 3494 if (sym.name == names.init && sym.owner != site.tsym) { 3495 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, 3496 pos, location, site, name, argtypes, typeargtypes); 3497 } 3498 else if ((sym.flags() & PUBLIC) != 0 3499 || (env != null && this.site != null 3500 && !isAccessible(env, this.site))) { 3501 return diags.create(dkind, log.currentSource(), 3502 pos, "not.def.access.class.intf.cant.access", 3503 sym, sym.location()); 3504 } 3505 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { 3506 return diags.create(dkind, log.currentSource(), 3507 pos, "report.access", sym, 3508 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 3509 sym.location()); 3510 } 3511 else { 3512 return diags.create(dkind, log.currentSource(), 3513 pos, "not.def.public.cant.access", sym, sym.location()); 3514 } 3515 } 3516 } 3517 3518 /** 3519 * InvalidSymbolError error class indicating that an instance member 3520 * has erroneously been accessed from a static context. 3521 */ 3522 class StaticError extends InvalidSymbolError { 3523 3524 StaticError(Symbol sym) { 3525 super(STATICERR, sym, "static error"); 3526 } 3527 3528 @Override 3529 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3530 DiagnosticPosition pos, 3531 Symbol location, 3532 Type site, 3533 Name name, 3534 List<Type> argtypes, 3535 List<Type> typeargtypes) { 3536 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS)) 3537 ? types.erasure(sym.type).tsym 3538 : sym); 3539 return diags.create(dkind, log.currentSource(), pos, 3540 "non-static.cant.be.ref", kindName(sym), errSym); 3541 } 3542 } 3543 3544 /** 3545 * InvalidSymbolError error class indicating that a pair of symbols 3546 * (either methods, constructors or operands) are ambiguous 3547 * given an actual arguments/type argument list. 3548 */ 3549 class AmbiguityError extends ResolveError { 3550 3551 /** The other maximally specific symbol */ 3552 List<Symbol> ambiguousSyms = List.nil(); 3553 3554 @Override 3555 public boolean exists() { 3556 return true; 3557 } 3558 3559 AmbiguityError(Symbol sym1, Symbol sym2) { 3560 super(AMBIGUOUS, "ambiguity error"); 3561 ambiguousSyms = flatten(sym2).appendList(flatten(sym1)); 3562 } 3563 3564 private List<Symbol> flatten(Symbol sym) { 3565 if (sym.kind == AMBIGUOUS) { 3566 return ((AmbiguityError)sym).ambiguousSyms; 3567 } else { 3568 return List.of(sym); 3569 } 3570 } 3571 3572 AmbiguityError addAmbiguousSymbol(Symbol s) { 3573 ambiguousSyms = ambiguousSyms.prepend(s); 3574 return this; 3575 } 3576 3577 @Override 3578 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3579 DiagnosticPosition pos, 3580 Symbol location, 3581 Type site, 3582 Name name, 3583 List<Type> argtypes, 3584 List<Type> typeargtypes) { 3585 List<Symbol> diagSyms = ambiguousSyms.reverse(); 3586 Symbol s1 = diagSyms.head; 3587 Symbol s2 = diagSyms.tail.head; 3588 Name sname = s1.name; 3589 if (sname == names.init) sname = s1.owner.name; 3590 return diags.create(dkind, log.currentSource(), 3591 pos, "ref.ambiguous", sname, 3592 kindName(s1), 3593 s1, 3594 s1.location(site, types), 3595 kindName(s2), 3596 s2, 3597 s2.location(site, types)); 3598 } 3599 3600 /** 3601 * If multiple applicable methods are found during overload and none of them 3602 * is more specific than the others, attempt to merge their signatures. 3603 */ 3604 Symbol mergeAbstracts(Type site) { 3605 Symbol fst = ambiguousSyms.last(); 3606 Symbol res = fst; 3607 for (Symbol s : ambiguousSyms.reverse()) { 3608 Type mt1 = types.memberType(site, res); 3609 Type mt2 = types.memberType(site, s); 3610 if ((s.flags() & ABSTRACT) == 0 || 3611 !types.overrideEquivalent(mt1, mt2) || 3612 !types.isSameTypes(fst.erasure(types).getParameterTypes(), 3613 s.erasure(types).getParameterTypes())) { 3614 //ambiguity cannot be resolved 3615 return this; 3616 } else { 3617 Type mst = mostSpecificReturnType(mt1, mt2); 3618 if (mst == null) { 3619 // Theoretically, this can't happen, but it is possible 3620 // due to error recovery or mixing incompatible class files 3621 return this; 3622 } 3623 Symbol mostSpecific = mst == mt1 ? res : s; 3624 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); 3625 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); 3626 res = new MethodSymbol( 3627 mostSpecific.flags(), 3628 mostSpecific.name, 3629 newSig, 3630 mostSpecific.owner); 3631 } 3632 } 3633 return res; 3634 } 3635 3636 @Override 3637 protected Symbol access(Name name, TypeSymbol location) { 3638 Symbol firstAmbiguity = ambiguousSyms.last(); 3639 return firstAmbiguity.kind == TYP ? 3640 types.createErrorType(name, location, firstAmbiguity.type).tsym : 3641 firstAmbiguity; 3642 } 3643 } 3644 3645 class BadVarargsMethod extends ResolveError { 3646 3647 ResolveError delegatedError; 3648 3649 BadVarargsMethod(ResolveError delegatedError) { 3650 super(delegatedError.kind, "badVarargs"); 3651 this.delegatedError = delegatedError; 3652 } 3653 3654 @Override 3655 public Symbol baseSymbol() { 3656 return delegatedError.baseSymbol(); 3657 } 3658 3659 @Override 3660 protected Symbol access(Name name, TypeSymbol location) { 3661 return delegatedError.access(name, location); 3662 } 3663 3664 @Override 3665 public boolean exists() { 3666 return true; 3667 } 3668 3669 @Override 3670 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 3671 return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes); 3672 } 3673 } 3674 3675 enum MethodResolutionPhase { 3676 BASIC(false, false), 3677 BOX(true, false), 3678 VARARITY(true, true) { 3679 @Override 3680 public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { 3681 switch (sym.kind) { 3682 case WRONG_MTH: 3683 return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ? 3684 bestSoFar : 3685 sym; 3686 case ABSENT_MTH: 3687 return bestSoFar; 3688 default: 3689 return sym; 3690 } 3691 } 3692 }; 3693 3694 final boolean isBoxingRequired; 3695 final boolean isVarargsRequired; 3696 3697 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { 3698 this.isBoxingRequired = isBoxingRequired; 3699 this.isVarargsRequired = isVarargsRequired; 3700 } 3701 3702 public boolean isBoxingRequired() { 3703 return isBoxingRequired; 3704 } 3705 3706 public boolean isVarargsRequired() { 3707 return isVarargsRequired; 3708 } 3709 3710 public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) { 3711 return (varargsEnabled || !isVarargsRequired) && 3712 (boxingEnabled || !isBoxingRequired); 3713 } 3714 3715 public Symbol mergeResults(Symbol prev, Symbol sym) { 3716 return sym; 3717 } 3718 } 3719 3720 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); 3721 3722 /** 3723 * A resolution context is used to keep track of intermediate results of 3724 * overload resolution, such as list of method that are not applicable 3725 * (used to generate more precise diagnostics) and so on. Resolution contexts 3726 * can be nested - this means that when each overload resolution routine should 3727 * work within the resolution context it created. 3728 */ 3729 class MethodResolutionContext { 3730 3731 private List<Candidate> candidates = List.nil(); 3732 3733 MethodResolutionPhase step = null; 3734 3735 MethodCheck methodCheck = resolveMethodCheck; 3736 3737 private boolean internalResolution = false; 3738 private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE; 3739 3740 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { 3741 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); 3742 candidates = candidates.append(c); 3743 } 3744 3745 void addApplicableCandidate(Symbol sym, Type mtype) { 3746 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype); 3747 candidates = candidates.append(c); 3748 } 3749 3750 DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) { 3751 return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn); 3752 } 3753 3754 /** 3755 * This class represents an overload resolution candidate. There are two 3756 * kinds of candidates: applicable methods and inapplicable methods; 3757 * applicable methods have a pointer to the instantiated method type, 3758 * while inapplicable candidates contain further details about the 3759 * reason why the method has been considered inapplicable. 3760 */ 3761 @SuppressWarnings("overrides") 3762 class Candidate { 3763 3764 final MethodResolutionPhase step; 3765 final Symbol sym; 3766 final JCDiagnostic details; 3767 final Type mtype; 3768 3769 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) { 3770 this.step = step; 3771 this.sym = sym; 3772 this.details = details; 3773 this.mtype = mtype; 3774 } 3775 3776 @Override 3777 public boolean equals(Object o) { 3778 if (o instanceof Candidate) { 3779 Symbol s1 = this.sym; 3780 Symbol s2 = ((Candidate)o).sym; 3781 if ((s1 != s2 && 3782 (s1.overrides(s2, s1.owner.type.tsym, types, false) || 3783 (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || 3784 ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) 3785 return true; 3786 } 3787 return false; 3788 } 3789 3790 boolean isApplicable() { 3791 return mtype != null; 3792 } 3793 } 3794 3795 DeferredAttr.AttrMode attrMode() { 3796 return attrMode; 3797 } 3798 3799 boolean internal() { 3800 return internalResolution; 3801 } 3802 } 3803 3804 MethodResolutionContext currentResolutionContext = null; 3805 }