1 /* 2 * Copyright (c) 1999, 2012, 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.Type.*; 31 import com.sun.tools.javac.code.Symbol.*; 32 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; 33 import com.sun.tools.javac.jvm.*; 34 import com.sun.tools.javac.tree.*; 35 import com.sun.tools.javac.tree.JCTree.*; 36 import com.sun.tools.javac.util.*; 37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 38 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 39 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 40 41 import java.util.Arrays; 42 import java.util.Collection; 43 import java.util.EnumMap; 44 import java.util.EnumSet; 45 import java.util.HashSet; 46 import java.util.Map; 47 import java.util.Set; 48 49 import javax.lang.model.element.ElementVisitor; 50 51 import static com.sun.tools.javac.code.Flags.*; 52 import static com.sun.tools.javac.code.Flags.BLOCK; 53 import static com.sun.tools.javac.code.Kinds.*; 54 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; 55 import static com.sun.tools.javac.code.TypeTags.*; 56 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; 57 import static com.sun.tools.javac.tree.JCTree.Tag.*; 58 59 /** Helper class for name resolution, used mostly by the attribution phase. 60 * 61 * <p><b>This is NOT part of any supported API. 62 * If you write code that depends on this, you do so at your own risk. 63 * This code and its internal interfaces are subject to change or 64 * deletion without notice.</b> 65 */ 66 public class Resolve { 67 protected static final Context.Key<Resolve> resolveKey = 68 new Context.Key<Resolve>(); 69 70 Names names; 71 Log log; 72 Symtab syms; 73 Check chk; 74 Infer infer; 75 ClassReader reader; 76 TreeInfo treeinfo; 77 Types types; 78 JCDiagnostic.Factory diags; 79 public final boolean boxingEnabled; // = source.allowBoxing(); 80 public final boolean varargsEnabled; // = source.allowVarargs(); 81 public final boolean allowMethodHandles; 82 private final boolean debugResolve; 83 final EnumSet<VerboseResolutionMode> verboseResolutionMode; 84 85 Scope polymorphicSignatureScope; 86 87 protected Resolve(Context context) { 88 context.put(resolveKey, this); 89 syms = Symtab.instance(context); 90 91 varNotFound = new 92 SymbolNotFoundError(ABSENT_VAR); 93 wrongMethod = new 94 InapplicableSymbolError(); 95 wrongMethods = new 96 InapplicableSymbolsError(); 97 methodNotFound = new 98 SymbolNotFoundError(ABSENT_MTH); 99 typeNotFound = new 100 SymbolNotFoundError(ABSENT_TYP); 101 102 names = Names.instance(context); 103 log = Log.instance(context); 104 chk = Check.instance(context); 105 infer = Infer.instance(context); 106 reader = ClassReader.instance(context); 107 treeinfo = TreeInfo.instance(context); 108 types = Types.instance(context); 109 diags = JCDiagnostic.Factory.instance(context); 110 Source source = Source.instance(context); 111 boxingEnabled = source.allowBoxing(); 112 varargsEnabled = source.allowVarargs(); 113 Options options = Options.instance(context); 114 debugResolve = options.isSet("debugresolve"); 115 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); 116 Target target = Target.instance(context); 117 allowMethodHandles = target.hasMethodHandles(); 118 polymorphicSignatureScope = new Scope(syms.noSymbol); 119 120 inapplicableMethodException = new InapplicableMethodException(diags); 121 } 122 123 /** error symbols, which are returned when resolution fails 124 */ 125 private final SymbolNotFoundError varNotFound; 126 private final InapplicableSymbolError wrongMethod; 127 private final InapplicableSymbolsError wrongMethods; 128 private final SymbolNotFoundError methodNotFound; 129 private final SymbolNotFoundError typeNotFound; 130 131 public static Resolve instance(Context context) { 132 Resolve instance = context.get(resolveKey); 133 if (instance == null) 134 instance = new Resolve(context); 135 return instance; 136 } 137 138 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support"> 139 enum VerboseResolutionMode { 140 SUCCESS("success"), 141 FAILURE("failure"), 142 APPLICABLE("applicable"), 143 INAPPLICABLE("inapplicable"), 144 DEFERRED_INST("deferred-inference"), 145 PREDEF("predef"), 146 OBJECT_INIT("object-init"), 147 INTERNAL("internal"); 148 149 String opt; 150 151 private VerboseResolutionMode(String opt) { 152 this.opt = opt; 153 } 154 155 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) { 156 String s = opts.get("verboseResolution"); 157 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class); 158 if (s == null) return res; 159 if (s.contains("all")) { 160 res = EnumSet.allOf(VerboseResolutionMode.class); 161 } 162 Collection<String> args = Arrays.asList(s.split(",")); 163 for (VerboseResolutionMode mode : values()) { 164 if (args.contains(mode.opt)) { 165 res.add(mode); 166 } else if (args.contains("-" + mode.opt)) { 167 res.remove(mode); 168 } 169 } 170 return res; 171 } 172 } 173 174 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, 175 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) { 176 boolean success = bestSoFar.kind < ERRONEOUS; 177 178 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { 179 return; 180 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { 181 return; 182 } 183 184 if (bestSoFar.name == names.init && 185 bestSoFar.owner == syms.objectType.tsym && 186 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { 187 return; //skip diags for Object constructor resolution 188 } else if (site == syms.predefClass.type && 189 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { 190 return; //skip spurious diags for predef symbols (i.e. operators) 191 } else if (currentResolutionContext.internalResolution && 192 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { 193 return; 194 } 195 196 int pos = 0; 197 int mostSpecificPos = -1; 198 ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb(); 199 for (Candidate c : currentResolutionContext.candidates) { 200 if (currentResolutionContext.step != c.step || 201 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || 202 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) { 203 continue; 204 } else { 205 subDiags.append(c.isApplicable() ? 206 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) : 207 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details)); 208 if (c.sym == bestSoFar) 209 mostSpecificPos = pos; 210 pos++; 211 } 212 } 213 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; 214 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, 215 site.tsym, mostSpecificPos, currentResolutionContext.step, 216 methodArguments(argtypes), methodArguments(typeargtypes)); 217 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); 218 log.report(d); 219 } 220 221 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) { 222 JCDiagnostic subDiag = null; 223 if (inst.getReturnType().tag == FORALL) { 224 Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(), 225 ((ForAll)inst.getReturnType()).qtype); 226 subDiag = diags.fragment("partial.inst.sig", diagType); 227 } else if (sym.type.tag == FORALL) { 228 subDiag = diags.fragment("full.inst.sig", inst.asMethodType()); 229 } 230 231 String key = subDiag == null ? 232 "applicable.method.found" : 233 "applicable.method.found.1"; 234 235 return diags.fragment(key, pos, sym, subDiag); 236 } 237 238 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) { 239 return diags.fragment("not.applicable.method.found", pos, sym, subDiag); 240 } 241 // </editor-fold> 242 243 /* ************************************************************************ 244 * Identifier resolution 245 *************************************************************************/ 246 247 /** An environment is "static" if its static level is greater than 248 * the one of its outer environment 249 */ 250 static boolean isStatic(Env<AttrContext> env) { 251 return env.info.staticLevel > env.outer.info.staticLevel; 252 } 253 254 /** An environment is an "initializer" if it is a constructor or 255 * an instance initializer. 256 */ 257 static boolean isInitializer(Env<AttrContext> env) { 258 Symbol owner = env.info.scope.owner; 259 return owner.isConstructor() || 260 owner.owner.kind == TYP && 261 (owner.kind == VAR || 262 owner.kind == MTH && (owner.flags() & BLOCK) != 0) && 263 (owner.flags() & STATIC) == 0; 264 } 265 266 /** Is class accessible in given evironment? 267 * @param env The current environment. 268 * @param c The class whose accessibility is checked. 269 */ 270 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) { 271 return isAccessible(env, c, false); 272 } 273 274 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) { 275 boolean isAccessible = false; 276 switch ((short)(c.flags() & AccessFlags)) { 277 case PRIVATE: 278 isAccessible = 279 env.enclClass.sym.outermostClass() == 280 c.owner.outermostClass(); 281 break; 282 case 0: 283 isAccessible = 284 env.toplevel.packge == c.owner // fast special case 285 || 286 env.toplevel.packge == c.packge() 287 || 288 // Hack: this case is added since synthesized default constructors 289 // of anonymous classes should be allowed to access 290 // classes which would be inaccessible otherwise. 291 env.enclMethod != null && 292 (env.enclMethod.mods.flags & ANONCONSTR) != 0; 293 break; 294 default: // error recovery 295 case PUBLIC: 296 isAccessible = true; 297 break; 298 case PROTECTED: 299 isAccessible = 300 env.toplevel.packge == c.owner // fast special case 301 || 302 env.toplevel.packge == c.packge() 303 || 304 isInnerSubClass(env.enclClass.sym, c.owner); 305 break; 306 } 307 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ? 308 isAccessible : 309 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner); 310 } 311 //where 312 /** Is given class a subclass of given base class, or an inner class 313 * of a subclass? 314 * Return null if no such class exists. 315 * @param c The class which is the subclass or is contained in it. 316 * @param base The base class 317 */ 318 private boolean isInnerSubClass(ClassSymbol c, Symbol base) { 319 while (c != null && !c.isSubClass(base, types)) { 320 c = c.owner.enclClass(); 321 } 322 return c != null; 323 } 324 325 boolean isAccessible(Env<AttrContext> env, Type t) { 326 return isAccessible(env, t, false); 327 } 328 329 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { 330 return (t.tag == ARRAY) 331 ? isAccessible(env, types.elemtype(t)) 332 : isAccessible(env, t.tsym, checkInner); 333 } 334 335 /** Is symbol accessible as a member of given type in given evironment? 336 * @param env The current environment. 337 * @param site The type of which the tested symbol is regarded 338 * as a member. 339 * @param sym The symbol. 340 */ 341 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) { 342 return isAccessible(env, site, sym, false); 343 } 344 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) { 345 if (sym.name == names.init && sym.owner != site.tsym) return false; 346 switch ((short)(sym.flags() & AccessFlags)) { 347 case PRIVATE: 348 return 349 (env.enclClass.sym == sym.owner // fast special case 350 || 351 env.enclClass.sym.outermostClass() == 352 sym.owner.outermostClass()) 353 && 354 sym.isInheritedIn(site.tsym, types); 355 case 0: 356 return 357 (env.toplevel.packge == sym.owner.owner // fast special case 358 || 359 env.toplevel.packge == sym.packge()) 360 && 361 isAccessible(env, site, checkInner) 362 && 363 sym.isInheritedIn(site.tsym, types) 364 && 365 notOverriddenIn(site, sym); 366 case PROTECTED: 367 return 368 (env.toplevel.packge == sym.owner.owner // fast special case 369 || 370 env.toplevel.packge == sym.packge() 371 || 372 isProtectedAccessible(sym, env.enclClass.sym, site) 373 || 374 // OK to select instance method or field from 'super' or type name 375 // (but type names should be disallowed elsewhere!) 376 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) 377 && 378 isAccessible(env, site, checkInner) 379 && 380 notOverriddenIn(site, sym); 381 default: // this case includes erroneous combinations as well 382 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym); 383 } 384 } 385 //where 386 /* `sym' is accessible only if not overridden by 387 * another symbol which is a member of `site' 388 * (because, if it is overridden, `sym' is not strictly 389 * speaking a member of `site'). A polymorphic signature method 390 * cannot be overridden (e.g. MH.invokeExact(Object[])). 391 */ 392 private boolean notOverriddenIn(Type site, Symbol sym) { 393 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) 394 return true; 395 else { 396 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 397 return (s2 == null || s2 == sym || sym.owner == s2.owner || 398 s2.isPolymorphicSignatureGeneric() || 399 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); 400 } 401 } 402 //where 403 /** Is given protected symbol accessible if it is selected from given site 404 * and the selection takes place in given class? 405 * @param sym The symbol with protected access 406 * @param c The class where the access takes place 407 * @site The type of the qualifier 408 */ 409 private 410 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { 411 while (c != null && 412 !(c.isSubClass(sym.owner, types) && 413 (c.flags() & INTERFACE) == 0 && 414 // In JLS 2e 6.6.2.1, the subclass restriction applies 415 // only to instance fields and methods -- types are excluded 416 // regardless of whether they are declared 'static' or not. 417 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) 418 c = c.owner.enclClass(); 419 return c != null; 420 } 421 422 /** Try to instantiate the type of a method so that it fits 423 * given type arguments and argument types. If succesful, return 424 * the method's instantiated type, else return null. 425 * The instantiation will take into account an additional leading 426 * formal parameter if the method is an instance method seen as a member 427 * of un underdetermined site In this case, we treat site as an additional 428 * parameter and the parameters of the class containing the method as 429 * additional type variables that get instantiated. 430 * 431 * @param env The current environment 432 * @param site The type of which the method is a member. 433 * @param m The method symbol. 434 * @param argtypes The invocation's given value arguments. 435 * @param typeargtypes The invocation's given type arguments. 436 * @param allowBoxing Allow boxing conversions of arguments. 437 * @param useVarargs Box trailing arguments into an array for varargs. 438 */ 439 Type rawInstantiate(Env<AttrContext> env, 440 Type site, 441 Symbol m, 442 List<Type> argtypes, 443 List<Type> typeargtypes, 444 boolean allowBoxing, 445 boolean useVarargs, 446 Warner warn) 447 throws Infer.InferenceException { 448 boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles; 449 if (useVarargs && (m.flags() & VARARGS) == 0) 450 throw inapplicableMethodException.setMessage(); 451 Type mt = types.memberType(site, m); 452 453 // tvars is the list of formal type variables for which type arguments 454 // need to inferred. 455 List<Type> tvars = null; 456 if (env.info.tvars != null) { 457 tvars = types.newInstances(env.info.tvars); 458 mt = types.subst(mt, env.info.tvars, tvars); 459 } 460 if (typeargtypes == null) typeargtypes = List.nil(); 461 if (mt.tag != FORALL && typeargtypes.nonEmpty()) { 462 // This is not a polymorphic method, but typeargs are supplied 463 // which is fine, see JLS 15.12.2.1 464 } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) { 465 ForAll pmt = (ForAll) mt; 466 if (typeargtypes.length() != pmt.tvars.length()) 467 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args 468 // Check type arguments are within bounds 469 List<Type> formals = pmt.tvars; 470 List<Type> actuals = typeargtypes; 471 while (formals.nonEmpty() && actuals.nonEmpty()) { 472 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head), 473 pmt.tvars, typeargtypes); 474 for (; bounds.nonEmpty(); bounds = bounds.tail) 475 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) 476 throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds); 477 formals = formals.tail; 478 actuals = actuals.tail; 479 } 480 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes); 481 } else if (mt.tag == FORALL) { 482 ForAll pmt = (ForAll) mt; 483 List<Type> tvars1 = types.newInstances(pmt.tvars); 484 tvars = tvars.appendList(tvars1); 485 mt = types.subst(pmt.qtype, pmt.tvars, tvars1); 486 } 487 488 // find out whether we need to go the slow route via infer 489 boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/ 490 polymorphicSignature; 491 for (List<Type> l = argtypes; 492 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded; 493 l = l.tail) { 494 if (l.head.tag == FORALL) instNeeded = true; 495 } 496 497 if (instNeeded) 498 return polymorphicSignature ? 499 infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) : 500 infer.instantiateMethod(env, 501 tvars, 502 (MethodType)mt, 503 m, 504 argtypes, 505 allowBoxing, 506 useVarargs, 507 warn); 508 509 checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(), 510 allowBoxing, useVarargs, warn); 511 return mt; 512 } 513 514 /** Same but returns null instead throwing a NoInstanceException 515 */ 516 Type instantiate(Env<AttrContext> env, 517 Type site, 518 Symbol m, 519 List<Type> argtypes, 520 List<Type> typeargtypes, 521 boolean allowBoxing, 522 boolean useVarargs, 523 Warner warn) { 524 try { 525 return rawInstantiate(env, site, m, argtypes, typeargtypes, 526 allowBoxing, useVarargs, warn); 527 } catch (InapplicableMethodException ex) { 528 return null; 529 } 530 } 531 532 /** Check if a parameter list accepts a list of args. 533 */ 534 boolean argumentsAcceptable(Env<AttrContext> env, 535 List<Type> argtypes, 536 List<Type> formals, 537 boolean allowBoxing, 538 boolean useVarargs, 539 Warner warn) { 540 try { 541 checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn); 542 return true; 543 } catch (InapplicableMethodException ex) { 544 return false; 545 } 546 } 547 /** 548 * A check handler is used by the main method applicability routine in order 549 * to handle specific method applicability failures. It is assumed that a class 550 * implementing this interface should throw exceptions that are a subtype of 551 * InapplicableMethodException (see below). Such exception will terminate the 552 * method applicability check and propagate important info outwards (for the 553 * purpose of generating better diagnostics). 554 */ 555 interface MethodCheckHandler { 556 /* The number of actuals and formals differ */ 557 InapplicableMethodException arityMismatch(); 558 /* An actual argument type does not conform to the corresponding formal type */ 559 InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected); 560 /* The element type of a varargs is not accessible in the current context */ 561 InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected); 562 } 563 564 /** 565 * Basic method check handler used within Resolve - all methods end up 566 * throwing InapplicableMethodException; a diagnostic fragment that describes 567 * the cause as to why the method is not applicable is set on the exception 568 * before it is thrown. 569 */ 570 MethodCheckHandler resolveHandler = new MethodCheckHandler() { 571 public InapplicableMethodException arityMismatch() { 572 return inapplicableMethodException.setMessage("arg.length.mismatch"); 573 } 574 public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) { 575 String key = varargs ? 576 "varargs.argument.mismatch" : 577 "no.conforming.assignment.exists"; 578 return inapplicableMethodException.setMessage(key, 579 found, expected); 580 } 581 public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) { 582 return inapplicableMethodException.setMessage("inaccessible.varargs.type", 583 expected, Kinds.kindName(location), location); 584 } 585 }; 586 587 void checkRawArgumentsAcceptable(Env<AttrContext> env, 588 List<Type> argtypes, 589 List<Type> formals, 590 boolean allowBoxing, 591 boolean useVarargs, 592 Warner warn) { 593 checkRawArgumentsAcceptable(env, List.<Type>nil(), argtypes, formals, 594 allowBoxing, useVarargs, warn, resolveHandler); 595 } 596 597 /** 598 * Main method applicability routine. Given a list of actual types A, 599 * a list of formal types F, determines whether the types in A are 600 * compatible (by method invocation conversion) with the types in F. 601 * 602 * Since this routine is shared between overload resolution and method 603 * type-inference, it is crucial that actual types are converted to the 604 * corresponding 'undet' form (i.e. where inference variables are replaced 605 * with undetvars) so that constraints can be propagated and collected. 606 * 607 * Moreover, if one or more types in A is a poly type, this routine calls 608 * Infer.instantiateArg in order to complete the poly type (this might involve 609 * deferred attribution). 610 * 611 * A method check handler (see above) is used in order to report errors. 612 */ 613 List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env, 614 List<Type> undetvars, 615 List<Type> argtypes, 616 List<Type> formals, 617 boolean allowBoxing, 618 boolean useVarargs, 619 Warner warn, 620 MethodCheckHandler handler) { 621 Type varargsFormal = useVarargs ? formals.last() : null; 622 ListBuffer<Type> checkedArgs = ListBuffer.lb(); 623 624 if (varargsFormal == null && 625 argtypes.size() != formals.size()) { 626 throw handler.arityMismatch(); // not enough args 627 } 628 629 while (argtypes.nonEmpty() && formals.head != varargsFormal) { 630 Type undetFormal = infer.asUndetType(formals.head, undetvars); 631 Type capturedActual = types.capture(argtypes.head); 632 boolean works = allowBoxing ? 633 types.isConvertible(capturedActual, undetFormal, warn) : 634 types.isSubtypeUnchecked(capturedActual, undetFormal, warn); 635 if (!works) { 636 throw handler.argumentMismatch(false, argtypes.head, formals.head); 637 } 638 checkedArgs.append(capturedActual); 639 argtypes = argtypes.tail; 640 formals = formals.tail; 641 } 642 643 if (formals.head != varargsFormal) { 644 throw handler.arityMismatch(); // not enough args 645 } 646 647 if (useVarargs) { 648 //note: if applicability check is triggered by most specific test, 649 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) 650 Type elt = types.elemtype(varargsFormal); 651 Type eltUndet = infer.asUndetType(elt, undetvars); 652 while (argtypes.nonEmpty()) { 653 Type capturedActual = types.capture(argtypes.head); 654 if (!types.isConvertible(capturedActual, eltUndet, warn)) { 655 throw handler.argumentMismatch(true, argtypes.head, elt); 656 } 657 checkedArgs.append(capturedActual); 658 argtypes = argtypes.tail; 659 } 660 //check varargs element type accessibility 661 if (undetvars.isEmpty() && !isAccessible(env, elt)) { 662 Symbol location = env.enclClass.sym; 663 throw handler.inaccessibleVarargs(location, elt); 664 } 665 } 666 return checkedArgs.toList(); 667 } 668 // where 669 public static class InapplicableMethodException extends RuntimeException { 670 private static final long serialVersionUID = 0; 671 672 JCDiagnostic diagnostic; 673 JCDiagnostic.Factory diags; 674 675 InapplicableMethodException(JCDiagnostic.Factory diags) { 676 this.diagnostic = null; 677 this.diags = diags; 678 } 679 InapplicableMethodException setMessage() { 680 this.diagnostic = null; 681 return this; 682 } 683 InapplicableMethodException setMessage(String key) { 684 this.diagnostic = key != null ? diags.fragment(key) : null; 685 return this; 686 } 687 InapplicableMethodException setMessage(String key, Object... args) { 688 this.diagnostic = key != null ? diags.fragment(key, args) : null; 689 return this; 690 } 691 InapplicableMethodException setMessage(JCDiagnostic diag) { 692 this.diagnostic = diag; 693 return this; 694 } 695 696 public JCDiagnostic getDiagnostic() { 697 return diagnostic; 698 } 699 } 700 private final InapplicableMethodException inapplicableMethodException; 701 702 /* *************************************************************************** 703 * Symbol lookup 704 * the following naming conventions for arguments are used 705 * 706 * env is the environment where the symbol was mentioned 707 * site is the type of which the symbol is a member 708 * name is the symbol's name 709 * if no arguments are given 710 * argtypes are the value arguments, if we search for a method 711 * 712 * If no symbol was found, a ResolveError detailing the problem is returned. 713 ****************************************************************************/ 714 715 /** Find field. Synthetic fields are always skipped. 716 * @param env The current environment. 717 * @param site The original type from where the selection takes place. 718 * @param name The name of the field. 719 * @param c The class to search for the field. This is always 720 * a superclass or implemented interface of site's class. 721 */ 722 Symbol findField(Env<AttrContext> env, 723 Type site, 724 Name name, 725 TypeSymbol c) { 726 while (c.type.tag == TYPEVAR) 727 c = c.type.getUpperBound().tsym; 728 Symbol bestSoFar = varNotFound; 729 Symbol sym; 730 Scope.Entry e = c.members().lookup(name); 731 while (e.scope != null) { 732 if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) { 733 return isAccessible(env, site, e.sym) 734 ? e.sym : new AccessError(env, site, e.sym); 735 } 736 e = e.next(); 737 } 738 Type st = types.supertype(c.type); 739 if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) { 740 sym = findField(env, site, name, st.tsym); 741 if (sym.kind < bestSoFar.kind) bestSoFar = sym; 742 } 743 for (List<Type> l = types.interfaces(c.type); 744 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 745 l = l.tail) { 746 sym = findField(env, site, name, l.head.tsym); 747 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 748 sym.owner != bestSoFar.owner) 749 bestSoFar = new AmbiguityError(bestSoFar, sym); 750 else if (sym.kind < bestSoFar.kind) 751 bestSoFar = sym; 752 } 753 return bestSoFar; 754 } 755 756 /** Resolve a field identifier, throw a fatal error if not found. 757 * @param pos The position to use for error reporting. 758 * @param env The environment current at the method invocation. 759 * @param site The type of the qualifying expression, in which 760 * identifier is searched. 761 * @param name The identifier's name. 762 */ 763 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env, 764 Type site, Name name) { 765 Symbol sym = findField(env, site, name, site.tsym); 766 if (sym.kind == VAR) return (VarSymbol)sym; 767 else throw new FatalError( 768 diags.fragment("fatal.err.cant.locate.field", 769 name)); 770 } 771 772 /** Find unqualified variable or field with given name. 773 * Synthetic fields always skipped. 774 * @param env The current environment. 775 * @param name The name of the variable or field. 776 */ 777 Symbol findVar(Env<AttrContext> env, Name name) { 778 Symbol bestSoFar = varNotFound; 779 Symbol sym; 780 Env<AttrContext> env1 = env; 781 boolean staticOnly = false; 782 while (env1.outer != null) { 783 if (isStatic(env1)) staticOnly = true; 784 Scope.Entry e = env1.info.scope.lookup(name); 785 while (e.scope != null && 786 (e.sym.kind != VAR || 787 (e.sym.flags_field & SYNTHETIC) != 0)) 788 e = e.next(); 789 sym = (e.scope != null) 790 ? e.sym 791 : findField( 792 env1, env1.enclClass.sym.type, name, env1.enclClass.sym); 793 if (sym.exists()) { 794 if (staticOnly && 795 sym.kind == VAR && 796 sym.owner.kind == TYP && 797 (sym.flags() & STATIC) == 0) 798 return new StaticError(sym); 799 else 800 return sym; 801 } else if (sym.kind < bestSoFar.kind) { 802 bestSoFar = sym; 803 } 804 805 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 806 env1 = env1.outer; 807 } 808 809 sym = findField(env, syms.predefClass.type, name, syms.predefClass); 810 if (sym.exists()) 811 return sym; 812 if (bestSoFar.exists()) 813 return bestSoFar; 814 815 Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 816 for (; e.scope != null; e = e.next()) { 817 sym = e.sym; 818 Type origin = e.getOrigin().owner.type; 819 if (sym.kind == VAR) { 820 if (e.sym.owner.type != origin) 821 sym = sym.clone(e.getOrigin().owner); 822 return isAccessible(env, origin, sym) 823 ? sym : new AccessError(env, origin, sym); 824 } 825 } 826 827 Symbol origin = null; 828 e = env.toplevel.starImportScope.lookup(name); 829 for (; e.scope != null; e = e.next()) { 830 sym = e.sym; 831 if (sym.kind != VAR) 832 continue; 833 // invariant: sym.kind == VAR 834 if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner) 835 return new AmbiguityError(bestSoFar, sym); 836 else if (bestSoFar.kind >= VAR) { 837 origin = e.getOrigin().owner; 838 bestSoFar = isAccessible(env, origin.type, sym) 839 ? sym : new AccessError(env, origin.type, sym); 840 } 841 } 842 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type) 843 return bestSoFar.clone(origin); 844 else 845 return bestSoFar; 846 } 847 848 Warner noteWarner = new Warner(); 849 850 /** Select the best method for a call site among two choices. 851 * @param env The current environment. 852 * @param site The original type from where the 853 * selection takes place. 854 * @param argtypes The invocation's value arguments, 855 * @param typeargtypes The invocation's type arguments, 856 * @param sym Proposed new best match. 857 * @param bestSoFar Previously found best match. 858 * @param allowBoxing Allow boxing conversions of arguments. 859 * @param useVarargs Box trailing arguments into an array for varargs. 860 */ 861 @SuppressWarnings("fallthrough") 862 Symbol selectBest(Env<AttrContext> env, 863 Type site, 864 List<Type> argtypes, 865 List<Type> typeargtypes, 866 Symbol sym, 867 Symbol bestSoFar, 868 boolean allowBoxing, 869 boolean useVarargs, 870 boolean operator) { 871 if (sym.kind == ERR) return bestSoFar; 872 if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; 873 Assert.check(sym.kind < AMBIGUOUS); 874 try { 875 Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes, 876 allowBoxing, useVarargs, Warner.noWarnings); 877 if (!operator) 878 currentResolutionContext.addApplicableCandidate(sym, mt); 879 } catch (InapplicableMethodException ex) { 880 if (!operator) 881 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); 882 switch (bestSoFar.kind) { 883 case ABSENT_MTH: 884 return wrongMethod; 885 case WRONG_MTH: 886 if (operator) return bestSoFar; 887 case WRONG_MTHS: 888 return wrongMethods; 889 default: 890 return bestSoFar; 891 } 892 } 893 if (!isAccessible(env, site, sym)) { 894 return (bestSoFar.kind == ABSENT_MTH) 895 ? new AccessError(env, site, sym) 896 : bestSoFar; 897 } 898 return (bestSoFar.kind > AMBIGUOUS) 899 ? sym 900 : mostSpecific(sym, bestSoFar, env, site, 901 allowBoxing && operator, useVarargs); 902 } 903 904 /* Return the most specific of the two methods for a call, 905 * given that both are accessible and applicable. 906 * @param m1 A new candidate for most specific. 907 * @param m2 The previous most specific candidate. 908 * @param env The current environment. 909 * @param site The original type from where the selection 910 * takes place. 911 * @param allowBoxing Allow boxing conversions of arguments. 912 * @param useVarargs Box trailing arguments into an array for varargs. 913 */ 914 Symbol mostSpecific(Symbol m1, 915 Symbol m2, 916 Env<AttrContext> env, 917 final Type site, 918 boolean allowBoxing, 919 boolean useVarargs) { 920 switch (m2.kind) { 921 case MTH: 922 if (m1 == m2) return m1; 923 boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs); 924 boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs); 925 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 926 Type mt1 = types.memberType(site, m1); 927 Type mt2 = types.memberType(site, m2); 928 if (!types.overrideEquivalent(mt1, mt2)) 929 return ambiguityError(m1, m2); 930 931 // same signature; select (a) the non-bridge method, or 932 // (b) the one that overrides the other, or (c) the concrete 933 // one, or (d) merge both abstract signatures 934 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) 935 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 936 937 // if one overrides or hides the other, use it 938 TypeSymbol m1Owner = (TypeSymbol)m1.owner; 939 TypeSymbol m2Owner = (TypeSymbol)m2.owner; 940 if (types.asSuper(m1Owner.type, m2Owner) != null && 941 ((m1.owner.flags_field & INTERFACE) == 0 || 942 (m2.owner.flags_field & INTERFACE) != 0) && 943 m1.overrides(m2, m1Owner, types, false)) 944 return m1; 945 if (types.asSuper(m2Owner.type, m1Owner) != null && 946 ((m2.owner.flags_field & INTERFACE) == 0 || 947 (m1.owner.flags_field & INTERFACE) != 0) && 948 m2.overrides(m1, m2Owner, types, false)) 949 return m2; 950 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; 951 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; 952 if (m1Abstract && !m2Abstract) return m2; 953 if (m2Abstract && !m1Abstract) return m1; 954 // both abstract or both concrete 955 if (!m1Abstract && !m2Abstract) 956 return ambiguityError(m1, m2); 957 // check that both signatures have the same erasure 958 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), 959 m2.erasure(types).getParameterTypes())) 960 return ambiguityError(m1, m2); 961 // both abstract, neither overridden; merge throws clause and result type 962 Type mst = mostSpecificReturnType(mt1, mt2); 963 if (mst == null) { 964 // Theoretically, this can't happen, but it is possible 965 // due to error recovery or mixing incompatible class files 966 return ambiguityError(m1, m2); 967 } 968 Symbol mostSpecific = mst == mt1 ? m1 : m2; 969 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); 970 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); 971 MethodSymbol result = new MethodSymbol( 972 mostSpecific.flags(), 973 mostSpecific.name, 974 newSig, 975 mostSpecific.owner) { 976 @Override 977 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 978 if (origin == site.tsym) 979 return this; 980 else 981 return super.implementation(origin, types, checkResult); 982 } 983 }; 984 return result; 985 } 986 if (m1SignatureMoreSpecific) return m1; 987 if (m2SignatureMoreSpecific) return m2; 988 return ambiguityError(m1, m2); 989 case AMBIGUOUS: 990 AmbiguityError e = (AmbiguityError)m2; 991 Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs); 992 Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs); 993 if (err1 == err2) return err1; 994 if (err1 == e.sym && err2 == e.sym2) return m2; 995 if (err1 instanceof AmbiguityError && 996 err2 instanceof AmbiguityError && 997 ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym) 998 return ambiguityError(m1, m2); 999 else 1000 return ambiguityError(err1, err2); 1001 default: 1002 throw new AssertionError(); 1003 } 1004 } 1005 //where 1006 private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) { 1007 noteWarner.clear(); 1008 Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs)); 1009 Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs), 1010 types.lowerBoundArgtypes(mtype1), null, 1011 allowBoxing, false, noteWarner); 1012 return mtype2 != null && 1013 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); 1014 } 1015 //where 1016 private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) { 1017 List<Type> fromArgs = from.type.getParameterTypes(); 1018 List<Type> toArgs = to.type.getParameterTypes(); 1019 if (useVarargs && 1020 (from.flags() & VARARGS) != 0 && 1021 (to.flags() & VARARGS) != 0) { 1022 Type varargsTypeFrom = fromArgs.last(); 1023 Type varargsTypeTo = toArgs.last(); 1024 ListBuffer<Type> args = ListBuffer.lb(); 1025 if (toArgs.length() < fromArgs.length()) { 1026 //if we are checking a varargs method 'from' against another varargs 1027 //method 'to' (where arity of 'to' < arity of 'from') then expand signature 1028 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to' 1029 //until 'to' signature has the same arity as 'from') 1030 while (fromArgs.head != varargsTypeFrom) { 1031 args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head); 1032 fromArgs = fromArgs.tail; 1033 toArgs = toArgs.head == varargsTypeTo ? 1034 toArgs : 1035 toArgs.tail; 1036 } 1037 } else { 1038 //formal argument list is same as original list where last 1039 //argument (array type) is removed 1040 args.appendList(toArgs.reverse().tail.reverse()); 1041 } 1042 //append varargs element type as last synthetic formal 1043 args.append(types.elemtype(varargsTypeTo)); 1044 Type mtype = types.createMethodTypeWithParameters(to.type, args.toList()); 1045 return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner); 1046 } else { 1047 return to; 1048 } 1049 } 1050 //where 1051 Type mostSpecificReturnType(Type mt1, Type mt2) { 1052 Type rt1 = mt1.getReturnType(); 1053 Type rt2 = mt2.getReturnType(); 1054 1055 if (mt1.tag == FORALL && mt2.tag == FORALL) { 1056 //if both are generic methods, adjust return type ahead of subtyping check 1057 rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments()); 1058 } 1059 //first use subtyping, then return type substitutability 1060 if (types.isSubtype(rt1, rt2)) { 1061 return mt1; 1062 } else if (types.isSubtype(rt2, rt1)) { 1063 return mt2; 1064 } else if (types.returnTypeSubstitutable(mt1, mt2)) { 1065 return mt1; 1066 } else if (types.returnTypeSubstitutable(mt2, mt1)) { 1067 return mt2; 1068 } else { 1069 return null; 1070 } 1071 } 1072 //where 1073 Symbol ambiguityError(Symbol m1, Symbol m2) { 1074 if (((m1.flags() | m2.flags()) & CLASH) != 0) { 1075 return (m1.flags() & CLASH) == 0 ? m1 : m2; 1076 } else { 1077 return new AmbiguityError(m1, m2); 1078 } 1079 } 1080 1081 /** Find best qualified method matching given name, type and value 1082 * arguments. 1083 * @param env The current environment. 1084 * @param site The original type from where the selection 1085 * takes place. 1086 * @param name The method's name. 1087 * @param argtypes The method's value arguments. 1088 * @param typeargtypes The method's type arguments 1089 * @param allowBoxing Allow boxing conversions of arguments. 1090 * @param useVarargs Box trailing arguments into an array for varargs. 1091 */ 1092 Symbol findMethod(Env<AttrContext> env, 1093 Type site, 1094 Name name, 1095 List<Type> argtypes, 1096 List<Type> typeargtypes, 1097 boolean allowBoxing, 1098 boolean useVarargs, 1099 boolean operator) { 1100 Symbol bestSoFar = methodNotFound; 1101 bestSoFar = findMethod(env, 1102 site, 1103 name, 1104 argtypes, 1105 typeargtypes, 1106 site.tsym.type, 1107 true, 1108 bestSoFar, 1109 allowBoxing, 1110 useVarargs, 1111 operator, 1112 new HashSet<TypeSymbol>()); 1113 reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar); 1114 return bestSoFar; 1115 } 1116 // where 1117 private Symbol findMethod(Env<AttrContext> env, 1118 Type site, 1119 Name name, 1120 List<Type> argtypes, 1121 List<Type> typeargtypes, 1122 Type intype, 1123 boolean abstractok, 1124 Symbol bestSoFar, 1125 boolean allowBoxing, 1126 boolean useVarargs, 1127 boolean operator, 1128 Set<TypeSymbol> seen) { 1129 for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) { 1130 while (ct.tag == TYPEVAR) 1131 ct = ct.getUpperBound(); 1132 ClassSymbol c = (ClassSymbol)ct.tsym; 1133 if (!seen.add(c)) return bestSoFar; 1134 if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0) 1135 abstractok = false; 1136 for (Scope.Entry e = c.members().lookup(name); 1137 e.scope != null; 1138 e = e.next()) { 1139 //- System.out.println(" e " + e.sym); 1140 if (e.sym.kind == MTH && 1141 (e.sym.flags_field & SYNTHETIC) == 0) { 1142 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 1143 e.sym, bestSoFar, 1144 allowBoxing, 1145 useVarargs, 1146 operator); 1147 } 1148 } 1149 if (name == names.init) 1150 break; 1151 //- System.out.println(" - " + bestSoFar); 1152 if (abstractok) { 1153 Symbol concrete = methodNotFound; 1154 if ((bestSoFar.flags() & ABSTRACT) == 0) 1155 concrete = bestSoFar; 1156 for (List<Type> l = types.interfaces(c.type); 1157 l.nonEmpty(); 1158 l = l.tail) { 1159 bestSoFar = findMethod(env, site, name, argtypes, 1160 typeargtypes, 1161 l.head, abstractok, bestSoFar, 1162 allowBoxing, useVarargs, operator, seen); 1163 } 1164 if (concrete != bestSoFar && 1165 concrete.kind < ERR && bestSoFar.kind < ERR && 1166 types.isSubSignature(concrete.type, bestSoFar.type)) 1167 bestSoFar = concrete; 1168 } 1169 } 1170 return bestSoFar; 1171 } 1172 1173 /** Find unqualified method matching given name, type and value arguments. 1174 * @param env The current environment. 1175 * @param name The method's name. 1176 * @param argtypes The method's value arguments. 1177 * @param typeargtypes The method's type arguments. 1178 * @param allowBoxing Allow boxing conversions of arguments. 1179 * @param useVarargs Box trailing arguments into an array for varargs. 1180 */ 1181 Symbol findFun(Env<AttrContext> env, Name name, 1182 List<Type> argtypes, List<Type> typeargtypes, 1183 boolean allowBoxing, boolean useVarargs) { 1184 Symbol bestSoFar = methodNotFound; 1185 Symbol sym; 1186 Env<AttrContext> env1 = env; 1187 boolean staticOnly = false; 1188 while (env1.outer != null) { 1189 if (isStatic(env1)) staticOnly = true; 1190 sym = findMethod( 1191 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 1192 allowBoxing, useVarargs, false); 1193 if (sym.exists()) { 1194 if (staticOnly && 1195 sym.kind == MTH && 1196 sym.owner.kind == TYP && 1197 (sym.flags() & STATIC) == 0) return new StaticError(sym); 1198 else return sym; 1199 } else if (sym.kind < bestSoFar.kind) { 1200 bestSoFar = sym; 1201 } 1202 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1203 env1 = env1.outer; 1204 } 1205 1206 sym = findMethod(env, syms.predefClass.type, name, argtypes, 1207 typeargtypes, allowBoxing, useVarargs, false); 1208 if (sym.exists()) 1209 return sym; 1210 1211 Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 1212 for (; e.scope != null; e = e.next()) { 1213 sym = e.sym; 1214 Type origin = e.getOrigin().owner.type; 1215 if (sym.kind == MTH) { 1216 if (e.sym.owner.type != origin) 1217 sym = sym.clone(e.getOrigin().owner); 1218 if (!isAccessible(env, origin, sym)) 1219 sym = new AccessError(env, origin, sym); 1220 bestSoFar = selectBest(env, origin, 1221 argtypes, typeargtypes, 1222 sym, bestSoFar, 1223 allowBoxing, useVarargs, false); 1224 } 1225 } 1226 if (bestSoFar.exists()) 1227 return bestSoFar; 1228 1229 e = env.toplevel.starImportScope.lookup(name); 1230 for (; e.scope != null; e = e.next()) { 1231 sym = e.sym; 1232 Type origin = e.getOrigin().owner.type; 1233 if (sym.kind == MTH) { 1234 if (e.sym.owner.type != origin) 1235 sym = sym.clone(e.getOrigin().owner); 1236 if (!isAccessible(env, origin, sym)) 1237 sym = new AccessError(env, origin, sym); 1238 bestSoFar = selectBest(env, origin, 1239 argtypes, typeargtypes, 1240 sym, bestSoFar, 1241 allowBoxing, useVarargs, false); 1242 } 1243 } 1244 return bestSoFar; 1245 } 1246 1247 /** Load toplevel or member class with given fully qualified name and 1248 * verify that it is accessible. 1249 * @param env The current environment. 1250 * @param name The fully qualified name of the class to be loaded. 1251 */ 1252 Symbol loadClass(Env<AttrContext> env, Name name) { 1253 try { 1254 ClassSymbol c = reader.loadClass(name); 1255 return isAccessible(env, c) ? c : new AccessError(c); 1256 } catch (ClassReader.BadClassFile err) { 1257 throw err; 1258 } catch (CompletionFailure ex) { 1259 return typeNotFound; 1260 } 1261 } 1262 1263 /** Find qualified member type. 1264 * @param env The current environment. 1265 * @param site The original type from where the selection takes 1266 * place. 1267 * @param name The type's name. 1268 * @param c The class to search for the member type. This is 1269 * always a superclass or implemented interface of 1270 * site's class. 1271 */ 1272 Symbol findMemberType(Env<AttrContext> env, 1273 Type site, 1274 Name name, 1275 TypeSymbol c) { 1276 Symbol bestSoFar = typeNotFound; 1277 Symbol sym; 1278 Scope.Entry e = c.members().lookup(name); 1279 while (e.scope != null) { 1280 if (e.sym.kind == TYP) { 1281 return isAccessible(env, site, e.sym) 1282 ? e.sym 1283 : new AccessError(env, site, e.sym); 1284 } 1285 e = e.next(); 1286 } 1287 Type st = types.supertype(c.type); 1288 if (st != null && st.tag == CLASS) { 1289 sym = findMemberType(env, site, name, st.tsym); 1290 if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1291 } 1292 for (List<Type> l = types.interfaces(c.type); 1293 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1294 l = l.tail) { 1295 sym = findMemberType(env, site, name, l.head.tsym); 1296 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 1297 sym.owner != bestSoFar.owner) 1298 bestSoFar = new AmbiguityError(bestSoFar, sym); 1299 else if (sym.kind < bestSoFar.kind) 1300 bestSoFar = sym; 1301 } 1302 return bestSoFar; 1303 } 1304 1305 /** Find a global type in given scope and load corresponding class. 1306 * @param env The current environment. 1307 * @param scope The scope in which to look for the type. 1308 * @param name The type's name. 1309 */ 1310 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) { 1311 Symbol bestSoFar = typeNotFound; 1312 for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) { 1313 Symbol sym = loadClass(env, e.sym.flatName()); 1314 if (bestSoFar.kind == TYP && sym.kind == TYP && 1315 bestSoFar != sym) 1316 return new AmbiguityError(bestSoFar, sym); 1317 else if (sym.kind < bestSoFar.kind) 1318 bestSoFar = sym; 1319 } 1320 return bestSoFar; 1321 } 1322 1323 /** Find an unqualified type symbol. 1324 * @param env The current environment. 1325 * @param name The type's name. 1326 */ 1327 Symbol findType(Env<AttrContext> env, Name name) { 1328 Symbol bestSoFar = typeNotFound; 1329 Symbol sym; 1330 boolean staticOnly = false; 1331 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) { 1332 if (isStatic(env1)) staticOnly = true; 1333 for (Scope.Entry e = env1.info.scope.lookup(name); 1334 e.scope != null; 1335 e = e.next()) { 1336 if (e.sym.kind == TYP) { 1337 if (staticOnly && 1338 e.sym.type.tag == TYPEVAR && 1339 e.sym.owner.kind == TYP) return new StaticError(e.sym); 1340 return e.sym; 1341 } 1342 } 1343 1344 sym = findMemberType(env1, env1.enclClass.sym.type, name, 1345 env1.enclClass.sym); 1346 if (staticOnly && sym.kind == TYP && 1347 sym.type.tag == CLASS && 1348 sym.type.getEnclosingType().tag == CLASS && 1349 env1.enclClass.sym.type.isParameterized() && 1350 sym.type.getEnclosingType().isParameterized()) 1351 return new StaticError(sym); 1352 else if (sym.exists()) return sym; 1353 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1354 1355 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass; 1356 if ((encl.sym.flags() & STATIC) != 0) 1357 staticOnly = true; 1358 } 1359 1360 if (!env.tree.hasTag(IMPORT)) { 1361 sym = findGlobalType(env, env.toplevel.namedImportScope, name); 1362 if (sym.exists()) return sym; 1363 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1364 1365 sym = findGlobalType(env, env.toplevel.packge.members(), name); 1366 if (sym.exists()) return sym; 1367 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1368 1369 sym = findGlobalType(env, env.toplevel.starImportScope, name); 1370 if (sym.exists()) return sym; 1371 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1372 } 1373 1374 return bestSoFar; 1375 } 1376 1377 /** Find an unqualified identifier which matches a specified kind set. 1378 * @param env The current environment. 1379 * @param name The indentifier's name. 1380 * @param kind Indicates the possible symbol kinds 1381 * (a subset of VAL, TYP, PCK). 1382 */ 1383 Symbol findIdent(Env<AttrContext> env, Name name, int kind) { 1384 Symbol bestSoFar = typeNotFound; 1385 Symbol sym; 1386 1387 if ((kind & VAR) != 0) { 1388 sym = findVar(env, name); 1389 if (sym.exists()) return sym; 1390 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1391 } 1392 1393 if ((kind & TYP) != 0) { 1394 sym = findType(env, name); 1395 if (sym.exists()) return sym; 1396 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1397 } 1398 1399 if ((kind & PCK) != 0) return reader.enterPackage(name); 1400 else return bestSoFar; 1401 } 1402 1403 /** Find an identifier in a package which matches a specified kind set. 1404 * @param env The current environment. 1405 * @param name The identifier's name. 1406 * @param kind Indicates the possible symbol kinds 1407 * (a nonempty subset of TYP, PCK). 1408 */ 1409 Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck, 1410 Name name, int kind) { 1411 Name fullname = TypeSymbol.formFullName(name, pck); 1412 Symbol bestSoFar = typeNotFound; 1413 PackageSymbol pack = null; 1414 if ((kind & PCK) != 0) { 1415 pack = reader.enterPackage(fullname); 1416 if (pack.exists()) return pack; 1417 } 1418 if ((kind & TYP) != 0) { 1419 Symbol sym = loadClass(env, fullname); 1420 if (sym.exists()) { 1421 // don't allow programs to use flatnames 1422 if (name == sym.name) return sym; 1423 } 1424 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1425 } 1426 return (pack != null) ? pack : bestSoFar; 1427 } 1428 1429 /** Find an identifier among the members of a given type `site'. 1430 * @param env The current environment. 1431 * @param site The type containing the symbol to be found. 1432 * @param name The identifier's name. 1433 * @param kind Indicates the possible symbol kinds 1434 * (a subset of VAL, TYP). 1435 */ 1436 Symbol findIdentInType(Env<AttrContext> env, Type site, 1437 Name name, int kind) { 1438 Symbol bestSoFar = typeNotFound; 1439 Symbol sym; 1440 if ((kind & VAR) != 0) { 1441 sym = findField(env, site, name, site.tsym); 1442 if (sym.exists()) return sym; 1443 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1444 } 1445 1446 if ((kind & TYP) != 0) { 1447 sym = findMemberType(env, site, name, site.tsym); 1448 if (sym.exists()) return sym; 1449 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1450 } 1451 return bestSoFar; 1452 } 1453 1454 /* *************************************************************************** 1455 * Access checking 1456 * The following methods convert ResolveErrors to ErrorSymbols, issuing 1457 * an error message in the process 1458 ****************************************************************************/ 1459 1460 /** If `sym' is a bad symbol: report error and return errSymbol 1461 * else pass through unchanged, 1462 * additional arguments duplicate what has been used in trying to find the 1463 * symbol (--> flyweight pattern). This improves performance since we 1464 * expect misses to happen frequently. 1465 * 1466 * @param sym The symbol that was found, or a ResolveError. 1467 * @param pos The position to use for error reporting. 1468 * @param site The original type from where the selection took place. 1469 * @param name The symbol's name. 1470 * @param argtypes The invocation's value arguments, 1471 * if we looked for a method. 1472 * @param typeargtypes The invocation's type arguments, 1473 * if we looked for a method. 1474 */ 1475 Symbol access(Symbol sym, 1476 DiagnosticPosition pos, 1477 Symbol location, 1478 Type site, 1479 Name name, 1480 boolean qualified, 1481 List<Type> argtypes, 1482 List<Type> typeargtypes) { 1483 if (sym.kind >= AMBIGUOUS) { 1484 ResolveError errSym = (ResolveError)sym; 1485 if (!site.isErroneous() && 1486 !Type.isErroneous(argtypes) && 1487 (typeargtypes==null || !Type.isErroneous(typeargtypes))) 1488 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes); 1489 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol); 1490 } 1491 return sym; 1492 } 1493 1494 /** Same as original access(), but without location. 1495 */ 1496 Symbol access(Symbol sym, 1497 DiagnosticPosition pos, 1498 Type site, 1499 Name name, 1500 boolean qualified, 1501 List<Type> argtypes, 1502 List<Type> typeargtypes) { 1503 return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes); 1504 } 1505 1506 /** Same as original access(), but without type arguments and arguments. 1507 */ 1508 Symbol access(Symbol sym, 1509 DiagnosticPosition pos, 1510 Symbol location, 1511 Type site, 1512 Name name, 1513 boolean qualified) { 1514 if (sym.kind >= AMBIGUOUS) 1515 return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null); 1516 else 1517 return sym; 1518 } 1519 1520 /** Same as original access(), but without location, type arguments and arguments. 1521 */ 1522 Symbol access(Symbol sym, 1523 DiagnosticPosition pos, 1524 Type site, 1525 Name name, 1526 boolean qualified) { 1527 return access(sym, pos, site.tsym, site, name, qualified); 1528 } 1529 1530 /** Check that sym is not an abstract method. 1531 */ 1532 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { 1533 if ((sym.flags() & ABSTRACT) != 0) 1534 log.error(pos, "abstract.cant.be.accessed.directly", 1535 kindName(sym), sym, sym.location()); 1536 } 1537 1538 /* *************************************************************************** 1539 * Debugging 1540 ****************************************************************************/ 1541 1542 /** print all scopes starting with scope s and proceeding outwards. 1543 * used for debugging. 1544 */ 1545 public void printscopes(Scope s) { 1546 while (s != null) { 1547 if (s.owner != null) 1548 System.err.print(s.owner + ": "); 1549 for (Scope.Entry e = s.elems; e != null; e = e.sibling) { 1550 if ((e.sym.flags() & ABSTRACT) != 0) 1551 System.err.print("abstract "); 1552 System.err.print(e.sym + " "); 1553 } 1554 System.err.println(); 1555 s = s.next; 1556 } 1557 } 1558 1559 void printscopes(Env<AttrContext> env) { 1560 while (env.outer != null) { 1561 System.err.println("------------------------------"); 1562 printscopes(env.info.scope); 1563 env = env.outer; 1564 } 1565 } 1566 1567 public void printscopes(Type t) { 1568 while (t.tag == CLASS) { 1569 printscopes(t.tsym.members()); 1570 t = types.supertype(t); 1571 } 1572 } 1573 1574 /* *************************************************************************** 1575 * Name resolution 1576 * Naming conventions are as for symbol lookup 1577 * Unlike the find... methods these methods will report access errors 1578 ****************************************************************************/ 1579 1580 /** Resolve an unqualified (non-method) identifier. 1581 * @param pos The position to use for error reporting. 1582 * @param env The environment current at the identifier use. 1583 * @param name The identifier's name. 1584 * @param kind The set of admissible symbol kinds for the identifier. 1585 */ 1586 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env, 1587 Name name, int kind) { 1588 return access( 1589 findIdent(env, name, kind), 1590 pos, env.enclClass.sym.type, name, false); 1591 } 1592 1593 /** Resolve an unqualified method identifier. 1594 * @param pos The position to use for error reporting. 1595 * @param env The environment current at the method invocation. 1596 * @param name The identifier's name. 1597 * @param argtypes The types of the invocation's value arguments. 1598 * @param typeargtypes The types of the invocation's type arguments. 1599 */ 1600 Symbol resolveMethod(DiagnosticPosition pos, 1601 Env<AttrContext> env, 1602 Name name, 1603 List<Type> argtypes, 1604 List<Type> typeargtypes) { 1605 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1606 try { 1607 currentResolutionContext = new MethodResolutionContext(); 1608 Symbol sym = methodNotFound; 1609 List<MethodResolutionPhase> steps = methodResolutionSteps; 1610 while (steps.nonEmpty() && 1611 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1612 sym.kind >= ERRONEOUS) { 1613 currentResolutionContext.step = steps.head; 1614 sym = findFun(env, name, argtypes, typeargtypes, 1615 steps.head.isBoxingRequired, 1616 env.info.varArgs = steps.head.isVarargsRequired); 1617 currentResolutionContext.resolutionCache.put(steps.head, sym); 1618 steps = steps.tail; 1619 } 1620 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 1621 MethodResolutionPhase errPhase = 1622 currentResolutionContext.firstErroneousResolutionPhase(); 1623 sym = access(currentResolutionContext.resolutionCache.get(errPhase), 1624 pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); 1625 env.info.varArgs = errPhase.isVarargsRequired; 1626 } 1627 return sym; 1628 } 1629 finally { 1630 currentResolutionContext = prevResolutionContext; 1631 } 1632 } 1633 1634 /** Resolve a qualified method identifier 1635 * @param pos The position to use for error reporting. 1636 * @param env The environment current at the method invocation. 1637 * @param site The type of the qualifying expression, in which 1638 * identifier is searched. 1639 * @param name The identifier's name. 1640 * @param argtypes The types of the invocation's value arguments. 1641 * @param typeargtypes The types of the invocation's type arguments. 1642 */ 1643 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 1644 Type site, Name name, List<Type> argtypes, 1645 List<Type> typeargtypes) { 1646 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes); 1647 } 1648 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 1649 Symbol location, Type site, Name name, List<Type> argtypes, 1650 List<Type> typeargtypes) { 1651 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes); 1652 } 1653 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext, 1654 DiagnosticPosition pos, Env<AttrContext> env, 1655 Symbol location, Type site, Name name, List<Type> argtypes, 1656 List<Type> typeargtypes) { 1657 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1658 try { 1659 currentResolutionContext = resolveContext; 1660 Symbol sym = methodNotFound; 1661 List<MethodResolutionPhase> steps = methodResolutionSteps; 1662 while (steps.nonEmpty() && 1663 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1664 sym.kind >= ERRONEOUS) { 1665 currentResolutionContext.step = steps.head; 1666 sym = findMethod(env, site, name, argtypes, typeargtypes, 1667 steps.head.isBoxingRequired(), 1668 env.info.varArgs = steps.head.isVarargsRequired(), false); 1669 currentResolutionContext.resolutionCache.put(steps.head, sym); 1670 steps = steps.tail; 1671 } 1672 if (sym.kind >= AMBIGUOUS) { 1673 if (site.tsym.isPolymorphicSignatureGeneric()) { 1674 //polymorphic receiver - synthesize new method symbol 1675 env.info.varArgs = false; 1676 sym = findPolymorphicSignatureInstance(env, 1677 site, name, null, argtypes); 1678 } 1679 else { 1680 //if nothing is found return the 'first' error 1681 MethodResolutionPhase errPhase = 1682 currentResolutionContext.firstErroneousResolutionPhase(); 1683 sym = access(currentResolutionContext.resolutionCache.get(errPhase), 1684 pos, location, site, name, true, argtypes, typeargtypes); 1685 env.info.varArgs = errPhase.isVarargsRequired; 1686 } 1687 } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) { 1688 //non-instantiated polymorphic signature - synthesize new method symbol 1689 env.info.varArgs = false; 1690 sym = findPolymorphicSignatureInstance(env, 1691 site, name, (MethodSymbol)sym, argtypes); 1692 } 1693 return sym; 1694 } 1695 finally { 1696 currentResolutionContext = prevResolutionContext; 1697 } 1698 } 1699 1700 /** Find or create an implicit method of exactly the given type (after erasure). 1701 * Searches in a side table, not the main scope of the site. 1702 * This emulates the lookup process required by JSR 292 in JVM. 1703 * @param env Attribution environment 1704 * @param site The original type from where the selection takes place. 1705 * @param name The method's name. 1706 * @param spMethod A template for the implicit method, or null. 1707 * @param argtypes The required argument types. 1708 * @param typeargtypes The required type arguments. 1709 */ 1710 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site, 1711 Name name, 1712 MethodSymbol spMethod, // sig. poly. method or null if none 1713 List<Type> argtypes) { 1714 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, 1715 site, name, spMethod, argtypes); 1716 long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE | 1717 (spMethod != null ? 1718 spMethod.flags() & Flags.AccessFlags : 1719 Flags.PUBLIC | Flags.STATIC); 1720 Symbol m = null; 1721 for (Scope.Entry e = polymorphicSignatureScope.lookup(name); 1722 e.scope != null; 1723 e = e.next()) { 1724 Symbol sym = e.sym; 1725 if (types.isSameType(mtype, sym.type) && 1726 (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) && 1727 types.isSameType(sym.owner.type, site)) { 1728 m = sym; 1729 break; 1730 } 1731 } 1732 if (m == null) { 1733 // create the desired method 1734 m = new MethodSymbol(flags, name, mtype, site.tsym); 1735 polymorphicSignatureScope.enter(m); 1736 } 1737 return m; 1738 } 1739 1740 /** Resolve a qualified method identifier, throw a fatal error if not 1741 * found. 1742 * @param pos The position to use for error reporting. 1743 * @param env The environment current at the method invocation. 1744 * @param site The type of the qualifying expression, in which 1745 * identifier is searched. 1746 * @param name The identifier's name. 1747 * @param argtypes The types of the invocation's value arguments. 1748 * @param typeargtypes The types of the invocation's type arguments. 1749 */ 1750 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env, 1751 Type site, Name name, 1752 List<Type> argtypes, 1753 List<Type> typeargtypes) { 1754 MethodResolutionContext resolveContext = new MethodResolutionContext(); 1755 resolveContext.internalResolution = true; 1756 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym, 1757 site, name, argtypes, typeargtypes); 1758 if (sym.kind == MTH) return (MethodSymbol)sym; 1759 else throw new FatalError( 1760 diags.fragment("fatal.err.cant.locate.meth", 1761 name)); 1762 } 1763 1764 /** Resolve constructor. 1765 * @param pos The position to use for error reporting. 1766 * @param env The environment current at the constructor invocation. 1767 * @param site The type of class for which a constructor is searched. 1768 * @param argtypes The types of the constructor invocation's value 1769 * arguments. 1770 * @param typeargtypes The types of the constructor invocation's type 1771 * arguments. 1772 */ 1773 Symbol resolveConstructor(DiagnosticPosition pos, 1774 Env<AttrContext> env, 1775 Type site, 1776 List<Type> argtypes, 1777 List<Type> typeargtypes) { 1778 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); 1779 } 1780 private Symbol resolveConstructor(MethodResolutionContext resolveContext, 1781 DiagnosticPosition pos, 1782 Env<AttrContext> env, 1783 Type site, 1784 List<Type> argtypes, 1785 List<Type> typeargtypes) { 1786 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1787 try { 1788 currentResolutionContext = resolveContext; 1789 Symbol sym = methodNotFound; 1790 List<MethodResolutionPhase> steps = methodResolutionSteps; 1791 while (steps.nonEmpty() && 1792 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1793 sym.kind >= ERRONEOUS) { 1794 currentResolutionContext.step = steps.head; 1795 sym = findConstructor(pos, env, site, argtypes, typeargtypes, 1796 steps.head.isBoxingRequired(), 1797 env.info.varArgs = steps.head.isVarargsRequired()); 1798 currentResolutionContext.resolutionCache.put(steps.head, sym); 1799 steps = steps.tail; 1800 } 1801 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 1802 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1803 sym = access(currentResolutionContext.resolutionCache.get(errPhase), 1804 pos, site, names.init, true, argtypes, typeargtypes); 1805 env.info.varArgs = errPhase.isVarargsRequired(); 1806 } 1807 return sym; 1808 } 1809 finally { 1810 currentResolutionContext = prevResolutionContext; 1811 } 1812 } 1813 1814 /** Resolve constructor using diamond inference. 1815 * @param pos The position to use for error reporting. 1816 * @param env The environment current at the constructor invocation. 1817 * @param site The type of class for which a constructor is searched. 1818 * The scope of this class has been touched in attribution. 1819 * @param argtypes The types of the constructor invocation's value 1820 * arguments. 1821 * @param typeargtypes The types of the constructor invocation's type 1822 * arguments. 1823 */ 1824 Symbol resolveDiamond(DiagnosticPosition pos, 1825 Env<AttrContext> env, 1826 Type site, 1827 List<Type> argtypes, 1828 List<Type> typeargtypes) { 1829 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1830 try { 1831 currentResolutionContext = new MethodResolutionContext(); 1832 Symbol sym = methodNotFound; 1833 List<MethodResolutionPhase> steps = methodResolutionSteps; 1834 while (steps.nonEmpty() && 1835 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1836 sym.kind >= ERRONEOUS) { 1837 currentResolutionContext.step = steps.head; 1838 sym = findDiamond(env, site, argtypes, typeargtypes, 1839 steps.head.isBoxingRequired(), 1840 env.info.varArgs = steps.head.isVarargsRequired()); 1841 currentResolutionContext.resolutionCache.put(steps.head, sym); 1842 steps = steps.tail; 1843 } 1844 if (sym.kind >= AMBIGUOUS) { 1845 final JCDiagnostic details = sym.kind == WRONG_MTH ? 1846 currentResolutionContext.candidates.head.details : 1847 null; 1848 Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") { 1849 @Override 1850 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 1851 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 1852 String key = details == null ? 1853 "cant.apply.diamond" : 1854 "cant.apply.diamond.1"; 1855 return diags.create(dkind, log.currentSource(), pos, key, 1856 diags.fragment("diamond", site.tsym), details); 1857 } 1858 }; 1859 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1860 sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes); 1861 env.info.varArgs = errPhase.isVarargsRequired(); 1862 } 1863 return sym; 1864 } 1865 finally { 1866 currentResolutionContext = prevResolutionContext; 1867 } 1868 } 1869 1870 /** This method scans all the constructor symbol in a given class scope - 1871 * assuming that the original scope contains a constructor of the kind: 1872 * Foo(X x, Y y), where X,Y are class type-variables declared in Foo, 1873 * a method check is executed against the modified constructor type: 1874 * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond 1875 * inference. The inferred return type of the synthetic constructor IS 1876 * the inferred type for the diamond operator. 1877 */ 1878 private Symbol findDiamond(Env<AttrContext> env, 1879 Type site, 1880 List<Type> argtypes, 1881 List<Type> typeargtypes, 1882 boolean allowBoxing, 1883 boolean useVarargs) { 1884 Symbol bestSoFar = methodNotFound; 1885 for (Scope.Entry e = site.tsym.members().lookup(names.init); 1886 e.scope != null; 1887 e = e.next()) { 1888 //- System.out.println(" e " + e.sym); 1889 if (e.sym.kind == MTH && 1890 (e.sym.flags_field & SYNTHETIC) == 0) { 1891 List<Type> oldParams = e.sym.type.tag == FORALL ? 1892 ((ForAll)e.sym.type).tvars : 1893 List.<Type>nil(); 1894 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), 1895 types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site)); 1896 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 1897 new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym), 1898 bestSoFar, 1899 allowBoxing, 1900 useVarargs, 1901 false); 1902 } 1903 } 1904 return bestSoFar; 1905 } 1906 1907 /** Resolve constructor. 1908 * @param pos The position to use for error reporting. 1909 * @param env The environment current at the constructor invocation. 1910 * @param site The type of class for which a constructor is searched. 1911 * @param argtypes The types of the constructor invocation's value 1912 * arguments. 1913 * @param typeargtypes The types of the constructor invocation's type 1914 * arguments. 1915 * @param allowBoxing Allow boxing and varargs conversions. 1916 * @param useVarargs Box trailing arguments into an array for varargs. 1917 */ 1918 Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1919 Type site, List<Type> argtypes, 1920 List<Type> typeargtypes, 1921 boolean allowBoxing, 1922 boolean useVarargs) { 1923 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1924 try { 1925 currentResolutionContext = new MethodResolutionContext(); 1926 return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs); 1927 } 1928 finally { 1929 currentResolutionContext = prevResolutionContext; 1930 } 1931 } 1932 1933 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1934 Type site, List<Type> argtypes, 1935 List<Type> typeargtypes, 1936 boolean allowBoxing, 1937 boolean useVarargs) { 1938 Symbol sym = findMethod(env, site, 1939 names.init, argtypes, 1940 typeargtypes, allowBoxing, 1941 useVarargs, false); 1942 chk.checkDeprecated(pos, env.info.scope.owner, sym); 1943 return sym; 1944 } 1945 1946 /** Resolve a constructor, throw a fatal error if not found. 1947 * @param pos The position to use for error reporting. 1948 * @param env The environment current at the method invocation. 1949 * @param site The type to be constructed. 1950 * @param argtypes The types of the invocation's value arguments. 1951 * @param typeargtypes The types of the invocation's type arguments. 1952 */ 1953 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1954 Type site, 1955 List<Type> argtypes, 1956 List<Type> typeargtypes) { 1957 MethodResolutionContext resolveContext = new MethodResolutionContext(); 1958 resolveContext.internalResolution = true; 1959 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 1960 if (sym.kind == MTH) return (MethodSymbol)sym; 1961 else throw new FatalError( 1962 diags.fragment("fatal.err.cant.locate.ctor", site)); 1963 } 1964 1965 /** Resolve operator. 1966 * @param pos The position to use for error reporting. 1967 * @param optag The tag of the operation tree. 1968 * @param env The environment current at the operation. 1969 * @param argtypes The types of the operands. 1970 */ 1971 Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, 1972 Env<AttrContext> env, List<Type> argtypes) { 1973 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1974 try { 1975 currentResolutionContext = new MethodResolutionContext(); 1976 Name name = treeinfo.operatorName(optag); 1977 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 1978 null, false, false, true); 1979 if (boxingEnabled && sym.kind >= WRONG_MTHS) 1980 sym = findMethod(env, syms.predefClass.type, name, argtypes, 1981 null, true, false, true); 1982 return access(sym, pos, env.enclClass.sym.type, name, 1983 false, argtypes, null); 1984 } 1985 finally { 1986 currentResolutionContext = prevResolutionContext; 1987 } 1988 } 1989 1990 /** Resolve operator. 1991 * @param pos The position to use for error reporting. 1992 * @param optag The tag of the operation tree. 1993 * @param env The environment current at the operation. 1994 * @param arg The type of the operand. 1995 */ 1996 Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) { 1997 return resolveOperator(pos, optag, env, List.of(arg)); 1998 } 1999 2000 /** Resolve binary operator. 2001 * @param pos The position to use for error reporting. 2002 * @param optag The tag of the operation tree. 2003 * @param env The environment current at the operation. 2004 * @param left The types of the left operand. 2005 * @param right The types of the right operand. 2006 */ 2007 Symbol resolveBinaryOperator(DiagnosticPosition pos, 2008 JCTree.Tag optag, 2009 Env<AttrContext> env, 2010 Type left, 2011 Type right) { 2012 return resolveOperator(pos, optag, env, List.of(left, right)); 2013 } 2014 2015 /** 2016 * Resolve `c.name' where name == this or name == super. 2017 * @param pos The position to use for error reporting. 2018 * @param env The environment current at the expression. 2019 * @param c The qualifier. 2020 * @param name The identifier's name. 2021 */ 2022 Symbol resolveSelf(DiagnosticPosition pos, 2023 Env<AttrContext> env, 2024 TypeSymbol c, 2025 Name name) { 2026 Env<AttrContext> env1 = env; 2027 boolean staticOnly = false; 2028 while (env1.outer != null) { 2029 if (isStatic(env1)) staticOnly = true; 2030 if (env1.enclClass.sym == c) { 2031 Symbol sym = env1.info.scope.lookup(name).sym; 2032 if (sym != null) { 2033 if (staticOnly) sym = new StaticError(sym); 2034 return access(sym, pos, env.enclClass.sym.type, 2035 name, true); 2036 } 2037 } 2038 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 2039 env1 = env1.outer; 2040 } 2041 log.error(pos, "not.encl.class", c); 2042 return syms.errSymbol; 2043 } 2044 2045 /** 2046 * Resolve `c.this' for an enclosing class c that contains the 2047 * named member. 2048 * @param pos The position to use for error reporting. 2049 * @param env The environment current at the expression. 2050 * @param member The member that must be contained in the result. 2051 */ 2052 Symbol resolveSelfContaining(DiagnosticPosition pos, 2053 Env<AttrContext> env, 2054 Symbol member, 2055 boolean isSuperCall) { 2056 Name name = names._this; 2057 Env<AttrContext> env1 = isSuperCall ? env.outer : env; 2058 boolean staticOnly = false; 2059 if (env1 != null) { 2060 while (env1 != null && env1.outer != null) { 2061 if (isStatic(env1)) staticOnly = true; 2062 if (env1.enclClass.sym.isSubClass(member.owner, types)) { 2063 Symbol sym = env1.info.scope.lookup(name).sym; 2064 if (sym != null) { 2065 if (staticOnly) sym = new StaticError(sym); 2066 return access(sym, pos, env.enclClass.sym.type, 2067 name, true); 2068 } 2069 } 2070 if ((env1.enclClass.sym.flags() & STATIC) != 0) 2071 staticOnly = true; 2072 env1 = env1.outer; 2073 } 2074 } 2075 log.error(pos, "encl.class.required", member); 2076 return syms.errSymbol; 2077 } 2078 2079 /** 2080 * Resolve an appropriate implicit this instance for t's container. 2081 * JLS 8.8.5.1 and 15.9.2 2082 */ 2083 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) { 2084 return resolveImplicitThis(pos, env, t, false); 2085 } 2086 2087 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) { 2088 Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0) 2089 ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) 2090 : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; 2091 if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) 2092 log.error(pos, "cant.ref.before.ctor.called", "this"); 2093 return thisType; 2094 } 2095 2096 /* *************************************************************************** 2097 * ResolveError classes, indicating error situations when accessing symbols 2098 ****************************************************************************/ 2099 2100 //used by TransTypes when checking target type of synthetic cast 2101 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) { 2102 AccessError error = new AccessError(env, env.enclClass.type, type.tsym); 2103 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null); 2104 } 2105 //where 2106 private void logResolveError(ResolveError error, 2107 DiagnosticPosition pos, 2108 Symbol location, 2109 Type site, 2110 Name name, 2111 List<Type> argtypes, 2112 List<Type> typeargtypes) { 2113 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 2114 pos, location, site, name, argtypes, typeargtypes); 2115 if (d != null) { 2116 d.setFlag(DiagnosticFlag.RESOLVE_ERROR); 2117 log.report(d); 2118 } 2119 } 2120 2121 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); 2122 2123 public Object methodArguments(List<Type> argtypes) { 2124 return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes; 2125 } 2126 2127 /** 2128 * Root class for resolution errors. Subclass of ResolveError 2129 * represent a different kinds of resolution error - as such they must 2130 * specify how they map into concrete compiler diagnostics. 2131 */ 2132 private abstract class ResolveError extends Symbol { 2133 2134 /** The name of the kind of error, for debugging only. */ 2135 final String debugName; 2136 2137 ResolveError(int kind, String debugName) { 2138 super(kind, 0, null, null, null); 2139 this.debugName = debugName; 2140 } 2141 2142 @Override 2143 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 2144 throw new AssertionError(); 2145 } 2146 2147 @Override 2148 public String toString() { 2149 return debugName; 2150 } 2151 2152 @Override 2153 public boolean exists() { 2154 return false; 2155 } 2156 2157 /** 2158 * Create an external representation for this erroneous symbol to be 2159 * used during attribution - by default this returns the symbol of a 2160 * brand new error type which stores the original type found 2161 * during resolution. 2162 * 2163 * @param name the name used during resolution 2164 * @param location the location from which the symbol is accessed 2165 */ 2166 protected Symbol access(Name name, TypeSymbol location) { 2167 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 2168 } 2169 2170 /** 2171 * Create a diagnostic representing this resolution error. 2172 * 2173 * @param dkind The kind of the diagnostic to be created (e.g error). 2174 * @param pos The position to be used for error reporting. 2175 * @param site The original type from where the selection took place. 2176 * @param name The name of the symbol to be resolved. 2177 * @param argtypes The invocation's value arguments, 2178 * if we looked for a method. 2179 * @param typeargtypes The invocation's type arguments, 2180 * if we looked for a method. 2181 */ 2182 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2183 DiagnosticPosition pos, 2184 Symbol location, 2185 Type site, 2186 Name name, 2187 List<Type> argtypes, 2188 List<Type> typeargtypes); 2189 2190 /** 2191 * A name designates an operator if it consists 2192 * of a non-empty sequence of operator symbols +-~!/*%&|^<>= 2193 */ 2194 boolean isOperator(Name name) { 2195 int i = 0; 2196 while (i < name.getByteLength() && 2197 "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++; 2198 return i > 0 && i == name.getByteLength(); 2199 } 2200 } 2201 2202 /** 2203 * This class is the root class of all resolution errors caused by 2204 * an invalid symbol being found during resolution. 2205 */ 2206 abstract class InvalidSymbolError extends ResolveError { 2207 2208 /** The invalid symbol found during resolution */ 2209 Symbol sym; 2210 2211 InvalidSymbolError(int kind, Symbol sym, String debugName) { 2212 super(kind, debugName); 2213 this.sym = sym; 2214 } 2215 2216 @Override 2217 public boolean exists() { 2218 return true; 2219 } 2220 2221 @Override 2222 public String toString() { 2223 return super.toString() + " wrongSym=" + sym; 2224 } 2225 2226 @Override 2227 public Symbol access(Name name, TypeSymbol location) { 2228 if (sym.kind >= AMBIGUOUS) 2229 return ((ResolveError)sym).access(name, location); 2230 else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0) 2231 return types.createErrorType(name, location, sym.type).tsym; 2232 else 2233 return sym; 2234 } 2235 } 2236 2237 /** 2238 * InvalidSymbolError error class indicating that a symbol matching a 2239 * given name does not exists in a given site. 2240 */ 2241 class SymbolNotFoundError extends ResolveError { 2242 2243 SymbolNotFoundError(int kind) { 2244 super(kind, "symbol not found error"); 2245 } 2246 2247 @Override 2248 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2249 DiagnosticPosition pos, 2250 Symbol location, 2251 Type site, 2252 Name name, 2253 List<Type> argtypes, 2254 List<Type> typeargtypes) { 2255 argtypes = argtypes == null ? List.<Type>nil() : argtypes; 2256 typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes; 2257 if (name == names.error) 2258 return null; 2259 2260 if (isOperator(name)) { 2261 boolean isUnaryOp = argtypes.size() == 1; 2262 String key = argtypes.size() == 1 ? 2263 "operator.cant.be.applied" : 2264 "operator.cant.be.applied.1"; 2265 Type first = argtypes.head; 2266 Type second = !isUnaryOp ? argtypes.tail.head : null; 2267 return diags.create(dkind, log.currentSource(), pos, 2268 key, name, first, second); 2269 } 2270 boolean hasLocation = false; 2271 if (location == null) { 2272 location = site.tsym; 2273 } 2274 if (!location.name.isEmpty()) { 2275 if (location.kind == PCK && !site.tsym.exists()) { 2276 return diags.create(dkind, log.currentSource(), pos, 2277 "doesnt.exist", location); 2278 } 2279 hasLocation = !location.name.equals(names._this) && 2280 !location.name.equals(names._super); 2281 } 2282 boolean isConstructor = kind == ABSENT_MTH && 2283 name == names.table.names.init; 2284 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind); 2285 Name idname = isConstructor ? site.tsym.name : name; 2286 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); 2287 if (hasLocation) { 2288 return diags.create(dkind, log.currentSource(), pos, 2289 errKey, kindname, idname, //symbol kindname, name 2290 typeargtypes, argtypes, //type parameters and arguments (if any) 2291 getLocationDiag(location, site)); //location kindname, type 2292 } 2293 else { 2294 return diags.create(dkind, log.currentSource(), pos, 2295 errKey, kindname, idname, //symbol kindname, name 2296 typeargtypes, argtypes); //type parameters and arguments (if any) 2297 } 2298 } 2299 //where 2300 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) { 2301 String key = "cant.resolve"; 2302 String suffix = hasLocation ? ".location" : ""; 2303 switch (kindname) { 2304 case METHOD: 2305 case CONSTRUCTOR: { 2306 suffix += ".args"; 2307 suffix += hasTypeArgs ? ".params" : ""; 2308 } 2309 } 2310 return key + suffix; 2311 } 2312 private JCDiagnostic getLocationDiag(Symbol location, Type site) { 2313 if (location.kind == VAR) { 2314 return diags.fragment("location.1", 2315 kindName(location), 2316 location, 2317 location.type); 2318 } else { 2319 return diags.fragment("location", 2320 typeKindName(site), 2321 site, 2322 null); 2323 } 2324 } 2325 } 2326 2327 /** 2328 * InvalidSymbolError error class indicating that a given symbol 2329 * (either a method, a constructor or an operand) is not applicable 2330 * given an actual arguments/type argument list. 2331 */ 2332 class InapplicableSymbolError extends ResolveError { 2333 2334 InapplicableSymbolError() { 2335 super(WRONG_MTH, "inapplicable symbol error"); 2336 } 2337 2338 protected InapplicableSymbolError(int kind, String debugName) { 2339 super(kind, debugName); 2340 } 2341 2342 @Override 2343 public String toString() { 2344 return super.toString(); 2345 } 2346 2347 @Override 2348 public boolean exists() { 2349 return true; 2350 } 2351 2352 @Override 2353 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2354 DiagnosticPosition pos, 2355 Symbol location, 2356 Type site, 2357 Name name, 2358 List<Type> argtypes, 2359 List<Type> typeargtypes) { 2360 if (name == names.error) 2361 return null; 2362 2363 if (isOperator(name)) { 2364 boolean isUnaryOp = argtypes.size() == 1; 2365 String key = argtypes.size() == 1 ? 2366 "operator.cant.be.applied" : 2367 "operator.cant.be.applied.1"; 2368 Type first = argtypes.head; 2369 Type second = !isUnaryOp ? argtypes.tail.head : null; 2370 return diags.create(dkind, log.currentSource(), pos, 2371 key, name, first, second); 2372 } 2373 else { 2374 Candidate c = errCandidate(); 2375 Symbol ws = c.sym.asMemberOf(site, types); 2376 return diags.create(dkind, log.currentSource(), pos, 2377 "cant.apply.symbol" + (c.details != null ? ".1" : ""), 2378 kindName(ws), 2379 ws.name == names.init ? ws.owner.name : ws.name, 2380 methodArguments(ws.type.getParameterTypes()), 2381 methodArguments(argtypes), 2382 kindName(ws.owner), 2383 ws.owner.type, 2384 c.details); 2385 } 2386 } 2387 2388 @Override 2389 public Symbol access(Name name, TypeSymbol location) { 2390 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 2391 } 2392 2393 protected boolean shouldReport(Candidate c) { 2394 return !c.isApplicable() && 2395 (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) || 2396 (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC)); 2397 } 2398 2399 private Candidate errCandidate() { 2400 for (Candidate c : currentResolutionContext.candidates) { 2401 if (shouldReport(c)) { 2402 return c; 2403 } 2404 } 2405 Assert.error(); 2406 return null; 2407 } 2408 } 2409 2410 /** 2411 * ResolveError error class indicating that a set of symbols 2412 * (either methods, constructors or operands) is not applicable 2413 * given an actual arguments/type argument list. 2414 */ 2415 class InapplicableSymbolsError extends InapplicableSymbolError { 2416 2417 InapplicableSymbolsError() { 2418 super(WRONG_MTHS, "inapplicable symbols"); 2419 } 2420 2421 @Override 2422 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2423 DiagnosticPosition pos, 2424 Symbol location, 2425 Type site, 2426 Name name, 2427 List<Type> argtypes, 2428 List<Type> typeargtypes) { 2429 if (currentResolutionContext.candidates.nonEmpty()) { 2430 JCDiagnostic err = diags.create(dkind, 2431 log.currentSource(), 2432 pos, 2433 "cant.apply.symbols", 2434 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), 2435 getName(), 2436 argtypes); 2437 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); 2438 } else { 2439 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, 2440 location, site, name, argtypes, typeargtypes); 2441 } 2442 } 2443 2444 //where 2445 List<JCDiagnostic> candidateDetails(Type site) { 2446 List<JCDiagnostic> details = List.nil(); 2447 for (Candidate c : currentResolutionContext.candidates) { 2448 if (!shouldReport(c)) continue; 2449 JCDiagnostic detailDiag = diags.fragment("inapplicable.method", 2450 Kinds.kindName(c.sym), 2451 c.sym.location(site, types), 2452 c.sym.asMemberOf(site, types), 2453 c.details); 2454 details = details.prepend(detailDiag); 2455 } 2456 return details.reverse(); 2457 } 2458 2459 private Name getName() { 2460 Symbol sym = currentResolutionContext.candidates.head.sym; 2461 return sym.name == names.init ? 2462 sym.owner.name : 2463 sym.name; 2464 } 2465 } 2466 2467 /** 2468 * An InvalidSymbolError error class indicating that a symbol is not 2469 * accessible from a given site 2470 */ 2471 class AccessError extends InvalidSymbolError { 2472 2473 private Env<AttrContext> env; 2474 private Type site; 2475 2476 AccessError(Symbol sym) { 2477 this(null, null, sym); 2478 } 2479 2480 AccessError(Env<AttrContext> env, Type site, Symbol sym) { 2481 super(HIDDEN, sym, "access error"); 2482 this.env = env; 2483 this.site = site; 2484 if (debugResolve) 2485 log.error("proc.messager", sym + " @ " + site + " is inaccessible."); 2486 } 2487 2488 @Override 2489 public boolean exists() { 2490 return false; 2491 } 2492 2493 @Override 2494 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2495 DiagnosticPosition pos, 2496 Symbol location, 2497 Type site, 2498 Name name, 2499 List<Type> argtypes, 2500 List<Type> typeargtypes) { 2501 if (sym.owner.type.tag == ERROR) 2502 return null; 2503 2504 if (sym.name == names.init && sym.owner != site.tsym) { 2505 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, 2506 pos, location, site, name, argtypes, typeargtypes); 2507 } 2508 else if ((sym.flags() & PUBLIC) != 0 2509 || (env != null && this.site != null 2510 && !isAccessible(env, this.site))) { 2511 return diags.create(dkind, log.currentSource(), 2512 pos, "not.def.access.class.intf.cant.access", 2513 sym, sym.location()); 2514 } 2515 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { 2516 return diags.create(dkind, log.currentSource(), 2517 pos, "report.access", sym, 2518 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 2519 sym.location()); 2520 } 2521 else { 2522 return diags.create(dkind, log.currentSource(), 2523 pos, "not.def.public.cant.access", sym, sym.location()); 2524 } 2525 } 2526 } 2527 2528 /** 2529 * InvalidSymbolError error class indicating that an instance member 2530 * has erroneously been accessed from a static context. 2531 */ 2532 class StaticError extends InvalidSymbolError { 2533 2534 StaticError(Symbol sym) { 2535 super(STATICERR, sym, "static error"); 2536 } 2537 2538 @Override 2539 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2540 DiagnosticPosition pos, 2541 Symbol location, 2542 Type site, 2543 Name name, 2544 List<Type> argtypes, 2545 List<Type> typeargtypes) { 2546 Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS) 2547 ? types.erasure(sym.type).tsym 2548 : sym); 2549 return diags.create(dkind, log.currentSource(), pos, 2550 "non-static.cant.be.ref", kindName(sym), errSym); 2551 } 2552 } 2553 2554 /** 2555 * InvalidSymbolError error class indicating that a pair of symbols 2556 * (either methods, constructors or operands) are ambiguous 2557 * given an actual arguments/type argument list. 2558 */ 2559 class AmbiguityError extends InvalidSymbolError { 2560 2561 /** The other maximally specific symbol */ 2562 Symbol sym2; 2563 2564 AmbiguityError(Symbol sym1, Symbol sym2) { 2565 super(AMBIGUOUS, sym1, "ambiguity error"); 2566 this.sym2 = sym2; 2567 } 2568 2569 @Override 2570 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2571 DiagnosticPosition pos, 2572 Symbol location, 2573 Type site, 2574 Name name, 2575 List<Type> argtypes, 2576 List<Type> typeargtypes) { 2577 AmbiguityError pair = this; 2578 while (true) { 2579 if (pair.sym.kind == AMBIGUOUS) 2580 pair = (AmbiguityError)pair.sym; 2581 else if (pair.sym2.kind == AMBIGUOUS) 2582 pair = (AmbiguityError)pair.sym2; 2583 else break; 2584 } 2585 Name sname = pair.sym.name; 2586 if (sname == names.init) sname = pair.sym.owner.name; 2587 return diags.create(dkind, log.currentSource(), 2588 pos, "ref.ambiguous", sname, 2589 kindName(pair.sym), 2590 pair.sym, 2591 pair.sym.location(site, types), 2592 kindName(pair.sym2), 2593 pair.sym2, 2594 pair.sym2.location(site, types)); 2595 } 2596 } 2597 2598 enum MethodResolutionPhase { 2599 BASIC(false, false), 2600 BOX(true, false), 2601 VARARITY(true, true); 2602 2603 boolean isBoxingRequired; 2604 boolean isVarargsRequired; 2605 2606 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { 2607 this.isBoxingRequired = isBoxingRequired; 2608 this.isVarargsRequired = isVarargsRequired; 2609 } 2610 2611 public boolean isBoxingRequired() { 2612 return isBoxingRequired; 2613 } 2614 2615 public boolean isVarargsRequired() { 2616 return isVarargsRequired; 2617 } 2618 2619 public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) { 2620 return (varargsEnabled || !isVarargsRequired) && 2621 (boxingEnabled || !isBoxingRequired); 2622 } 2623 } 2624 2625 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); 2626 2627 /** 2628 * A resolution context is used to keep track of intermediate results of 2629 * overload resolution, such as list of method that are not applicable 2630 * (used to generate more precise diagnostics) and so on. Resolution contexts 2631 * can be nested - this means that when each overload resolution routine should 2632 * work within the resolution context it created. 2633 */ 2634 class MethodResolutionContext { 2635 2636 private List<Candidate> candidates = List.nil(); 2637 2638 private Map<MethodResolutionPhase, Symbol> resolutionCache = 2639 new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class); 2640 2641 private MethodResolutionPhase step = null; 2642 2643 private boolean internalResolution = false; 2644 2645 private MethodResolutionPhase firstErroneousResolutionPhase() { 2646 MethodResolutionPhase bestSoFar = BASIC; 2647 Symbol sym = methodNotFound; 2648 List<MethodResolutionPhase> steps = methodResolutionSteps; 2649 while (steps.nonEmpty() && 2650 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 2651 sym.kind >= WRONG_MTHS) { 2652 sym = resolutionCache.get(steps.head); 2653 bestSoFar = steps.head; 2654 steps = steps.tail; 2655 } 2656 return bestSoFar; 2657 } 2658 2659 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { 2660 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); 2661 if (!candidates.contains(c)) 2662 candidates = candidates.append(c); 2663 } 2664 2665 void addApplicableCandidate(Symbol sym, Type mtype) { 2666 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype); 2667 candidates = candidates.append(c); 2668 } 2669 2670 /** 2671 * This class represents an overload resolution candidate. There are two 2672 * kinds of candidates: applicable methods and inapplicable methods; 2673 * applicable methods have a pointer to the instantiated method type, 2674 * while inapplicable candidates contain further details about the 2675 * reason why the method has been considered inapplicable. 2676 */ 2677 class Candidate { 2678 2679 final MethodResolutionPhase step; 2680 final Symbol sym; 2681 final JCDiagnostic details; 2682 final Type mtype; 2683 2684 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) { 2685 this.step = step; 2686 this.sym = sym; 2687 this.details = details; 2688 this.mtype = mtype; 2689 } 2690 2691 @Override 2692 public boolean equals(Object o) { 2693 if (o instanceof Candidate) { 2694 Symbol s1 = this.sym; 2695 Symbol s2 = ((Candidate)o).sym; 2696 if ((s1 != s2 && 2697 (s1.overrides(s2, s1.owner.type.tsym, types, false) || 2698 (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || 2699 ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) 2700 return true; 2701 } 2702 return false; 2703 } 2704 2705 boolean isApplicable() { 2706 return mtype != null; 2707 } 2708 } 2709 } 2710 2711 MethodResolutionContext currentResolutionContext = null; 2712 }