6822637: ResolveError hierarchy needs to be refactored

Wed, 24 Jun 2009 10:50:27 +0100

author
mcimadamore
date
Wed, 24 Jun 2009 10:50:27 +0100
changeset 302
18e0269f25e3
parent 300
ed989c347b3c
child 303
8ec37cf2b37e

6822637: ResolveError hierarchy needs to be refactored
Summary: Break ResolveError class into a hierarchy representing different kinds of resolution errors
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/code/Kinds.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java file | annotate | diff | comparison | revisions
     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) {

mercurial