Wed, 24 Jun 2009 10:50:27 +0100
6822637: ResolveError hierarchy needs to be refactored
Summary: Break ResolveError class into a hierarchy representing different kinds of resolution errors
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Kinds.java Fri Jun 19 11:40:47 2009 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java Wed Jun 24 10:50:27 2009 +0100 1.3 @@ -95,6 +95,7 @@ 1.4 ANNOTATION("kindname.interface"), 1.5 CONSTRUCTOR("kindname.constructor"), 1.6 INTERFACE("kindname.interface"), 1.7 + ENUM("kindname.enum"), 1.8 STATIC("kindname.static"), 1.9 TYPEVAR("kindname.type.variable"), 1.10 BOUND("kindname.type.variable.bound"), 1.11 @@ -145,11 +146,15 @@ 1.12 return KindName.PACKAGE; 1.13 1.14 case ENUM: 1.15 + return KindName.ENUM; 1.16 + 1.17 case ANNOTATION_TYPE: 1.18 - case INTERFACE: 1.19 case CLASS: 1.20 return KindName.CLASS; 1.21 1.22 + case INTERFACE: 1.23 + return KindName.INTERFACE; 1.24 + 1.25 case TYPE_PARAMETER: 1.26 return KindName.TYPEVAR; 1.27 1.28 @@ -160,8 +165,10 @@ 1.29 case EXCEPTION_PARAMETER: 1.30 return KindName.VAR; 1.31 1.32 + case CONSTRUCTOR: 1.33 + return KindName.CONSTRUCTOR; 1.34 + 1.35 case METHOD: 1.36 - case CONSTRUCTOR: 1.37 case STATIC_INIT: 1.38 case INSTANCE_INIT: 1.39 return KindName.METHOD;
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jun 19 11:40:47 2009 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jun 24 10:50:27 2009 +0100 2.3 @@ -82,15 +82,15 @@ 2.4 syms = Symtab.instance(context); 2.5 2.6 varNotFound = new 2.7 - ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found"); 2.8 + SymbolNotFoundError(ABSENT_VAR); 2.9 wrongMethod = new 2.10 - ResolveError(WRONG_MTH, syms.errSymbol, "method not found"); 2.11 + InapplicableSymbolError(syms.errSymbol); 2.12 wrongMethods = new 2.13 - ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods"); 2.14 + InapplicableSymbolsError(syms.errSymbol); 2.15 methodNotFound = new 2.16 - ResolveError(ABSENT_MTH, syms.errSymbol, "method not found"); 2.17 + SymbolNotFoundError(ABSENT_MTH); 2.18 typeNotFound = new 2.19 - ResolveError(ABSENT_TYP, syms.errSymbol, "type not found"); 2.20 + SymbolNotFoundError(ABSENT_TYP); 2.21 2.22 names = Names.instance(context); 2.23 log = Log.instance(context); 2.24 @@ -110,11 +110,11 @@ 2.25 2.26 /** error symbols, which are returned when resolution fails 2.27 */ 2.28 - final ResolveError varNotFound; 2.29 - final ResolveError wrongMethod; 2.30 - final ResolveError wrongMethods; 2.31 - final ResolveError methodNotFound; 2.32 - final ResolveError typeNotFound; 2.33 + final SymbolNotFoundError varNotFound; 2.34 + final InapplicableSymbolError wrongMethod; 2.35 + final InapplicableSymbolsError wrongMethods; 2.36 + final SymbolNotFoundError methodNotFound; 2.37 + final SymbolNotFoundError typeNotFound; 2.38 2.39 /* ************************************************************************ 2.40 * Identifier resolution 2.41 @@ -710,13 +710,13 @@ 2.42 return new AmbiguityError(m1, m2); 2.43 case AMBIGUOUS: 2.44 AmbiguityError e = (AmbiguityError)m2; 2.45 - Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs); 2.46 + Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs); 2.47 Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs); 2.48 if (err1 == err2) return err1; 2.49 - if (err1 == e.sym1 && err2 == e.sym2) return m2; 2.50 + if (err1 == e.sym && err2 == e.sym2) return m2; 2.51 if (err1 instanceof AmbiguityError && 2.52 err2 instanceof AmbiguityError && 2.53 - ((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1) 2.54 + ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym) 2.55 return new AmbiguityError(m1, m2); 2.56 else 2.57 return new AmbiguityError(err1, err2); 2.58 @@ -1192,18 +1192,12 @@ 2.59 List<Type> argtypes, 2.60 List<Type> typeargtypes) { 2.61 if (sym.kind >= AMBIGUOUS) { 2.62 -// printscopes(site.tsym.members());//DEBUG 2.63 + ResolveError errSym = (ResolveError)sym; 2.64 if (!site.isErroneous() && 2.65 !Type.isErroneous(argtypes) && 2.66 (typeargtypes==null || !Type.isErroneous(typeargtypes))) 2.67 - ((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes); 2.68 - do { 2.69 - sym = ((ResolveError)sym).sym; 2.70 - } while (sym.kind >= AMBIGUOUS); 2.71 - if (sym == syms.errSymbol // preserve the symbol name through errors 2.72 - || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned 2.73 - && (sym.kind & TYP) != 0)) 2.74 - sym = types.createErrorType(name, qualified ? site.tsym : syms.noSymbol, sym.type).tsym; 2.75 + logResolveError(errSym, pos, site, name, argtypes, typeargtypes); 2.76 + sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol); 2.77 } 2.78 return sym; 2.79 } 2.80 @@ -1583,7 +1577,19 @@ 2.81 2.82 public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) { 2.83 AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym); 2.84 - error.report(log, tree.pos(), type.getEnclosingType(), null, null, null); 2.85 + logResolveError(error, tree.pos(), type.getEnclosingType(), null, null, null); 2.86 + } 2.87 + //where 2.88 + private void logResolveError(ResolveError error, 2.89 + DiagnosticPosition pos, 2.90 + Type site, 2.91 + Name name, 2.92 + List<Type> argtypes, 2.93 + List<Type> typeargtypes) { 2.94 + JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 2.95 + pos, site, name, argtypes, typeargtypes); 2.96 + if (d != null) 2.97 + log.report(d); 2.98 } 2.99 2.100 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); 2.101 @@ -1592,152 +1598,71 @@ 2.102 return argtypes.isEmpty() ? noArgs : argtypes; 2.103 } 2.104 2.105 - /** Root class for resolve errors. 2.106 - * Instances of this class indicate "Symbol not found". 2.107 - * Instances of subclass indicate other errors. 2.108 + /** 2.109 + * Root class for resolution errors. Subclass of ResolveError 2.110 + * represent a different kinds of resolution error - as such they must 2.111 + * specify how they map into concrete compiler diagnostics. 2.112 */ 2.113 - private class ResolveError extends Symbol { 2.114 + private abstract class ResolveError extends Symbol { 2.115 2.116 - ResolveError(int kind, Symbol sym, String debugName) { 2.117 + /** The name of the kind of error, for debugging only. */ 2.118 + final String debugName; 2.119 + 2.120 + ResolveError(int kind, String debugName) { 2.121 super(kind, 0, null, null, null); 2.122 this.debugName = debugName; 2.123 - this.sym = sym; 2.124 } 2.125 2.126 - /** The name of the kind of error, for debugging only. 2.127 - */ 2.128 - final String debugName; 2.129 - 2.130 - /** The symbol that was determined by resolution, or errSymbol if none 2.131 - * was found. 2.132 - */ 2.133 - final Symbol sym; 2.134 - 2.135 - /** The symbol that was a close mismatch, or null if none was found. 2.136 - * wrongSym is currently set if a simgle method with the correct name, but 2.137 - * the wrong parameters was found. 2.138 - */ 2.139 - Symbol wrongSym; 2.140 - 2.141 - /** An auxiliary explanation set in case of instantiation errors. 2.142 - */ 2.143 - JCDiagnostic explanation; 2.144 - 2.145 - 2.146 + @Override 2.147 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 2.148 throw new AssertionError(); 2.149 } 2.150 2.151 - /** Print the (debug only) name of the kind of error. 2.152 - */ 2.153 + @Override 2.154 public String toString() { 2.155 - return debugName + " wrongSym=" + wrongSym + " explanation=" + explanation; 2.156 + return debugName; 2.157 } 2.158 2.159 - /** Update wrongSym and explanation and return this. 2.160 - */ 2.161 - ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) { 2.162 - this.wrongSym = sym; 2.163 - this.explanation = explanation; 2.164 - return this; 2.165 + @Override 2.166 + public boolean exists() { 2.167 + return false; 2.168 } 2.169 2.170 - /** Update wrongSym and return this. 2.171 + /** 2.172 + * Create an external representation for this erroneous symbol to be 2.173 + * used during attribution - by default this returns the symbol of a 2.174 + * brand new error type which stores the original type found 2.175 + * during resolution. 2.176 + * 2.177 + * @param name the name used during resolution 2.178 + * @param location the location from which the symbol is accessed 2.179 */ 2.180 - ResolveError setWrongSym(Symbol sym) { 2.181 - this.wrongSym = sym; 2.182 - this.explanation = null; 2.183 - return this; 2.184 + protected Symbol access(Name name, TypeSymbol location) { 2.185 + return types.createErrorType(name, location, syms.errSymbol.type).tsym; 2.186 } 2.187 2.188 - public boolean exists() { 2.189 - switch (kind) { 2.190 - case HIDDEN: 2.191 - case ABSENT_VAR: 2.192 - case ABSENT_MTH: 2.193 - case ABSENT_TYP: 2.194 - return false; 2.195 - default: 2.196 - return true; 2.197 - } 2.198 - } 2.199 + /** 2.200 + * Create a diagnostic representing this resolution error. 2.201 + * 2.202 + * @param dkind The kind of the diagnostic to be created (e.g error). 2.203 + * @param pos The position to be used for error reporting. 2.204 + * @param site The original type from where the selection took place. 2.205 + * @param name The name of the symbol to be resolved. 2.206 + * @param argtypes The invocation's value arguments, 2.207 + * if we looked for a method. 2.208 + * @param typeargtypes The invocation's type arguments, 2.209 + * if we looked for a method. 2.210 + */ 2.211 + abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.212 + DiagnosticPosition pos, 2.213 + Type site, 2.214 + Name name, 2.215 + List<Type> argtypes, 2.216 + List<Type> typeargtypes); 2.217 2.218 - /** Report error. 2.219 - * @param log The error log to be used for error reporting. 2.220 - * @param pos The position to be used for error reporting. 2.221 - * @param site The original type from where the selection took place. 2.222 - * @param name The name of the symbol to be resolved. 2.223 - * @param argtypes The invocation's value arguments, 2.224 - * if we looked for a method. 2.225 - * @param typeargtypes The invocation's type arguments, 2.226 - * if we looked for a method. 2.227 - */ 2.228 - void report(Log log, DiagnosticPosition pos, Type site, Name name, 2.229 - List<Type> argtypes, List<Type> typeargtypes) { 2.230 - if (argtypes == null) 2.231 - argtypes = List.nil(); 2.232 - if (typeargtypes == null) 2.233 - typeargtypes = List.nil(); 2.234 - if (name != names.error) { 2.235 - KindName kindname = absentKind(kind); 2.236 - Name idname = name; 2.237 - if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) { 2.238 - if (isOperator(name)) { 2.239 - log.error(pos, "operator.cant.be.applied", 2.240 - name, argtypes); 2.241 - return; 2.242 - } 2.243 - if (name == names.init) { 2.244 - kindname = KindName.CONSTRUCTOR; 2.245 - idname = site.tsym.name; 2.246 - } 2.247 - } 2.248 - if (kind == WRONG_MTH) { 2.249 - Symbol ws = wrongSym.asMemberOf(site, types); 2.250 - log.error(pos, 2.251 - "cant.apply.symbol" + (explanation != null ? ".1" : ""), 2.252 - kindname, 2.253 - ws.name == names.init ? ws.owner.name : ws.name, 2.254 - methodArguments(ws.type.getParameterTypes()), 2.255 - methodArguments(argtypes), 2.256 - kindName(ws.owner), 2.257 - ws.owner.type, 2.258 - explanation); 2.259 - } else if (!site.tsym.name.isEmpty()) { 2.260 - if (site.tsym.kind == PCK && !site.tsym.exists()) 2.261 - log.error(pos, "doesnt.exist", site.tsym); 2.262 - else { 2.263 - String errKey = getErrorKey("cant.resolve.location", 2.264 - argtypes, typeargtypes, 2.265 - kindname); 2.266 - log.error(pos, errKey, kindname, idname, //symbol kindname, name 2.267 - typeargtypes, argtypes, //type parameters and arguments (if any) 2.268 - typeKindName(site), site); //location kindname, type 2.269 - } 2.270 - } else { 2.271 - String errKey = getErrorKey("cant.resolve", 2.272 - argtypes, typeargtypes, 2.273 - kindname); 2.274 - log.error(pos, errKey, kindname, idname, //symbol kindname, name 2.275 - typeargtypes, argtypes); //type parameters and arguments (if any) 2.276 - } 2.277 - } 2.278 - } 2.279 - //where 2.280 - String getErrorKey(String key, List<Type> argtypes, List<Type> typeargtypes, KindName kindname) { 2.281 - String suffix = ""; 2.282 - switch (kindname) { 2.283 - case METHOD: 2.284 - case CONSTRUCTOR: { 2.285 - suffix += ".args"; 2.286 - suffix += typeargtypes.nonEmpty() ? ".params" : ""; 2.287 - } 2.288 - } 2.289 - return key + suffix; 2.290 - } 2.291 - 2.292 - /** A name designates an operator if it consists 2.293 - * of a non-empty sequence of operator symbols +-~!/*%&|^<>= 2.294 + /** 2.295 + * A name designates an operator if it consists 2.296 + * of a non-empty sequence of operator symbols +-~!/*%&|^<>= 2.297 */ 2.298 boolean isOperator(Name name) { 2.299 int i = 0; 2.300 @@ -1747,9 +1672,206 @@ 2.301 } 2.302 } 2.303 2.304 - /** Resolve error class indicating that a symbol is not accessible. 2.305 + /** 2.306 + * This class is the root class of all resolution errors caused by 2.307 + * an invalid symbol being found during resolution. 2.308 */ 2.309 - class AccessError extends ResolveError { 2.310 + abstract class InvalidSymbolError extends ResolveError { 2.311 + 2.312 + /** The invalid symbol found during resolution */ 2.313 + Symbol sym; 2.314 + 2.315 + InvalidSymbolError(int kind, Symbol sym, String debugName) { 2.316 + super(kind, debugName); 2.317 + this.sym = sym; 2.318 + } 2.319 + 2.320 + @Override 2.321 + public boolean exists() { 2.322 + return true; 2.323 + } 2.324 + 2.325 + @Override 2.326 + public String toString() { 2.327 + return super.toString() + " wrongSym=" + sym; 2.328 + } 2.329 + 2.330 + @Override 2.331 + public Symbol access(Name name, TypeSymbol location) { 2.332 + if (sym.kind >= AMBIGUOUS) 2.333 + return ((ResolveError)sym).access(name, location); 2.334 + else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0) 2.335 + return types.createErrorType(name, location, sym.type).tsym; 2.336 + else 2.337 + return sym; 2.338 + } 2.339 + } 2.340 + 2.341 + /** 2.342 + * InvalidSymbolError error class indicating that a symbol matching a 2.343 + * given name does not exists in a given site. 2.344 + */ 2.345 + class SymbolNotFoundError extends ResolveError { 2.346 + 2.347 + SymbolNotFoundError(int kind) { 2.348 + super(kind, "symbol not found error"); 2.349 + } 2.350 + 2.351 + @Override 2.352 + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.353 + DiagnosticPosition pos, 2.354 + Type site, 2.355 + Name name, 2.356 + List<Type> argtypes, 2.357 + List<Type> typeargtypes) { 2.358 + argtypes = argtypes == null ? List.<Type>nil() : argtypes; 2.359 + typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes; 2.360 + if (name == names.error) 2.361 + return null; 2.362 + 2.363 + if (isOperator(name)) { 2.364 + return diags.create(dkind, false, log.currentSource(), pos, 2.365 + "operator.cant.be.applied", name, argtypes); 2.366 + } 2.367 + boolean hasLocation = false; 2.368 + if (!site.tsym.name.isEmpty()) { 2.369 + if (site.tsym.kind == PCK && !site.tsym.exists()) { 2.370 + return diags.create(dkind, false, log.currentSource(), pos, 2.371 + "doesnt.exist", site.tsym); 2.372 + } 2.373 + hasLocation = true; 2.374 + } 2.375 + boolean isConstructor = kind == ABSENT_MTH && 2.376 + name == names.table.names.init; 2.377 + KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind); 2.378 + Name idname = isConstructor ? site.tsym.name : name; 2.379 + String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); 2.380 + if (hasLocation) { 2.381 + return diags.create(dkind, false, log.currentSource(), pos, 2.382 + errKey, kindname, idname, //symbol kindname, name 2.383 + typeargtypes, argtypes, //type parameters and arguments (if any) 2.384 + typeKindName(site), site); //location kindname, type 2.385 + } 2.386 + else { 2.387 + return diags.create(dkind, false, log.currentSource(), pos, 2.388 + errKey, kindname, idname, //symbol kindname, name 2.389 + typeargtypes, argtypes); //type parameters and arguments (if any) 2.390 + } 2.391 + } 2.392 + //where 2.393 + private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) { 2.394 + String key = "cant.resolve"; 2.395 + String suffix = hasLocation ? ".location" : ""; 2.396 + switch (kindname) { 2.397 + case METHOD: 2.398 + case CONSTRUCTOR: { 2.399 + suffix += ".args"; 2.400 + suffix += hasTypeArgs ? ".params" : ""; 2.401 + } 2.402 + } 2.403 + return key + suffix; 2.404 + } 2.405 + } 2.406 + 2.407 + /** 2.408 + * InvalidSymbolError error class indicating that a given symbol 2.409 + * (either a method, a constructor or an operand) is not applicable 2.410 + * given an actual arguments/type argument list. 2.411 + */ 2.412 + class InapplicableSymbolError extends InvalidSymbolError { 2.413 + 2.414 + /** An auxiliary explanation set in case of instantiation errors. */ 2.415 + JCDiagnostic explanation; 2.416 + 2.417 + InapplicableSymbolError(Symbol sym) { 2.418 + super(WRONG_MTH, sym, "inapplicable symbol error"); 2.419 + } 2.420 + 2.421 + /** Update sym and explanation and return this. 2.422 + */ 2.423 + InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) { 2.424 + this.sym = sym; 2.425 + this.explanation = explanation; 2.426 + return this; 2.427 + } 2.428 + 2.429 + /** Update sym and return this. 2.430 + */ 2.431 + InapplicableSymbolError setWrongSym(Symbol sym) { 2.432 + this.sym = sym; 2.433 + this.explanation = null; 2.434 + return this; 2.435 + } 2.436 + 2.437 + @Override 2.438 + public String toString() { 2.439 + return super.toString() + " explanation=" + explanation; 2.440 + } 2.441 + 2.442 + @Override 2.443 + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.444 + DiagnosticPosition pos, 2.445 + Type site, 2.446 + Name name, 2.447 + List<Type> argtypes, 2.448 + List<Type> typeargtypes) { 2.449 + if (name == names.error) 2.450 + return null; 2.451 + 2.452 + if (isOperator(name)) { 2.453 + return diags.create(dkind, false, log.currentSource(), 2.454 + pos, "operator.cant.be.applied", name, argtypes); 2.455 + } 2.456 + else { 2.457 + Symbol ws = sym.asMemberOf(site, types); 2.458 + return diags.create(dkind, false, log.currentSource(), pos, 2.459 + "cant.apply.symbol" + (explanation != null ? ".1" : ""), 2.460 + kindName(ws), 2.461 + ws.name == names.init ? ws.owner.name : ws.name, 2.462 + methodArguments(ws.type.getParameterTypes()), 2.463 + methodArguments(argtypes), 2.464 + kindName(ws.owner), 2.465 + ws.owner.type, 2.466 + explanation); 2.467 + } 2.468 + } 2.469 + 2.470 + @Override 2.471 + public Symbol access(Name name, TypeSymbol location) { 2.472 + return types.createErrorType(name, location, syms.errSymbol.type).tsym; 2.473 + } 2.474 + } 2.475 + 2.476 + /** 2.477 + * ResolveError error class indicating that a set of symbols 2.478 + * (either methods, constructors or operands) is not applicable 2.479 + * given an actual arguments/type argument list. 2.480 + */ 2.481 + class InapplicableSymbolsError extends ResolveError { 2.482 + InapplicableSymbolsError(Symbol sym) { 2.483 + super(WRONG_MTHS, "inapplicable symbols"); 2.484 + } 2.485 + 2.486 + @Override 2.487 + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.488 + DiagnosticPosition pos, 2.489 + Type site, 2.490 + Name name, 2.491 + List<Type> argtypes, 2.492 + List<Type> typeargtypes) { 2.493 + return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, 2.494 + site, name, argtypes, typeargtypes); 2.495 + } 2.496 + } 2.497 + 2.498 + /** 2.499 + * An InvalidSymbolError error class indicating that a symbol is not 2.500 + * accessible from a given site 2.501 + */ 2.502 + class AccessError extends InvalidSymbolError { 2.503 + 2.504 + private Env<AttrContext> env; 2.505 + private Type site; 2.506 2.507 AccessError(Symbol sym) { 2.508 this(null, null, sym); 2.509 @@ -1763,111 +1885,107 @@ 2.510 log.error("proc.messager", sym + " @ " + site + " is inaccessible."); 2.511 } 2.512 2.513 - private Env<AttrContext> env; 2.514 - private Type site; 2.515 + @Override 2.516 + public boolean exists() { 2.517 + return false; 2.518 + } 2.519 2.520 - /** Report error. 2.521 - * @param log The error log to be used for error reporting. 2.522 - * @param pos The position to be used for error reporting. 2.523 - * @param site The original type from where the selection took place. 2.524 - * @param name The name of the symbol to be resolved. 2.525 - * @param argtypes The invocation's value arguments, 2.526 - * if we looked for a method. 2.527 - * @param typeargtypes The invocation's type arguments, 2.528 - * if we looked for a method. 2.529 - */ 2.530 - void report(Log log, DiagnosticPosition pos, Type site, Name name, 2.531 - List<Type> argtypes, List<Type> typeargtypes) { 2.532 - if (sym.owner.type.tag != ERROR) { 2.533 - if (sym.name == names.init && sym.owner != site.tsym) 2.534 - new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report( 2.535 - log, pos, site, name, argtypes, typeargtypes); 2.536 - if ((sym.flags() & PUBLIC) != 0 2.537 - || (env != null && this.site != null 2.538 - && !isAccessible(env, this.site))) 2.539 - log.error(pos, "not.def.access.class.intf.cant.access", 2.540 - sym, sym.location()); 2.541 - else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) 2.542 - log.error(pos, "report.access", sym, 2.543 - asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 2.544 - sym.location()); 2.545 - else 2.546 - log.error(pos, "not.def.public.cant.access", 2.547 - sym, sym.location()); 2.548 + @Override 2.549 + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.550 + DiagnosticPosition pos, 2.551 + Type site, 2.552 + Name name, 2.553 + List<Type> argtypes, 2.554 + List<Type> typeargtypes) { 2.555 + if (sym.owner.type.tag == ERROR) 2.556 + return null; 2.557 + 2.558 + if (sym.name == names.init && sym.owner != site.tsym) { 2.559 + return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, 2.560 + pos, site, name, argtypes, typeargtypes); 2.561 + } 2.562 + else if ((sym.flags() & PUBLIC) != 0 2.563 + || (env != null && this.site != null 2.564 + && !isAccessible(env, this.site))) { 2.565 + return diags.create(dkind, false, log.currentSource(), 2.566 + pos, "not.def.access.class.intf.cant.access", 2.567 + sym, sym.location()); 2.568 + } 2.569 + else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { 2.570 + return diags.create(dkind, false, log.currentSource(), 2.571 + pos, "report.access", sym, 2.572 + asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 2.573 + sym.location()); 2.574 + } 2.575 + else { 2.576 + return diags.create(dkind, false, log.currentSource(), 2.577 + pos, "not.def.public.cant.access", sym, sym.location()); 2.578 } 2.579 } 2.580 } 2.581 2.582 - /** Resolve error class indicating that an instance member was accessed 2.583 - * from a static context. 2.584 + /** 2.585 + * InvalidSymbolError error class indicating that an instance member 2.586 + * has erroneously been accessed from a static context. 2.587 */ 2.588 - class StaticError extends ResolveError { 2.589 + class StaticError extends InvalidSymbolError { 2.590 + 2.591 StaticError(Symbol sym) { 2.592 super(STATICERR, sym, "static error"); 2.593 } 2.594 2.595 - /** Report error. 2.596 - * @param log The error log to be used for error reporting. 2.597 - * @param pos The position to be used for error reporting. 2.598 - * @param site The original type from where the selection took place. 2.599 - * @param name The name of the symbol to be resolved. 2.600 - * @param argtypes The invocation's value arguments, 2.601 - * if we looked for a method. 2.602 - * @param typeargtypes The invocation's type arguments, 2.603 - * if we looked for a method. 2.604 - */ 2.605 - void report(Log log, 2.606 - DiagnosticPosition pos, 2.607 - Type site, 2.608 - Name name, 2.609 - List<Type> argtypes, 2.610 - List<Type> typeargtypes) { 2.611 + @Override 2.612 + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.613 + DiagnosticPosition pos, 2.614 + Type site, 2.615 + Name name, 2.616 + List<Type> argtypes, 2.617 + List<Type> typeargtypes) { 2.618 Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS) 2.619 ? types.erasure(sym.type).tsym 2.620 : sym); 2.621 - log.error(pos, "non-static.cant.be.ref", 2.622 - kindName(sym), errSym); 2.623 + return diags.create(dkind, false, log.currentSource(), pos, 2.624 + "non-static.cant.be.ref", kindName(sym), errSym); 2.625 } 2.626 } 2.627 2.628 - /** Resolve error class indicating an ambiguous reference. 2.629 + /** 2.630 + * InvalidSymbolError error class indicating that a pair of symbols 2.631 + * (either methods, constructors or operands) are ambiguous 2.632 + * given an actual arguments/type argument list. 2.633 */ 2.634 - class AmbiguityError extends ResolveError { 2.635 - Symbol sym1; 2.636 + class AmbiguityError extends InvalidSymbolError { 2.637 + 2.638 + /** The other maximally specific symbol */ 2.639 Symbol sym2; 2.640 2.641 AmbiguityError(Symbol sym1, Symbol sym2) { 2.642 super(AMBIGUOUS, sym1, "ambiguity error"); 2.643 - this.sym1 = sym1; 2.644 this.sym2 = sym2; 2.645 } 2.646 2.647 - /** Report error. 2.648 - * @param log The error log to be used for error reporting. 2.649 - * @param pos The position to be used for error reporting. 2.650 - * @param site The original type from where the selection took place. 2.651 - * @param name The name of the symbol to be resolved. 2.652 - * @param argtypes The invocation's value arguments, 2.653 - * if we looked for a method. 2.654 - * @param typeargtypes The invocation's type arguments, 2.655 - * if we looked for a method. 2.656 - */ 2.657 - void report(Log log, DiagnosticPosition pos, Type site, Name name, 2.658 - List<Type> argtypes, List<Type> typeargtypes) { 2.659 + @Override 2.660 + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2.661 + DiagnosticPosition pos, 2.662 + Type site, 2.663 + Name name, 2.664 + List<Type> argtypes, 2.665 + List<Type> typeargtypes) { 2.666 AmbiguityError pair = this; 2.667 while (true) { 2.668 - if (pair.sym1.kind == AMBIGUOUS) 2.669 - pair = (AmbiguityError)pair.sym1; 2.670 + if (pair.sym.kind == AMBIGUOUS) 2.671 + pair = (AmbiguityError)pair.sym; 2.672 else if (pair.sym2.kind == AMBIGUOUS) 2.673 pair = (AmbiguityError)pair.sym2; 2.674 else break; 2.675 } 2.676 - Name sname = pair.sym1.name; 2.677 - if (sname == names.init) sname = pair.sym1.owner.name; 2.678 - log.error(pos, "ref.ambiguous", sname, 2.679 - kindName(pair.sym1), 2.680 - pair.sym1, 2.681 - pair.sym1.location(site, types), 2.682 + Name sname = pair.sym.name; 2.683 + if (sname == names.init) sname = pair.sym.owner.name; 2.684 + return diags.create(dkind, false, log.currentSource(), 2.685 + pos, "ref.ambiguous", sname, 2.686 + kindName(pair.sym), 2.687 + pair.sym, 2.688 + pair.sym.location(site, types), 2.689 kindName(pair.sym2), 2.690 pair.sym2, 2.691 pair.sym2.location(site, types));
3.1 --- a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Fri Jun 19 11:40:47 2009 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Wed Jun 24 10:50:27 2009 +0100 3.3 @@ -83,7 +83,7 @@ 3.4 */ 3.5 public JCDiagnostic error( 3.6 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { 3.7 - return new JCDiagnostic(formatter, ERROR, true, source, pos, qualify(ERROR, key), args); 3.8 + return create(ERROR, true, source, pos, key, args); 3.9 } 3.10 3.11 /** 3.12 @@ -96,7 +96,7 @@ 3.13 */ 3.14 public JCDiagnostic mandatoryWarning( 3.15 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { 3.16 - return new JCDiagnostic(formatter, WARNING, true, source, pos, qualify(WARNING, key), args); 3.17 + return create(WARNING, true, source, pos, key, args); 3.18 } 3.19 3.20 /** 3.21 @@ -108,7 +108,7 @@ 3.22 */ 3.23 public JCDiagnostic warning( 3.24 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { 3.25 - return new JCDiagnostic(formatter, WARNING, false, source, pos, qualify(WARNING, key), args); 3.26 + return create(WARNING, false, source, pos, key, args); 3.27 } 3.28 3.29 /** 3.30 @@ -118,7 +118,7 @@ 3.31 * @see MandatoryWarningHandler 3.32 */ 3.33 public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) { 3.34 - return new JCDiagnostic(formatter, NOTE, true, source, null, qualify(NOTE, key), args); 3.35 + return create(NOTE, true, source, null, key, args); 3.36 } 3.37 3.38 /** 3.39 @@ -127,7 +127,7 @@ 3.40 * @param args Fields of the error message. 3.41 */ 3.42 public JCDiagnostic note(String key, Object... args) { 3.43 - return note(null, null, key, args); 3.44 + return create(NOTE, false, null, null, key, args); 3.45 } 3.46 3.47 /** 3.48 @@ -139,7 +139,7 @@ 3.49 */ 3.50 public JCDiagnostic note( 3.51 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { 3.52 - return new JCDiagnostic(formatter, NOTE, false, source, pos, qualify(NOTE, key), args); 3.53 + return create(NOTE, false, source, pos, key, args); 3.54 } 3.55 3.56 /** 3.57 @@ -148,7 +148,21 @@ 3.58 * @param args Fields of the error message. 3.59 */ 3.60 public JCDiagnostic fragment(String key, Object... args) { 3.61 - return new JCDiagnostic(formatter, FRAGMENT, false, null, null, qualify(FRAGMENT, key), args); 3.62 + return create(FRAGMENT, false, null, null, key, args); 3.63 + } 3.64 + 3.65 + /** 3.66 + * Create a new diagnostic of the given kind. 3.67 + * @param kind The diagnostic kind 3.68 + * @param isMandatory is diagnostic mandatory? 3.69 + * @param source The source of the compilation unit, if any, in which to report the note. 3.70 + * @param pos The source position at which to report the note. 3.71 + * @param key The key for the localized error message. 3.72 + * @param args Fields of the error message. 3.73 + */ 3.74 + public JCDiagnostic create( 3.75 + DiagnosticType kind, boolean isMandatory, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { 3.76 + return new JCDiagnostic(formatter, kind, isMandatory, source, pos, qualify(kind, key), args); 3.77 } 3.78 3.79 protected String qualify(DiagnosticType t, String key) {