Source Code Cross Referenced for Check.java in  » 6.0-JDK-Modules-com.sun » tools » com » sun » tools » javac » comp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun » tools » com.sun.tools.javac.comp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.tools.javac.comp;
0027:
0028:        import java.util.*;
0029:        import java.util.Set;
0030:
0031:        import com.sun.tools.javac.code.*;
0032:        import com.sun.tools.javac.jvm.*;
0033:        import com.sun.tools.javac.tree.*;
0034:        import com.sun.tools.javac.util.*;
0035:        import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
0036:        import com.sun.tools.javac.util.List;
0037:
0038:        import com.sun.tools.javac.tree.JCTree.*;
0039:        import com.sun.tools.javac.code.Lint;
0040:        import com.sun.tools.javac.code.Lint.LintCategory;
0041:        import com.sun.tools.javac.code.Type.*;
0042:        import com.sun.tools.javac.code.Symbol.*;
0043:
0044:        import static com.sun.tools.javac.code.Flags.*;
0045:        import static com.sun.tools.javac.code.Kinds.*;
0046:        import static com.sun.tools.javac.code.TypeTags.*;
0047:
0048:        /** Type checking helper class for the attribution phase.
0049:         *
0050:         *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
0051:         *  you write code that depends on this, you do so at your own risk.
0052:         *  This code and its internal interfaces are subject to change or
0053:         *  deletion without notice.</b>
0054:         */
0055:        @Version("@(#)Check.java	1.174 07/06/14")
0056:        public class Check {
0057:            protected static final Context.Key<Check> checkKey = new Context.Key<Check>();
0058:
0059:            private final Name.Table names;
0060:            private final Log log;
0061:            private final Symtab syms;
0062:            private final Infer infer;
0063:            private final Target target;
0064:            private final Source source;
0065:            private final Types types;
0066:            private final boolean skipAnnotations;
0067:            private final TreeInfo treeinfo;
0068:
0069:            // The set of lint options currently in effect. It is initialized
0070:            // from the context, and then is set/reset as needed by Attr as it 
0071:            // visits all the various parts of the trees during attribution.
0072:            private Lint lint;
0073:
0074:            public static Check instance(Context context) {
0075:                Check instance = context.get(checkKey);
0076:                if (instance == null)
0077:                    instance = new Check(context);
0078:                return instance;
0079:            }
0080:
0081:            protected Check(Context context) {
0082:                context.put(checkKey, this );
0083:
0084:                names = Name.Table.instance(context);
0085:                log = Log.instance(context);
0086:                syms = Symtab.instance(context);
0087:                infer = Infer.instance(context);
0088:                this .types = Types.instance(context);
0089:                Options options = Options.instance(context);
0090:                target = Target.instance(context);
0091:                source = Source.instance(context);
0092:                lint = Lint.instance(context);
0093:                treeinfo = TreeInfo.instance(context);
0094:
0095:                Source source = Source.instance(context);
0096:                allowGenerics = source.allowGenerics();
0097:                allowAnnotations = source.allowAnnotations();
0098:                complexInference = options.get("-complexinference") != null;
0099:                skipAnnotations = options.get("skipAnnotations") != null;
0100:
0101:                boolean verboseDeprecated = lint
0102:                        .isEnabled(LintCategory.DEPRECATION);
0103:                boolean verboseUnchecked = lint
0104:                        .isEnabled(LintCategory.UNCHECKED);
0105:
0106:                deprecationHandler = new MandatoryWarningHandler(log,
0107:                        verboseDeprecated, "deprecated");
0108:                uncheckedHandler = new MandatoryWarningHandler(log,
0109:                        verboseUnchecked, "unchecked");
0110:            }
0111:
0112:            /** Switch: generics enabled?
0113:             */
0114:            boolean allowGenerics;
0115:
0116:            /** Switch: annotations enabled?
0117:             */
0118:            boolean allowAnnotations;
0119:
0120:            /** Switch: -complexinference option set?
0121:             */
0122:            boolean complexInference;
0123:
0124:            /** A table mapping flat names of all compiled classes in this run to their
0125:             *  symbols; maintained from outside.
0126:             */
0127:            public Map<Name, ClassSymbol> compiled = new HashMap<Name, ClassSymbol>();
0128:
0129:            /** A handler for messages about deprecated usage.
0130:             */
0131:            private MandatoryWarningHandler deprecationHandler;
0132:
0133:            /** A handler for messages about unchecked or unsafe usage.
0134:             */
0135:            private MandatoryWarningHandler uncheckedHandler;
0136:
0137:            /* *************************************************************************
0138:             * Errors and Warnings
0139:             **************************************************************************/
0140:
0141:            Lint setLint(Lint newLint) {
0142:                Lint prev = lint;
0143:                lint = newLint;
0144:                return prev;
0145:            }
0146:
0147:            /** Warn about deprecated symbol.
0148:             *  @param pos        Position to be used for error reporting.
0149:             *  @param sym        The deprecated symbol.
0150:             */
0151:            void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
0152:                if (!lint.isSuppressed(LintCategory.DEPRECATION))
0153:                    deprecationHandler.report(pos, "has.been.deprecated", sym,
0154:                            sym.location());
0155:            }
0156:
0157:            /** Warn about unchecked operation.
0158:             *  @param pos        Position to be used for error reporting.
0159:             *  @param msg        A string describing the problem.
0160:             */
0161:            public void warnUnchecked(DiagnosticPosition pos, String msg,
0162:                    Object... args) {
0163:                if (!lint.isSuppressed(LintCategory.UNCHECKED))
0164:                    uncheckedHandler.report(pos, msg, args);
0165:            }
0166:
0167:            /**
0168:             * Report any deferred diagnostics.
0169:             */
0170:            public void reportDeferredDiagnostics() {
0171:                deprecationHandler.reportDeferredDiagnostic();
0172:                uncheckedHandler.reportDeferredDiagnostic();
0173:            }
0174:
0175:            /** Report a failure to complete a class.
0176:             *  @param pos        Position to be used for error reporting.
0177:             *  @param ex         The failure to report.
0178:             */
0179:            public Type completionError(DiagnosticPosition pos,
0180:                    CompletionFailure ex) {
0181:                log.error(pos, "cant.access", ex.sym, ex.errmsg);
0182:                if (ex instanceof  ClassReader.BadClassFile)
0183:                    throw new Abort();
0184:                else
0185:                    return syms.errType;
0186:            }
0187:
0188:            /** Report a type error.
0189:             *  @param pos        Position to be used for error reporting.
0190:             *  @param problem    A string describing the error.
0191:             *  @param found      The type that was found.
0192:             *  @param req        The type that was required.
0193:             */
0194:            Type typeError(DiagnosticPosition pos, Object problem, Type found,
0195:                    Type req) {
0196:                log.error(pos, "prob.found.req", problem, found, req);
0197:                return syms.errType;
0198:            }
0199:
0200:            Type typeError(DiagnosticPosition pos, String problem, Type found,
0201:                    Type req, Object explanation) {
0202:                log.error(pos, "prob.found.req.1", problem, found, req,
0203:                        explanation);
0204:                return syms.errType;
0205:            }
0206:
0207:            /** Report an error that wrong type tag was found.
0208:             *  @param pos        Position to be used for error reporting.
0209:             *  @param required   An internationalized string describing the type tag
0210:             *                    required.
0211:             *  @param found      The type that was found.
0212:             */
0213:            Type typeTagError(DiagnosticPosition pos, Object required,
0214:                    Object found) {
0215:                log.error(pos, "type.found.req", found, required);
0216:                return syms.errType;
0217:            }
0218:
0219:            /** Report an error that symbol cannot be referenced before super
0220:             *  has been called.
0221:             *  @param pos        Position to be used for error reporting.
0222:             *  @param sym        The referenced symbol.
0223:             */
0224:            void earlyRefError(DiagnosticPosition pos, Symbol sym) {
0225:                log.error(pos, "cant.ref.before.ctor.called", sym);
0226:            }
0227:
0228:            /** Report duplicate declaration error.
0229:             */
0230:            void duplicateError(DiagnosticPosition pos, Symbol sym) {
0231:                if (!sym.type.isErroneous()) {
0232:                    log.error(pos, "already.defined", sym, sym.location());
0233:                }
0234:            }
0235:
0236:            /** Report array/varargs duplicate declaration 
0237:             */
0238:            void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1,
0239:                    Symbol sym2) {
0240:                if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
0241:                    log.error(pos, "array.and.varargs", sym1, sym2, sym2
0242:                            .location());
0243:                }
0244:            }
0245:
0246:            /* ************************************************************************
0247:             * duplicate declaration checking
0248:             *************************************************************************/
0249:
0250:            /** Check that variable does not hide variable with same name in
0251:             *	immediately enclosing local scope.
0252:             *	@param pos	     Position for error reporting.
0253:             *	@param v	     The symbol.
0254:             *	@param s	     The scope.
0255:             */
0256:            void checkTransparentVar(DiagnosticPosition pos, VarSymbol v,
0257:                    Scope s) {
0258:                if (s.next != null) {
0259:                    for (Scope.Entry e = s.next.lookup(v.name); e.scope != null
0260:                            && e.sym.owner == v.owner; e = e.next()) {
0261:                        if (e.sym.kind == VAR
0262:                                && (e.sym.owner.kind & (VAR | MTH)) != 0
0263:                                && v.name != names.error) {
0264:                            duplicateError(pos, e.sym);
0265:                            return;
0266:                        }
0267:                    }
0268:                }
0269:            }
0270:
0271:            /** Check that a class or interface does not hide a class or
0272:             *	interface with same name in immediately enclosing local scope.
0273:             *	@param pos	     Position for error reporting.
0274:             *	@param c	     The symbol.
0275:             *	@param s	     The scope.
0276:             */
0277:            void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c,
0278:                    Scope s) {
0279:                if (s.next != null) {
0280:                    for (Scope.Entry e = s.next.lookup(c.name); e.scope != null
0281:                            && e.sym.owner == c.owner; e = e.next()) {
0282:                        if (e.sym.kind == TYP
0283:                                && (e.sym.owner.kind & (VAR | MTH)) != 0
0284:                                && c.name != names.error) {
0285:                            duplicateError(pos, e.sym);
0286:                            return;
0287:                        }
0288:                    }
0289:                }
0290:            }
0291:
0292:            /** Check that class does not have the same name as one of
0293:             *	its enclosing classes, or as a class defined in its enclosing scope.
0294:             *	return true if class is unique in its enclosing scope.
0295:             *	@param pos	     Position for error reporting.
0296:             *	@param name	     The class name.
0297:             *	@param s	     The enclosing scope.
0298:             */
0299:            boolean checkUniqueClassName(DiagnosticPosition pos, Name name,
0300:                    Scope s) {
0301:                for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
0302:                    if (e.sym.kind == TYP && e.sym.name != names.error) {
0303:                        duplicateError(pos, e.sym);
0304:                        return false;
0305:                    }
0306:                }
0307:                for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
0308:                    if (sym.kind == TYP && sym.name == name
0309:                            && sym.name != names.error) {
0310:                        duplicateError(pos, sym);
0311:                        return true;
0312:                    }
0313:                }
0314:                return true;
0315:            }
0316:
0317:            /* *************************************************************************
0318:             * Class name generation
0319:             **************************************************************************/
0320:
0321:            /** Return name of local class.
0322:             *  This is of the form    <enclClass> $ n <classname>
0323:             *  where
0324:             *    enclClass is the flat name of the enclosing class,
0325:             *    classname is the simple name of the local class
0326:             */
0327:            Name localClassName(ClassSymbol c) {
0328:                for (int i = 1;; i++) {
0329:                    Name flatname = names.fromString(""
0330:                            + c.owner.enclClass().flatname
0331:                            + target.syntheticNameChar() + i + c.name);
0332:                    if (compiled.get(flatname) == null)
0333:                        return flatname;
0334:                }
0335:            }
0336:
0337:            /* *************************************************************************
0338:             * Type Checking
0339:             **************************************************************************/
0340:
0341:            /** Check that a given type is assignable to a given proto-type.
0342:             *  If it is, return the type, otherwise return errType.
0343:             *  @param pos        Position to be used for error reporting.
0344:             *  @param found      The type that was found.
0345:             *  @param req        The type that was required.
0346:             */
0347:            Type checkType(DiagnosticPosition pos, Type found, Type req) {
0348:                if (req.tag == ERROR)
0349:                    return req;
0350:                if (found.tag == FORALL)
0351:                    return instantiatePoly(pos, (ForAll) found, req,
0352:                            convertWarner(pos, found, req));
0353:                if (req.tag == NONE)
0354:                    return found;
0355:                if (types.isAssignable(found, req, convertWarner(pos, found,
0356:                        req)))
0357:                    return found;
0358:                if (found.tag <= DOUBLE && req.tag <= DOUBLE)
0359:                    return typeError(pos, JCDiagnostic
0360:                            .fragment("possible.loss.of.precision"), found, req);
0361:                if (found.isSuperBound()) {
0362:                    log.error(pos, "assignment.from.super-bound", found);
0363:                    return syms.errType;
0364:                }
0365:                if (req.isExtendsBound()) {
0366:                    log.error(pos, "assignment.to.extends-bound", req);
0367:                    return syms.errType;
0368:                }
0369:                return typeError(pos, JCDiagnostic
0370:                        .fragment("incompatible.types"), found, req);
0371:            }
0372:
0373:            /** Instantiate polymorphic type to some prototype, unless
0374:             *  prototype is `anyPoly' in which case polymorphic type
0375:             *  is returned unchanged.
0376:             */
0377:            Type instantiatePoly(DiagnosticPosition pos, ForAll t, Type pt,
0378:                    Warner warn) {
0379:                if (pt == Infer.anyPoly && complexInference) {
0380:                    return t;
0381:                } else if (pt == Infer.anyPoly || pt.tag == NONE) {
0382:                    Type newpt = t.qtype.tag <= VOID ? t.qtype
0383:                            : syms.objectType;
0384:                    return instantiatePoly(pos, t, newpt, warn);
0385:                } else if (pt.tag == ERROR) {
0386:                    return pt;
0387:                } else {
0388:                    try {
0389:                        return infer.instantiateExpr(t, pt, warn);
0390:                    } catch (Infer.NoInstanceException ex) {
0391:                        if (ex.isAmbiguous) {
0392:                            JCDiagnostic d = ex.getDiagnostic();
0393:                            log.error(pos, "undetermined.type"
0394:                                    + (d != null ? ".1" : ""), t, d);
0395:                            return syms.errType;
0396:                        } else {
0397:                            JCDiagnostic d = ex.getDiagnostic();
0398:                            return typeError(pos, JCDiagnostic.fragment(
0399:                                    "incompatible.types"
0400:                                            + (d != null ? ".1" : ""), d), t,
0401:                                    pt);
0402:                        }
0403:                    }
0404:                }
0405:            }
0406:
0407:            /** Check that a given type can be cast to a given target type.
0408:             *  Return the result of the cast.
0409:             *  @param pos        Position to be used for error reporting.
0410:             *  @param found      The type that is being cast.
0411:             *  @param req        The target type of the cast.
0412:             */
0413:            Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
0414:                if (found.tag == FORALL) {
0415:                    instantiatePoly(pos, (ForAll) found, req, castWarner(pos,
0416:                            found, req));
0417:                    return req;
0418:                } else if (types.isCastable(found, req, castWarner(pos, found,
0419:                        req))) {
0420:                    return req;
0421:                } else {
0422:                    return typeError(pos, JCDiagnostic
0423:                            .fragment("inconvertible.types"), found, req);
0424:                }
0425:            }
0426:
0427:            //where
0428:            /** Is type a type variable, or a (possibly multi-dimensional) array of
0429:             *  type variables?
0430:             */
0431:            boolean isTypeVar(Type t) {
0432:                return t.tag == TYPEVAR || t.tag == ARRAY
0433:                        && isTypeVar(types.elemtype(t));
0434:            }
0435:
0436:            /** Check that a type is within some bounds.
0437:             *
0438:             *  Used in TypeApply to verify that, e.g., X in V<X> is a valid
0439:             *  type argument.
0440:             *  @param pos           Position to be used for error reporting.
0441:             *  @param a             The type that should be bounded by bs.
0442:             *  @param bs            The bound.
0443:             */
0444:            private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
0445:                if (a.isUnbound()) {
0446:                    return;
0447:                } else if (a.tag != WILDCARD) {
0448:                    a = types.upperBound(a);
0449:                    for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
0450:                        if (!types.isSubtype(a, l.head)) {
0451:                            log.error(pos, "not.within.bounds", a);
0452:                            return;
0453:                        }
0454:                    }
0455:                } else if (a.isExtendsBound()) {
0456:                    if (!types.isCastable(bs.getUpperBound(), types
0457:                            .upperBound(a), Warner.noWarnings))
0458:                        log.error(pos, "not.within.bounds", a);
0459:                } else if (a.isSuperBound()) {
0460:                    if (types.notSoftSubtype(types.lowerBound(a), bs
0461:                            .getUpperBound()))
0462:                        log.error(pos, "not.within.bounds", a);
0463:                }
0464:            }
0465:
0466:            /** Check that type is different from 'void'.
0467:             *  @param pos           Position to be used for error reporting.
0468:             *  @param t             The type to be checked.
0469:             */
0470:            Type checkNonVoid(DiagnosticPosition pos, Type t) {
0471:                if (t.tag == VOID) {
0472:                    log.error(pos, "void.not.allowed.here");
0473:                    return syms.errType;
0474:                } else {
0475:                    return t;
0476:                }
0477:            }
0478:
0479:            /** Check that type is a class or interface type.
0480:             *  @param pos           Position to be used for error reporting.
0481:             *  @param t             The type to be checked.
0482:             */
0483:            Type checkClassType(DiagnosticPosition pos, Type t) {
0484:                if (t.tag != CLASS && t.tag != ERROR)
0485:                    return typeTagError(pos, JCDiagnostic
0486:                            .fragment("type.req.class"),
0487:                            (t.tag == TYPEVAR) ? JCDiagnostic.fragment(
0488:                                    "type.parameter", t) : t);
0489:                else
0490:                    return t;
0491:            }
0492:
0493:            /** Check that type is a class or interface type.
0494:             *  @param pos           Position to be used for error reporting.
0495:             *  @param t             The type to be checked.
0496:             *  @param noBounds    True if type bounds are illegal here.
0497:             */
0498:            Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
0499:                t = checkClassType(pos, t);
0500:                if (noBounds && t.isParameterized()) {
0501:                    List<Type> args = t.getTypeArguments();
0502:                    while (args.nonEmpty()) {
0503:                        if (args.head.tag == WILDCARD)
0504:                            return typeTagError(pos, log
0505:                                    .getLocalizedString("type.req.exact"),
0506:                                    args.head);
0507:                        args = args.tail;
0508:                    }
0509:                }
0510:                return t;
0511:            }
0512:
0513:            /** Check that type is a reifiable class, interface or array type.
0514:             *  @param pos           Position to be used for error reporting.
0515:             *  @param t             The type to be checked.
0516:             */
0517:            Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
0518:                if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR) {
0519:                    return typeTagError(pos, JCDiagnostic
0520:                            .fragment("type.req.class.array"), t);
0521:                } else if (!types.isReifiable(t)) {
0522:                    log.error(pos, "illegal.generic.type.for.instof");
0523:                    return syms.errType;
0524:                } else {
0525:                    return t;
0526:                }
0527:            }
0528:
0529:            /** Check that type is a reference type, i.e. a class, interface or array type
0530:             *  or a type variable.
0531:             *  @param pos           Position to be used for error reporting.
0532:             *  @param t             The type to be checked.
0533:             */
0534:            Type checkRefType(DiagnosticPosition pos, Type t) {
0535:                switch (t.tag) {
0536:                case CLASS:
0537:                case ARRAY:
0538:                case TYPEVAR:
0539:                case WILDCARD:
0540:                case ERROR:
0541:                    return t;
0542:                default:
0543:                    return typeTagError(pos, JCDiagnostic
0544:                            .fragment("type.req.ref"), t);
0545:                }
0546:            }
0547:
0548:            /** Check that type is a null or reference type.
0549:             *  @param pos           Position to be used for error reporting.
0550:             *  @param t             The type to be checked.
0551:             */
0552:            Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
0553:                switch (t.tag) {
0554:                case CLASS:
0555:                case ARRAY:
0556:                case TYPEVAR:
0557:                case WILDCARD:
0558:                case BOT:
0559:                case ERROR:
0560:                    return t;
0561:                default:
0562:                    return typeTagError(pos, JCDiagnostic
0563:                            .fragment("type.req.ref"), t);
0564:                }
0565:            }
0566:
0567:            /** Check that flag set does not contain elements of two conflicting sets. s
0568:             *  Return true if it doesn't.
0569:             *  @param pos           Position to be used for error reporting.
0570:             *  @param flags         The set of flags to be checked.
0571:             *  @param set1          Conflicting flags set #1.
0572:             *  @param set2          Conflicting flags set #2.
0573:             */
0574:            boolean checkDisjoint(DiagnosticPosition pos, long flags,
0575:                    long set1, long set2) {
0576:                if ((flags & set1) != 0 && (flags & set2) != 0) {
0577:                    log
0578:                            .error(pos, "illegal.combination.of.modifiers",
0579:                                    TreeInfo.flagNames(TreeInfo.firstFlag(flags
0580:                                            & set1)), TreeInfo
0581:                                            .flagNames(TreeInfo.firstFlag(flags
0582:                                                    & set2)));
0583:                    return false;
0584:                } else
0585:                    return true;
0586:            }
0587:
0588:            /** Check that given modifiers are legal for given symbol and
0589:             *  return modifiers together with any implicit modififiers for that symbol.
0590:             *  Warning: we can't use flags() here since this method
0591:             *  is called during class enter, when flags() would cause a premature
0592:             *  completion.
0593:             *  @param pos           Position to be used for error reporting.
0594:             *  @param flags         The set of modifiers given in a definition.
0595:             *  @param sym           The defined symbol.
0596:             */
0597:            long checkFlags(DiagnosticPosition pos, long flags, Symbol sym,
0598:                    JCTree tree) {
0599:                long mask;
0600:                long implicit = 0;
0601:                switch (sym.kind) {
0602:                case VAR:
0603:                    if (sym.owner.kind != TYP)
0604:                        mask = LocalVarFlags;
0605:                    else if ((sym.owner.flags_field & INTERFACE) != 0)
0606:                        mask = implicit = InterfaceVarFlags;
0607:                    else
0608:                        mask = VarFlags;
0609:                    break;
0610:                case MTH:
0611:                    if (sym.name == names.init) {
0612:                        if ((sym.owner.flags_field & ENUM) != 0) {
0613:                            // enum constructors cannot be declared public or
0614:                            // protected and must be implicitly or explicitly
0615:                            // private
0616:                            implicit = PRIVATE;
0617:                            mask = PRIVATE;
0618:                        } else
0619:                            mask = ConstructorFlags;
0620:                    } else if ((sym.owner.flags_field & INTERFACE) != 0)
0621:                        mask = implicit = InterfaceMethodFlags;
0622:                    else {
0623:                        mask = MethodFlags;
0624:                    }
0625:                    // Imply STRICTFP if owner has STRICTFP set.
0626:                    if (((flags | implicit) & Flags.ABSTRACT) == 0)
0627:                        implicit |= sym.owner.flags_field & STRICTFP;
0628:                    break;
0629:                case TYP:
0630:                    if (sym.isLocal()) {
0631:                        mask = LocalClassFlags;
0632:                        if (sym.name.len == 0) { // Anonymous class
0633:                            // Anonymous classes in static methods are themselves static;
0634:                            // that's why we admit STATIC here.
0635:                            mask |= STATIC;
0636:                            // JLS: Anonymous classes are final.
0637:                            implicit |= FINAL;
0638:                        }
0639:                        if ((sym.owner.flags_field & STATIC) == 0
0640:                                && (flags & ENUM) != 0)
0641:                            log.error(pos, "enums.must.be.static");
0642:                    } else if (sym.owner.kind == TYP) {
0643:                        mask = MemberClassFlags;
0644:                        if (sym.owner.owner.kind == PCK
0645:                                || (sym.owner.flags_field & STATIC) != 0)
0646:                            mask |= STATIC;
0647:                        else if ((flags & ENUM) != 0)
0648:                            log.error(pos, "enums.must.be.static");
0649:                        // Nested interfaces and enums are always STATIC (Spec ???)
0650:                        if ((flags & (INTERFACE | ENUM)) != 0)
0651:                            implicit = STATIC;
0652:                    } else {
0653:                        mask = ClassFlags;
0654:                    }
0655:                    // Interfaces are always ABSTRACT
0656:                    if ((flags & INTERFACE) != 0)
0657:                        implicit |= ABSTRACT;
0658:
0659:                    if ((flags & ENUM) != 0) {
0660:                        // enums can't be declared abstract or final
0661:                        mask &= ~(ABSTRACT | FINAL);
0662:                        implicit |= implicitEnumFinalFlag(tree);
0663:                    }
0664:                    // Imply STRICTFP if owner has STRICTFP set.
0665:                    implicit |= sym.owner.flags_field & STRICTFP;
0666:                    break;
0667:                default:
0668:                    throw new AssertionError();
0669:                }
0670:                long illegal = flags & StandardFlags & ~mask;
0671:                if (illegal != 0) {
0672:                    if ((illegal & INTERFACE) != 0) {
0673:                        log.error(pos, "intf.not.allowed.here");
0674:                        mask |= INTERFACE;
0675:                    } else {
0676:                        log.error(pos, "mod.not.allowed.here", TreeInfo
0677:                                .flagNames(illegal));
0678:                    }
0679:                } else if ((sym.kind == TYP ||
0680:                // ISSUE: Disallowing abstract&private is no longer appropriate
0681:                // in the presence of inner classes. Should it be deleted here?
0682:                checkDisjoint(pos, flags, ABSTRACT, PRIVATE | STATIC))
0683:                        && checkDisjoint(pos, flags, ABSTRACT | INTERFACE,
0684:                                FINAL | NATIVE | SYNCHRONIZED)
0685:                        && checkDisjoint(pos, flags, PUBLIC, PRIVATE
0686:                                | PROTECTED)
0687:                        && checkDisjoint(pos, flags, PRIVATE, PUBLIC
0688:                                | PROTECTED)
0689:                        && checkDisjoint(pos, flags, FINAL, VOLATILE)
0690:                        && (sym.kind == TYP || checkDisjoint(pos, flags,
0691:                                ABSTRACT | NATIVE, STRICTFP))) {
0692:                    // skip
0693:                }
0694:                return flags & (mask | ~StandardFlags) | implicit;
0695:            }
0696:
0697:            /** Determine if this enum should be implicitly final.
0698:             *
0699:             *  If the enum has no specialized enum contants, it is final.
0700:             *
0701:             *  If the enum does have specialized enum contants, it is
0702:             *  <i>not</i> final.
0703:             */
0704:            private long implicitEnumFinalFlag(JCTree tree) {
0705:                if (tree.getTag() != JCTree.CLASSDEF)
0706:                    return 0;
0707:                class SpecialTreeVisitor extends JCTree.Visitor {
0708:                    boolean specialized;
0709:
0710:                    SpecialTreeVisitor() {
0711:                        this .specialized = false;
0712:                    };
0713:
0714:                    public void visitTree(JCTree tree) { /* no-op */
0715:                    }
0716:
0717:                    public void visitVarDef(JCVariableDecl tree) {
0718:                        if ((tree.mods.flags & ENUM) != 0) {
0719:                            if (tree.init instanceof  JCNewClass
0720:                                    && ((JCNewClass) tree.init).def != null) {
0721:                                specialized = true;
0722:                            }
0723:                        }
0724:                    }
0725:                }
0726:
0727:                SpecialTreeVisitor sts = new SpecialTreeVisitor();
0728:                JCClassDecl cdef = (JCClassDecl) tree;
0729:                for (JCTree defs : cdef.defs) {
0730:                    defs.accept(sts);
0731:                    if (sts.specialized)
0732:                        return 0;
0733:                }
0734:                return FINAL;
0735:            }
0736:
0737:            /* *************************************************************************
0738:             * Type Validation
0739:             **************************************************************************/
0740:
0741:            /** Validate a type expression. That is,
0742:             *  check that all type arguments of a parametric type are within
0743:             *  their bounds. This must be done in a second phase after type attributon
0744:             *  since a class might have a subclass as type parameter bound. E.g:
0745:             *
0746:             *  class B<A extends C> { ... }
0747:             *  class C extends B<C> { ... }
0748:             *
0749:             *  and we can't make sure that the bound is already attributed because
0750:             *  of possible cycles.
0751:             */
0752:            private Validator validator = new Validator();
0753:
0754:            /** Visitor method: Validate a type expression, if it is not null, catching
0755:             *  and reporting any completion failures.
0756:             */
0757:            void validate(JCTree tree) {
0758:                try {
0759:                    if (tree != null)
0760:                        tree.accept(validator);
0761:                } catch (CompletionFailure ex) {
0762:                    completionError(tree.pos(), ex);
0763:                }
0764:            }
0765:
0766:            /** Visitor method: Validate a list of type expressions.
0767:             */
0768:            void validate(List<? extends JCTree> trees) {
0769:                for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
0770:                    validate(l.head);
0771:            }
0772:
0773:            /** Visitor method: Validate a list of type parameters.
0774:             */
0775:            void validateTypeParams(List<JCTypeParameter> trees) {
0776:                for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail)
0777:                    validate(l.head);
0778:            }
0779:
0780:            /** A visitor class for type validation.
0781:             */
0782:            class Validator extends JCTree.Visitor {
0783:
0784:                public void visitTypeArray(JCArrayTypeTree tree) {
0785:                    validate(tree.elemtype);
0786:                }
0787:
0788:                public void visitTypeApply(JCTypeApply tree) {
0789:                    if (tree.type.tag == CLASS) {
0790:                        List<Type> formals = tree.type.tsym.type
0791:                                .getTypeArguments();
0792:                        List<Type> actuals = tree.type.getTypeArguments();
0793:                        List<JCExpression> args = tree.arguments;
0794:                        List<Type> forms = formals;
0795:                        ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>();
0796:
0797:                        // For matching pairs of actual argument types `a' and
0798:                        // formal type parameters with declared bound `b' ...
0799:                        while (args.nonEmpty() && forms.nonEmpty()) {
0800:                            validate(args.head);
0801:
0802:                            // exact type arguments needs to know their
0803:                            // bounds (for upper and lower bound
0804:                            // calculations).  So we create new TypeVars with
0805:                            // bounds substed with actuals.
0806:                            tvars_buf.append(types.substBound(
0807:                                    ((TypeVar) forms.head), formals, Type
0808:                                            .removeBounds(actuals)));
0809:
0810:                            args = args.tail;
0811:                            forms = forms.tail;
0812:                        }
0813:
0814:                        args = tree.arguments;
0815:                        List<TypeVar> tvars = tvars_buf.toList();
0816:                        while (args.nonEmpty() && tvars.nonEmpty()) {
0817:                            // Let the actual arguments know their bound
0818:                            args.head.type.withTypeVar(tvars.head);
0819:                            args = args.tail;
0820:                            tvars = tvars.tail;
0821:                        }
0822:
0823:                        args = tree.arguments;
0824:                        tvars = tvars_buf.toList();
0825:                        while (args.nonEmpty() && tvars.nonEmpty()) {
0826:                            checkExtends(args.head.pos(), args.head.type,
0827:                                    tvars.head);
0828:                            args = args.tail;
0829:                            tvars = tvars.tail;
0830:                        }
0831:
0832:                        // Check that this type is either fully parameterized, or
0833:                        // not parameterized at all.
0834:                        if (tree.type.getEnclosingType().isRaw())
0835:                            log.error(tree.pos(),
0836:                                    "improperly.formed.type.inner.raw.param");
0837:                        if (tree.clazz.getTag() == JCTree.SELECT)
0838:                            visitSelectInternal((JCFieldAccess) tree.clazz);
0839:                    }
0840:                }
0841:
0842:                public void visitTypeParameter(JCTypeParameter tree) {
0843:                    validate(tree.bounds);
0844:                    checkClassBounds(tree.pos(), tree.type);
0845:                }
0846:
0847:                @Override
0848:                public void visitWildcard(JCWildcard tree) {
0849:                    if (tree.inner != null)
0850:                        validate(tree.inner);
0851:                }
0852:
0853:                public void visitSelect(JCFieldAccess tree) {
0854:                    if (tree.type.tag == CLASS) {
0855:                        visitSelectInternal(tree);
0856:
0857:                        // Check that this type is either fully parameterized, or
0858:                        // not parameterized at all.
0859:                        if (tree.selected.type.isParameterized()
0860:                                && tree.type.tsym.type.getTypeArguments()
0861:                                        .nonEmpty())
0862:                            log.error(tree.pos(),
0863:                                    "improperly.formed.type.param.missing");
0864:                    }
0865:                }
0866:
0867:                public void visitSelectInternal(JCFieldAccess tree) {
0868:                    if (tree.type.getEnclosingType().tag != CLASS
0869:                            && tree.selected.type.isParameterized()) {
0870:                        // The enclosing type is not a class, so we are
0871:                        // looking at a static member type.  However, the
0872:                        // qualifying expression is parameterized.
0873:                        log.error(tree.pos(),
0874:                                "cant.select.static.class.from.param.type");
0875:                    } else {
0876:                        // otherwise validate the rest of the expression
0877:                        validate(tree.selected);
0878:                    }
0879:                }
0880:
0881:                /** Default visitor method: do nothing.
0882:                 */
0883:                public void visitTree(JCTree tree) {
0884:                }
0885:            }
0886:
0887:            /* *************************************************************************
0888:             * Exception checking
0889:             **************************************************************************/
0890:
0891:            /* The following methods treat classes as sets that contain
0892:             * the class itself and all their subclasses
0893:             */
0894:
0895:            /** Is given type a subtype of some of the types in given list?
0896:             */
0897:            boolean subset(Type t, List<Type> ts) {
0898:                for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
0899:                    if (types.isSubtype(t, l.head))
0900:                        return true;
0901:                return false;
0902:            }
0903:
0904:            /** Is given type a subtype or supertype of
0905:             *  some of the types in given list?
0906:             */
0907:            boolean intersects(Type t, List<Type> ts) {
0908:                for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
0909:                    if (types.isSubtype(t, l.head)
0910:                            || types.isSubtype(l.head, t))
0911:                        return true;
0912:                return false;
0913:            }
0914:
0915:            /** Add type set to given type list, unless it is a subclass of some class
0916:             *  in the list.
0917:             */
0918:            List<Type> incl(Type t, List<Type> ts) {
0919:                return subset(t, ts) ? ts : excl(t, ts).prepend(t);
0920:            }
0921:
0922:            /** Remove type set from type set list.
0923:             */
0924:            List<Type> excl(Type t, List<Type> ts) {
0925:                if (ts.isEmpty()) {
0926:                    return ts;
0927:                } else {
0928:                    List<Type> ts1 = excl(t, ts.tail);
0929:                    if (types.isSubtype(ts.head, t))
0930:                        return ts1;
0931:                    else if (ts1 == ts.tail)
0932:                        return ts;
0933:                    else
0934:                        return ts1.prepend(ts.head);
0935:                }
0936:            }
0937:
0938:            /** Form the union of two type set lists.
0939:             */
0940:            List<Type> union(List<Type> ts1, List<Type> ts2) {
0941:                List<Type> ts = ts1;
0942:                for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
0943:                    ts = incl(l.head, ts);
0944:                return ts;
0945:            }
0946:
0947:            /** Form the difference of two type lists.
0948:             */
0949:            List<Type> diff(List<Type> ts1, List<Type> ts2) {
0950:                List<Type> ts = ts1;
0951:                for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
0952:                    ts = excl(l.head, ts);
0953:                return ts;
0954:            }
0955:
0956:            /** Form the intersection of two type lists.
0957:             */
0958:            public List<Type> intersect(List<Type> ts1, List<Type> ts2) {
0959:                List<Type> ts = List.nil();
0960:                for (List<Type> l = ts1; l.nonEmpty(); l = l.tail)
0961:                    if (subset(l.head, ts2))
0962:                        ts = incl(l.head, ts);
0963:                for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
0964:                    if (subset(l.head, ts1))
0965:                        ts = incl(l.head, ts);
0966:                return ts;
0967:            }
0968:
0969:            /** Is exc an exception symbol that need not be declared?
0970:             */
0971:            boolean isUnchecked(ClassSymbol exc) {
0972:                return exc.kind == ERR
0973:                        || exc.isSubClass(syms.errorType.tsym, types)
0974:                        || exc
0975:                                .isSubClass(syms.runtimeExceptionType.tsym,
0976:                                        types);
0977:            }
0978:
0979:            /** Is exc an exception type that need not be declared?
0980:             */
0981:            boolean isUnchecked(Type exc) {
0982:                return (exc.tag == TYPEVAR) ? isUnchecked(types.super type(exc))
0983:                        : (exc.tag == CLASS) ? isUnchecked((ClassSymbol) exc.tsym)
0984:                                : exc.tag == BOT;
0985:            }
0986:
0987:            /** Same, but handling completion failures.
0988:             */
0989:            boolean isUnchecked(DiagnosticPosition pos, Type exc) {
0990:                try {
0991:                    return isUnchecked(exc);
0992:                } catch (CompletionFailure ex) {
0993:                    completionError(pos, ex);
0994:                    return true;
0995:                }
0996:            }
0997:
0998:            /** Is exc handled by given exception list?
0999:             */
1000:            boolean isHandled(Type exc, List<Type> handled) {
1001:                return isUnchecked(exc) || subset(exc, handled);
1002:            }
1003:
1004:            /** Return all exceptions in thrown list that are not in handled list.
1005:             *  @param thrown     The list of thrown exceptions.
1006:             *  @param handled    The list of handled exceptions.
1007:             */
1008:            List<Type> unHandled(List<Type> thrown, List<Type> handled) {
1009:                List<Type> unhandled = List.nil();
1010:                for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1011:                    if (!isHandled(l.head, handled))
1012:                        unhandled = unhandled.prepend(l.head);
1013:                return unhandled;
1014:            }
1015:
1016:            /* *************************************************************************
1017:             * Overriding/Implementation checking
1018:             **************************************************************************/
1019:
1020:            /** The level of access protection given by a flag set,
1021:             *  where PRIVATE is highest and PUBLIC is lowest.
1022:             */
1023:            static int protection(long flags) {
1024:                switch ((short) (flags & AccessFlags)) {
1025:                case PRIVATE:
1026:                    return 3;
1027:                case PROTECTED:
1028:                    return 1;
1029:                default:
1030:                case PUBLIC:
1031:                    return 0;
1032:                case 0:
1033:                    return 2;
1034:                }
1035:            }
1036:
1037:            /** A string describing the access permission given by a flag set.
1038:             *  This always returns a space-separated list of Java Keywords.
1039:             */
1040:            private static String protectionString(long flags) {
1041:                long flags1 = flags & AccessFlags;
1042:                return (flags1 == 0) ? "package" : TreeInfo.flagNames(flags1);
1043:            }
1044:
1045:            /** A customized "cannot override" error message.
1046:             *  @param m      The overriding method.
1047:             *  @param other  The overridden method.
1048:             *  @return       An internationalized string.
1049:             */
1050:            static Object cannotOverride(MethodSymbol m, MethodSymbol other) {
1051:                String key;
1052:                if ((other.owner.flags() & INTERFACE) == 0)
1053:                    key = "cant.override";
1054:                else if ((m.owner.flags() & INTERFACE) == 0)
1055:                    key = "cant.implement";
1056:                else
1057:                    key = "clashes.with";
1058:                return JCDiagnostic.fragment(key, m, m.location(), other, other
1059:                        .location());
1060:            }
1061:
1062:            /** A customized "override" warning message.
1063:             *  @param m      The overriding method.
1064:             *  @param other  The overridden method.
1065:             *  @return       An internationalized string.
1066:             */
1067:            static Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
1068:                String key;
1069:                if ((other.owner.flags() & INTERFACE) == 0)
1070:                    key = "unchecked.override";
1071:                else if ((m.owner.flags() & INTERFACE) == 0)
1072:                    key = "unchecked.implement";
1073:                else
1074:                    key = "unchecked.clash.with";
1075:                return JCDiagnostic.fragment(key, m, m.location(), other, other
1076:                        .location());
1077:            }
1078:
1079:            /** A customized "override" warning message.
1080:             *  @param m      The overriding method.
1081:             *  @param other  The overridden method.
1082:             *  @return       An internationalized string.
1083:             */
1084:            static Object varargsOverrides(MethodSymbol m, MethodSymbol other) {
1085:                String key;
1086:                if ((other.owner.flags() & INTERFACE) == 0)
1087:                    key = "varargs.override";
1088:                else if ((m.owner.flags() & INTERFACE) == 0)
1089:                    key = "varargs.implement";
1090:                else
1091:                    key = "varargs.clash.with";
1092:                return JCDiagnostic.fragment(key, m, m.location(), other, other
1093:                        .location());
1094:            }
1095:
1096:            /** Check that this method conforms with overridden method 'other'.
1097:             *  where `origin' is the class where checking started.
1098:             *  Complications:
1099:             *  (1) Do not check overriding of synthetic methods
1100:             *      (reason: they might be final).
1101:             *      todo: check whether this is still necessary.
1102:             *  (2) Admit the case where an interface proxy throws fewer exceptions
1103:             *      than the method it implements. Augment the proxy methods with the
1104:             *      undeclared exceptions in this case.
1105:             *  (3) When generics are enabled, admit the case where an interface proxy
1106:             *	    has a result type
1107:             *      extended by the result type of the method it implements.
1108:             *      Change the proxies result type to the smaller type in this case.
1109:             *
1110:             *  @param tree         The tree from which positions
1111:             *			    are extracted for errors.
1112:             *  @param m            The overriding method.
1113:             *  @param other        The overridden method.
1114:             *  @param origin       The class of which the overriding method
1115:             *			    is a member.
1116:             */
1117:            void checkOverride(JCTree tree, MethodSymbol m, MethodSymbol other,
1118:                    ClassSymbol origin) {
1119:                // Don't check overriding of synthetic methods or by bridge methods.
1120:                if ((m.flags() & (SYNTHETIC | BRIDGE)) != 0
1121:                        || (other.flags() & SYNTHETIC) != 0) {
1122:                    return;
1123:                }
1124:
1125:                // Error if static method overrides instance method (JLS 8.4.6.2).
1126:                if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) == 0) {
1127:                    log.error(TreeInfo.diagnosticPositionFor(m, tree),
1128:                            "override.static", cannotOverride(m, other));
1129:                    return;
1130:                }
1131:
1132:                // Error if instance method overrides static or final
1133:                // method (JLS 8.4.6.1).
1134:                if ((other.flags() & FINAL) != 0 || (m.flags() & STATIC) == 0
1135:                        && (other.flags() & STATIC) != 0) {
1136:                    log
1137:                            .error(TreeInfo.diagnosticPositionFor(m, tree),
1138:                                    "override.meth", cannotOverride(m, other),
1139:                                    TreeInfo.flagNames(other.flags()
1140:                                            & (FINAL | STATIC)));
1141:                    return;
1142:                }
1143:
1144:                if ((m.owner.flags() & ANNOTATION) != 0) {
1145:                    // handled in validateAnnotationMethod
1146:                    return;
1147:                }
1148:
1149:                // Error if overriding method has weaker access (JLS 8.4.6.3).
1150:                if ((origin.flags() & INTERFACE) == 0
1151:                        && protection(m.flags()) > protection(other.flags())) {
1152:                    log.error(TreeInfo.diagnosticPositionFor(m, tree),
1153:                            "override.weaker.access", cannotOverride(m, other),
1154:                            protectionString(other.flags()));
1155:                    return;
1156:
1157:                }
1158:
1159:                Type mt = types.memberType(origin.type, m);
1160:                Type ot = types.memberType(origin.type, other);
1161:                // Error if overriding result type is different
1162:                // (or, in the case of generics mode, not a subtype) of
1163:                // overridden result type. We have to rename any type parameters
1164:                // before comparing types.
1165:                List<Type> mtvars = mt.getTypeArguments();
1166:                List<Type> otvars = ot.getTypeArguments();
1167:                Type mtres = mt.getReturnType();
1168:                Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
1169:
1170:                overrideWarner.warned = false;
1171:                boolean resultTypesOK = types.returnTypeSubstitutable(mt, ot,
1172:                        otres, overrideWarner);
1173:                if (!resultTypesOK) {
1174:                    if (!source.allowCovariantReturns() && m.owner != origin
1175:                            && m.owner.isSubClass(other.owner, types)) {
1176:                        // allow limited interoperability with covariant returns
1177:                    } else {
1178:                        typeError(TreeInfo.diagnosticPositionFor(m, tree),
1179:                                JCDiagnostic.fragment(
1180:                                        "override.incompatible.ret",
1181:                                        cannotOverride(m, other)), mtres, otres);
1182:                        return;
1183:                    }
1184:                } else if (overrideWarner.warned) {
1185:                    warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1186:                            "prob.found.req", JCDiagnostic.fragment(
1187:                                    "override.unchecked.ret",
1188:                                    uncheckedOverrides(m, other)), mtres, otres);
1189:                }
1190:
1191:                // Error if overriding method throws an exception not reported
1192:                // by overridden method.
1193:                List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars,
1194:                        mtvars);
1195:                List<Type> unhandled = unHandled(mt.getThrownTypes(), otthrown);
1196:                if (unhandled.nonEmpty()) {
1197:                    log.error(TreeInfo.diagnosticPositionFor(m, tree),
1198:                            "override.meth.doesnt.throw", cannotOverride(m,
1199:                                    other), unhandled.head);
1200:                    return;
1201:                }
1202:
1203:                // Optional warning if varargs don't agree 
1204:                if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
1205:                        && lint.isEnabled(Lint.LintCategory.OVERRIDES)) {
1206:                    log
1207:                            .warning(
1208:                                    TreeInfo.diagnosticPositionFor(m, tree),
1209:                                    ((m.flags() & Flags.VARARGS) != 0) ? "override.varargs.missing"
1210:                                            : "override.varargs.extra",
1211:                                    varargsOverrides(m, other));
1212:                }
1213:
1214:                // Warn if instance method overrides bridge method (compiler spec ??)
1215:                if ((other.flags() & BRIDGE) != 0) {
1216:                    log.warning(TreeInfo.diagnosticPositionFor(m, tree),
1217:                            "override.bridge", uncheckedOverrides(m, other));
1218:                }
1219:
1220:                // Warn if a deprecated method overridden by a non-deprecated one.
1221:                if ((other.flags() & DEPRECATED) != 0
1222:                        && (m.flags() & DEPRECATED) == 0
1223:                        && m.outermostClass() != other.outermostClass()
1224:                        && !isDeprecatedOverrideIgnorable(other, origin)) {
1225:                    warnDeprecated(TreeInfo.diagnosticPositionFor(m, tree),
1226:                            other);
1227:                }
1228:            }
1229:
1230:            // where
1231:            private boolean isDeprecatedOverrideIgnorable(MethodSymbol m,
1232:                    ClassSymbol origin) {
1233:                // If the method, m, is defined in an interface, then ignore the issue if the method
1234:                // is only inherited via a supertype and also implemented in the supertype,
1235:                // because in that case, we will rediscover the issue when examining the method
1236:                // in the supertype.
1237:                // If the method, m, is not defined in an interface, then the only time we need to
1238:                // address the issue is when the method is the supertype implemementation: any other
1239:                // case, we will have dealt with when examining the supertype classes
1240:                ClassSymbol mc = m.enclClass();
1241:                Type st = types.super type(origin.type);
1242:                if (st.tag != CLASS)
1243:                    return true;
1244:                MethodSymbol stimpl = m.implementation((ClassSymbol) st.tsym,
1245:                        types, false);
1246:
1247:                if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
1248:                    List<Type> intfs = types.interfaces(origin.type);
1249:                    return (intfs.contains(mc.type) ? false : (stimpl != null));
1250:                } else
1251:                    return (stimpl != m);
1252:            }
1253:
1254:            // used to check if there were any unchecked conversions
1255:            Warner overrideWarner = new Warner();
1256:
1257:            /** Check that a class does not inherit two concrete methods
1258:             *  with the same signature.
1259:             *  @param pos          Position to be used for error reporting.
1260:             *  @param site         The class type to be checked.
1261:             */
1262:            public void checkCompatibleConcretes(DiagnosticPosition pos,
1263:                    Type site) {
1264:                Type sup = types.super type(site);
1265:                if (sup.tag != CLASS)
1266:                    return;
1267:
1268:                for (Type t1 = sup; t1.tsym.type.isParameterized(); t1 = types
1269:                        .super type(t1)) {
1270:                    for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
1271:                        Symbol s1 = e1.sym;
1272:                        if (s1.kind != MTH
1273:                                || (s1.flags() & (STATIC | SYNTHETIC | BRIDGE)) != 0
1274:                                || !s1.isInheritedIn(site.tsym, types)
1275:                                || ((MethodSymbol) s1).implementation(
1276:                                        site.tsym, types, true) != s1)
1277:                            continue;
1278:                        Type st1 = types.memberType(t1, s1);
1279:                        int s1ArgsLength = st1.getParameterTypes().length();
1280:                        if (st1 == s1.type)
1281:                            continue;
1282:
1283:                        for (Type t2 = sup; t2.tag == CLASS; t2 = types
1284:                                .super type(t2)) {
1285:                            for (Scope.Entry e2 = t1.tsym.members().lookup(
1286:                                    s1.name); e2.scope != null; e2 = e2.next()) {
1287:                                Symbol s2 = e2.sym;
1288:                                if (s2 == s1
1289:                                        || s2.kind != MTH
1290:                                        || (s2.flags() & (STATIC | SYNTHETIC | BRIDGE)) != 0
1291:                                        || s2.type.getParameterTypes().length() != s1ArgsLength
1292:                                        || !s2.isInheritedIn(site.tsym, types)
1293:                                        || ((MethodSymbol) s2).implementation(
1294:                                                site.tsym, types, true) != s2)
1295:                                    continue;
1296:                                Type st2 = types.memberType(t2, s2);
1297:                                if (types.overrideEquivalent(st1, st2))
1298:                                    log.error(pos,
1299:                                            "concrete.inheritance.conflict",
1300:                                            s1, t1, s2, t2, sup);
1301:                            }
1302:                        }
1303:                    }
1304:                }
1305:            }
1306:
1307:            /** Check that classes (or interfaces) do not each define an abstract
1308:             *  method with same name and arguments but incompatible return types.
1309:             *  @param pos          Position to be used for error reporting.
1310:             *  @param t1           The first argument type.
1311:             *  @param t2           The second argument type.
1312:             */
1313:            public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
1314:                    Type t1, Type t2) {
1315:                return checkCompatibleAbstracts(pos, t1, t2, types
1316:                        .makeCompoundType(t1, t2));
1317:            }
1318:
1319:            public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
1320:                    Type t1, Type t2, Type site) {
1321:                Symbol sym = firstIncompatibility(t1, t2, site);
1322:                if (sym != null) {
1323:                    log.error(pos, "types.incompatible.diff.ret", t1, t2,
1324:                            sym.name
1325:                                    + "("
1326:                                    + types.memberType(t2, sym)
1327:                                            .getParameterTypes() + ")");
1328:                    return false;
1329:                }
1330:                return true;
1331:            }
1332:
1333:            /** Return the first method which is defined with same args
1334:             *  but different return types in two given interfaces, or null if none
1335:             *  exists.
1336:             *  @param t1     The first type.
1337:             *  @param t2     The second type.
1338:             *  @param site   The most derived type.
1339:             *  @returns symbol from t2 that conflicts with one in t1.
1340:             */
1341:            private Symbol firstIncompatibility(Type t1, Type t2, Type site) {
1342:                Map<TypeSymbol, Type> interfaces1 = new HashMap<TypeSymbol, Type>();
1343:                closure(t1, interfaces1);
1344:                Map<TypeSymbol, Type> interfaces2;
1345:                if (t1 == t2)
1346:                    interfaces2 = interfaces1;
1347:                else
1348:                    closure(t2, interfaces1,
1349:                            interfaces2 = new HashMap<TypeSymbol, Type>());
1350:
1351:                for (Type t3 : interfaces1.values()) {
1352:                    for (Type t4 : interfaces2.values()) {
1353:                        Symbol s = firstDirectIncompatibility(t3, t4, site);
1354:                        if (s != null)
1355:                            return s;
1356:                    }
1357:                }
1358:                return null;
1359:            }
1360:
1361:            /** Compute all the supertypes of t, indexed by type symbol. */
1362:            private void closure(Type t, Map<TypeSymbol, Type> typeMap) {
1363:                if (t.tag != CLASS)
1364:                    return;
1365:                if (typeMap.put(t.tsym, t) == null) {
1366:                    closure(types.super type(t), typeMap);
1367:                    for (Type i : types.interfaces(t))
1368:                        closure(i, typeMap);
1369:                }
1370:            }
1371:
1372:            /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
1373:            private void closure(Type t, Map<TypeSymbol, Type> typesSkip,
1374:                    Map<TypeSymbol, Type> typeMap) {
1375:                if (t.tag != CLASS)
1376:                    return;
1377:                if (typesSkip.get(t.tsym) != null)
1378:                    return;
1379:                if (typeMap.put(t.tsym, t) == null) {
1380:                    closure(types.super type(t), typesSkip, typeMap);
1381:                    for (Type i : types.interfaces(t))
1382:                        closure(i, typesSkip, typeMap);
1383:                }
1384:            }
1385:
1386:            /** Return the first method in t2 that conflicts with a method from t1. */
1387:            private Symbol firstDirectIncompatibility(Type t1, Type t2,
1388:                    Type site) {
1389:                for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
1390:                    Symbol s1 = e1.sym;
1391:                    Type st1 = null;
1392:                    if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types))
1393:                        continue;
1394:                    Symbol impl = ((MethodSymbol) s1).implementation(site.tsym,
1395:                            types, false);
1396:                    if (impl != null && (impl.flags() & ABSTRACT) == 0)
1397:                        continue;
1398:                    for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2
1399:                            .next()) {
1400:                        Symbol s2 = e2.sym;
1401:                        if (s1 == s2)
1402:                            continue;
1403:                        if (s2.kind != MTH
1404:                                || !s2.isInheritedIn(site.tsym, types))
1405:                            continue;
1406:                        if (st1 == null)
1407:                            st1 = types.memberType(t1, s1);
1408:                        Type st2 = types.memberType(t2, s2);
1409:                        if (types.overrideEquivalent(st1, st2)) {
1410:                            List<Type> tvars1 = st1.getTypeArguments();
1411:                            List<Type> tvars2 = st2.getTypeArguments();
1412:                            Type rt1 = st1.getReturnType();
1413:                            Type rt2 = types.subst(st2.getReturnType(), tvars2,
1414:                                    tvars1);
1415:                            boolean compat = types.isSameType(rt1, rt2)
1416:                                    || rt1.tag >= CLASS
1417:                                    && rt2.tag >= CLASS
1418:                                    && (types.covariantReturnType(rt1, rt2,
1419:                                            Warner.noWarnings) || types
1420:                                            .covariantReturnType(rt2, rt1,
1421:                                                    Warner.noWarnings));
1422:                            if (!compat)
1423:                                return s2;
1424:                        }
1425:                    }
1426:                }
1427:                return null;
1428:            }
1429:
1430:            /** Check that a given method conforms with any method it overrides.
1431:             *  @param tree         The tree from which positions are extracted
1432:             *			    for errors.
1433:             *  @param m            The overriding method.
1434:             */
1435:            void checkOverride(JCTree tree, MethodSymbol m) {
1436:                ClassSymbol origin = (ClassSymbol) m.owner;
1437:                if ((origin.flags() & ENUM) != 0
1438:                        && names.finalize.equals(m.name))
1439:                    if (m.overrides(syms.enumFinalFinalize, origin, types,
1440:                            false)) {
1441:                        log.error(tree.pos(), "enum.no.finalize");
1442:                        return;
1443:                    }
1444:                for (Type t = types.super type(origin.type); t.tag == CLASS; t = types
1445:                        .super type(t)) {
1446:                    TypeSymbol c = t.tsym;
1447:                    Scope.Entry e = c.members().lookup(m.name);
1448:                    while (e.scope != null) {
1449:                        if (m.overrides(e.sym, origin, types, false))
1450:                            checkOverride(tree, m, (MethodSymbol) e.sym, origin);
1451:                        e = e.next();
1452:                    }
1453:                }
1454:            }
1455:
1456:            /** Check that all abstract members of given class have definitions.
1457:             *  @param pos          Position to be used for error reporting.
1458:             *  @param c            The class.
1459:             */
1460:            void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
1461:                try {
1462:                    MethodSymbol undef = firstUndef(c, c);
1463:                    if (undef != null) {
1464:                        if ((c.flags() & ENUM) != 0
1465:                                && types.super type(c.type).tsym == syms.enumSym
1466:                                && (c.flags() & FINAL) == 0) {
1467:                            // add the ABSTRACT flag to an enum
1468:                            c.flags_field |= ABSTRACT;
1469:                        } else {
1470:                            MethodSymbol undef1 = new MethodSymbol(undef
1471:                                    .flags(), undef.name, types.memberType(
1472:                                    c.type, undef), undef.owner);
1473:                            log.error(pos, "does.not.override.abstract", c,
1474:                                    undef1, undef1.location());
1475:                        }
1476:                    }
1477:                } catch (CompletionFailure ex) {
1478:                    completionError(pos, ex);
1479:                }
1480:            }
1481:
1482:            //where
1483:            /** Return first abstract member of class `c' that is not defined
1484:             *  in `impl', null if there is none.
1485:             */
1486:            private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {
1487:                MethodSymbol undef = null;
1488:                // Do not bother to search in classes that are not abstract,
1489:                // since they cannot have abstract members.
1490:                if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
1491:                    Scope s = c.members();
1492:                    for (Scope.Entry e = s.elems; undef == null && e != null; e = e.sibling) {
1493:                        if (e.sym.kind == MTH
1494:                                && (e.sym.flags() & (ABSTRACT | IPROXY)) == ABSTRACT) {
1495:                            MethodSymbol absmeth = (MethodSymbol) e.sym;
1496:                            MethodSymbol implmeth = absmeth.implementation(
1497:                                    impl, types, true);
1498:                            if (implmeth == null || implmeth == absmeth)
1499:                                undef = absmeth;
1500:                        }
1501:                    }
1502:                    if (undef == null) {
1503:                        Type st = types.super type(c.type);
1504:                        if (st.tag == CLASS)
1505:                            undef = firstUndef(impl, (ClassSymbol) st.tsym);
1506:                    }
1507:                    for (List<Type> l = types.interfaces(c.type); undef == null
1508:                            && l.nonEmpty(); l = l.tail) {
1509:                        undef = firstUndef(impl, (ClassSymbol) l.head.tsym);
1510:                    }
1511:                }
1512:                return undef;
1513:            }
1514:
1515:            /** Check for cyclic references. Issue an error if the
1516:             *  symbol of the type referred to has a LOCKED flag set.
1517:             *
1518:             *  @param pos      Position to be used for error reporting.
1519:             *  @param t        The type referred to.
1520:             */
1521:            void checkNonCyclic(DiagnosticPosition pos, Type t) {
1522:                checkNonCyclicInternal(pos, t);
1523:            }
1524:
1525:            void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
1526:                checkNonCyclic1(pos, t, new HashSet<TypeVar>());
1527:            }
1528:
1529:            private void checkNonCyclic1(DiagnosticPosition pos, Type t,
1530:                    Set<TypeVar> seen) {
1531:                final TypeVar tv;
1532:                if (seen.contains(t)) {
1533:                    tv = (TypeVar) t;
1534:                    tv.bound = new ErrorType();
1535:                    log.error(pos, "cyclic.inheritance", t);
1536:                } else if (t.tag == TYPEVAR) {
1537:                    tv = (TypeVar) t;
1538:                    seen.add(tv);
1539:                    for (Type b : types.getBounds(tv))
1540:                        checkNonCyclic1(pos, b, seen);
1541:                }
1542:            }
1543:
1544:            /** Check for cyclic references. Issue an error if the
1545:             *  symbol of the type referred to has a LOCKED flag set.
1546:             *
1547:             *  @param pos      Position to be used for error reporting.
1548:             *  @param t        The type referred to.
1549:             *  @returns        True if the check completed on all attributed classes
1550:             */
1551:            private boolean checkNonCyclicInternal(DiagnosticPosition pos,
1552:                    Type t) {
1553:                boolean complete = true; // was the check complete?
1554:                //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
1555:                Symbol c = t.tsym;
1556:                if ((c.flags_field & ACYCLIC) != 0)
1557:                    return true;
1558:
1559:                if ((c.flags_field & LOCKED) != 0) {
1560:                    noteCyclic(pos, (ClassSymbol) c);
1561:                } else if (!c.type.isErroneous()) {
1562:                    try {
1563:                        c.flags_field |= LOCKED;
1564:                        if (c.type.tag == CLASS) {
1565:                            ClassType clazz = (ClassType) c.type;
1566:                            if (clazz.interfaces_field != null)
1567:                                for (List<Type> l = clazz.interfaces_field; l
1568:                                        .nonEmpty(); l = l.tail)
1569:                                    complete &= checkNonCyclicInternal(pos,
1570:                                            l.head);
1571:                            if (clazz.super type_field != null) {
1572:                                Type st = clazz.super type_field;
1573:                                if (st != null && st.tag == CLASS)
1574:                                    complete &= checkNonCyclicInternal(pos, st);
1575:                            }
1576:                            if (c.owner.kind == TYP)
1577:                                complete &= checkNonCyclicInternal(pos,
1578:                                        c.owner.type);
1579:                        }
1580:                    } finally {
1581:                        c.flags_field &= ~LOCKED;
1582:                    }
1583:                }
1584:                if (complete)
1585:                    complete = ((c.flags_field & UNATTRIBUTED) == 0)
1586:                            && c.completer == null;
1587:                if (complete)
1588:                    c.flags_field |= ACYCLIC;
1589:                return complete;
1590:            }
1591:
1592:            /** Note that we found an inheritance cycle. */
1593:            private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
1594:                log.error(pos, "cyclic.inheritance", c);
1595:                for (List<Type> l = types.interfaces(c.type); l.nonEmpty(); l = l.tail)
1596:                    l.head = new ErrorType((ClassSymbol) l.head.tsym);
1597:                Type st = types.super type(c.type);
1598:                if (st.tag == CLASS)
1599:                    ((ClassType) c.type).super type_field = new ErrorType(
1600:                            (ClassSymbol) st.tsym);
1601:                c.type = new ErrorType(c);
1602:                c.flags_field |= ACYCLIC;
1603:            }
1604:
1605:            /** Check that all methods which implement some
1606:             *  method conform to the method they implement.
1607:             *  @param tree         The class definition whose members are checked.
1608:             */
1609:            void checkImplementations(JCClassDecl tree) {
1610:                checkImplementations(tree, tree.sym);
1611:            }
1612:
1613:            //where
1614:            /** Check that all methods which implement some
1615:             *  method in `ic' conform to the method they implement.
1616:             */
1617:            void checkImplementations(JCClassDecl tree, ClassSymbol ic) {
1618:                ClassSymbol origin = tree.sym;
1619:                for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
1620:                    ClassSymbol lc = (ClassSymbol) l.head.tsym;
1621:                    if ((allowGenerics || origin != lc)
1622:                            && (lc.flags() & ABSTRACT) != 0) {
1623:                        for (Scope.Entry e = lc.members().elems; e != null; e = e.sibling) {
1624:                            if (e.sym.kind == MTH
1625:                                    && (e.sym.flags() & (STATIC | ABSTRACT)) == ABSTRACT) {
1626:                                MethodSymbol absmeth = (MethodSymbol) e.sym;
1627:                                MethodSymbol implmeth = absmeth.implementation(
1628:                                        origin, types, false);
1629:                                if (implmeth != null
1630:                                        && implmeth != absmeth
1631:                                        && (implmeth.owner.flags() & INTERFACE) == (origin
1632:                                                .flags() & INTERFACE)) {
1633:                                    // don't check if implmeth is in a class, yet
1634:                                    // origin is an interface. This case arises only
1635:                                    // if implmeth is declared in Object. The reason is
1636:                                    // that interfaces really don't inherit from
1637:                                    // Object it's just that the compiler represents
1638:                                    // things that way.
1639:                                    checkOverride(tree, implmeth, absmeth,
1640:                                            origin);
1641:                                }
1642:                            }
1643:                        }
1644:                    }
1645:                }
1646:            }
1647:
1648:            /** Check that all abstract methods implemented by a class are
1649:             *  mutually compatible.
1650:             *  @param pos          Position to be used for error reporting.
1651:             *  @param c            The class whose interfaces are checked.
1652:             */
1653:            void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
1654:                List<Type> super types = types.interfaces(c);
1655:                Type super type = types.super type(c);
1656:                if (super type.tag == CLASS
1657:                        && (super type.tsym.flags() & ABSTRACT) != 0)
1658:                    super types = super types.prepend(super type);
1659:                for (List<Type> l = super types; l.nonEmpty(); l = l.tail) {
1660:                    if (allowGenerics
1661:                            && !l.head.getTypeArguments().isEmpty()
1662:                            && !checkCompatibleAbstracts(pos, l.head, l.head, c))
1663:                        return;
1664:                    for (List<Type> m = super types; m != l; m = m.tail)
1665:                        if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
1666:                            return;
1667:                }
1668:                checkCompatibleConcretes(pos, c);
1669:            }
1670:
1671:            /** Check that class c does not implement directly or indirectly
1672:             *  the same parameterized interface with two different argument lists.
1673:             *  @param pos          Position to be used for error reporting.
1674:             *  @param type         The type whose interfaces are checked.
1675:             */
1676:            void checkClassBounds(DiagnosticPosition pos, Type type) {
1677:                checkClassBounds(pos, new HashMap<TypeSymbol, Type>(), type);
1678:            }
1679:
1680:            //where
1681:            /** Enter all interfaces of type `type' into the hash table `seensofar'
1682:             *  with their class symbol as key and their type as value. Make
1683:             *  sure no class is entered with two different types.
1684:             */
1685:            void checkClassBounds(DiagnosticPosition pos,
1686:                    Map<TypeSymbol, Type> seensofar, Type type) {
1687:                if (type.isErroneous())
1688:                    return;
1689:                for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
1690:                    Type it = l.head;
1691:                    Type oldit = seensofar.put(it.tsym, it);
1692:                    if (oldit != null) {
1693:                        List<Type> oldparams = oldit.allparams();
1694:                        List<Type> newparams = it.allparams();
1695:                        if (!types.containsTypeEquivalent(oldparams, newparams))
1696:                            log.error(pos, "cant.inherit.diff.arg", it.tsym,
1697:                                    Type.toString(oldparams), Type
1698:                                            .toString(newparams));
1699:                    }
1700:                    checkClassBounds(pos, seensofar, it);
1701:                }
1702:                Type st = types.super type(type);
1703:                if (st != null)
1704:                    checkClassBounds(pos, seensofar, st);
1705:            }
1706:
1707:            /** Enter interface into into set.
1708:             *  If it existed already, issue a "repeated interface" error.
1709:             */
1710:            void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
1711:                if (its.contains(it))
1712:                    log.error(pos, "repeated.interface");
1713:                else {
1714:                    its.add(it);
1715:                }
1716:            }
1717:
1718:            /* *************************************************************************
1719:             * Check annotations
1720:             **************************************************************************/
1721:
1722:            /** Annotation types are restricted to primitives, String, an
1723:             *  enum, an annotation, Class, Class<?>, Class<? extends
1724:             *  Anything>, arrays of the preceding.
1725:             */
1726:            void validateAnnotationType(JCTree restype) {
1727:                // restype may be null if an error occurred, so don't bother validating it
1728:                if (restype != null) {
1729:                    validateAnnotationType(restype.pos(), restype.type);
1730:                }
1731:            }
1732:
1733:            void validateAnnotationType(DiagnosticPosition pos, Type type) {
1734:                if (type.isPrimitive())
1735:                    return;
1736:                if (types.isSameType(type, syms.stringType))
1737:                    return;
1738:                if ((type.tsym.flags() & Flags.ENUM) != 0)
1739:                    return;
1740:                if ((type.tsym.flags() & Flags.ANNOTATION) != 0)
1741:                    return;
1742:                if (types.lowerBound(type).tsym == syms.classType.tsym)
1743:                    return;
1744:                if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
1745:                    validateAnnotationType(pos, types.elemtype(type));
1746:                    return;
1747:                }
1748:                log.error(pos, "invalid.annotation.member.type");
1749:            }
1750:
1751:            /**
1752:             * "It is also a compile-time error if any method declared in an
1753:             * annotation type has a signature that is override-equivalent to
1754:             * that of any public or protected method declared in class Object
1755:             * or in the interface annotation.Annotation."
1756:             *
1757:             * @jls3 9.6 Annotation Types
1758:             */
1759:            void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
1760:                for (Type sup = syms.annotationType; sup.tag == CLASS; sup = types
1761:                        .super type(sup)) {
1762:                    Scope s = sup.tsym.members();
1763:                    for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e
1764:                            .next()) {
1765:                        if (e.sym.kind == MTH
1766:                                && (e.sym.flags() & (PUBLIC | PROTECTED)) != 0
1767:                                && types.overrideEquivalent(m.type, e.sym.type))
1768:                            log.error(pos, "intf.annotation.member.clash",
1769:                                    e.sym, sup);
1770:                    }
1771:                }
1772:            }
1773:
1774:            /** Check the annotations of a symbol.
1775:             */
1776:            public void validateAnnotations(List<JCAnnotation> annotations,
1777:                    Symbol s) {
1778:                if (skipAnnotations)
1779:                    return;
1780:                for (JCAnnotation a : annotations)
1781:                    validateAnnotation(a, s);
1782:            }
1783:
1784:            /** Check an annotation of a symbol.
1785:             */
1786:            public void validateAnnotation(JCAnnotation a, Symbol s) {
1787:                validateAnnotation(a);
1788:
1789:                if (!annotationApplicable(a, s))
1790:                    log.error(a.pos(), "annotation.type.not.applicable");
1791:
1792:                if (a.annotationType.type.tsym == syms.overrideType.tsym) {
1793:                    if (!isOverrider(s))
1794:                        log.error(a.pos(),
1795:                                "method.does.not.override.superclass");
1796:                }
1797:            }
1798:
1799:            /** Is s a method symbol that overrides a method in a superclass? */
1800:            boolean isOverrider(Symbol s) {
1801:                if (s.kind != MTH || s.isStatic())
1802:                    return false;
1803:                MethodSymbol m = (MethodSymbol) s;
1804:                TypeSymbol owner = (TypeSymbol) m.owner;
1805:                for (Type sup : types.closure(owner.type)) {
1806:                    if (sup == owner.type)
1807:                        continue; // skip "this"
1808:                    Scope scope = sup.tsym.members();
1809:                    for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e
1810:                            .next()) {
1811:                        if (!e.sym.isStatic()
1812:                                && m.overrides(e.sym, owner, types, true))
1813:                            return true;
1814:                    }
1815:                }
1816:                return false;
1817:            }
1818:
1819:            /** Is the annotation applicable to the symbol? */
1820:            boolean annotationApplicable(JCAnnotation a, Symbol s) {
1821:                Attribute.Compound atTarget = a.annotationType.type.tsym
1822:                        .attribute(syms.annotationTargetType.tsym);
1823:                if (atTarget == null)
1824:                    return true;
1825:                Attribute atValue = atTarget.member(names.value);
1826:                if (!(atValue instanceof  Attribute.Array))
1827:                    return true; // error recovery
1828:                Attribute.Array arr = (Attribute.Array) atValue;
1829:                for (Attribute app : arr.values) {
1830:                    if (!(app instanceof  Attribute.Enum))
1831:                        return true; // recovery
1832:                    Attribute.Enum e = (Attribute.Enum) app;
1833:                    if (e.value.name == names.TYPE) {
1834:                        if (s.kind == TYP)
1835:                            return true;
1836:                    } else if (e.value.name == names.FIELD) {
1837:                        if (s.kind == VAR && s.owner.kind != MTH)
1838:                            return true;
1839:                    } else if (e.value.name == names.METHOD) {
1840:                        if (s.kind == MTH && !s.isConstructor())
1841:                            return true;
1842:                    } else if (e.value.name == names.PARAMETER) {
1843:                        if (s.kind == VAR && s.owner.kind == MTH
1844:                                && (s.flags() & PARAMETER) != 0)
1845:                            return true;
1846:                    } else if (e.value.name == names.CONSTRUCTOR) {
1847:                        if (s.kind == MTH && s.isConstructor())
1848:                            return true;
1849:                    } else if (e.value.name == names.LOCAL_VARIABLE) {
1850:                        if (s.kind == VAR && s.owner.kind == MTH
1851:                                && (s.flags() & PARAMETER) == 0)
1852:                            return true;
1853:                    } else if (e.value.name == names.ANNOTATION_TYPE) {
1854:                        if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
1855:                            return true;
1856:                    } else if (e.value.name == names.PACKAGE) {
1857:                        if (s.kind == PCK)
1858:                            return true;
1859:                    } else
1860:                        return true; // recovery
1861:                }
1862:                return false;
1863:            }
1864:
1865:            /** Check an annotation value.
1866:             */
1867:            public void validateAnnotation(JCAnnotation a) {
1868:                if (a.type.isErroneous())
1869:                    return;
1870:
1871:                // collect an inventory of the members
1872:                Set<MethodSymbol> members = new HashSet<MethodSymbol>();
1873:                for (Scope.Entry e = a.annotationType.type.tsym.members().elems; e != null; e = e.sibling)
1874:                    if (e.sym.kind == MTH)
1875:                        members.add((MethodSymbol) e.sym);
1876:
1877:                // count them off as they're annotated
1878:                for (JCTree arg : a.args) {
1879:                    if (arg.getTag() != JCTree.ASSIGN)
1880:                        continue; // recovery
1881:                    JCAssign assign = (JCAssign) arg;
1882:                    Symbol m = TreeInfo.symbol(assign.lhs);
1883:                    if (m == null || m.type.isErroneous())
1884:                        continue;
1885:                    if (!members.remove(m))
1886:                        log.error(arg.pos(),
1887:                                "duplicate.annotation.member.value", m.name,
1888:                                a.type);
1889:                    if (assign.rhs.getTag() == ANNOTATION)
1890:                        validateAnnotation((JCAnnotation) assign.rhs);
1891:                }
1892:
1893:                // all the remaining ones better have default values
1894:                for (MethodSymbol m : members)
1895:                    if (m.defaultValue == null && !m.type.isErroneous())
1896:                        log.error(a.pos(), "annotation.missing.default.value",
1897:                                a.type, m.name);
1898:
1899:                // special case: java.lang.annotation.Target must not have
1900:                // repeated values in its value member
1901:                if (a.annotationType.type.tsym != syms.annotationTargetType.tsym
1902:                        || a.args.tail == null)
1903:                    return;
1904:
1905:                if (a.args.head.getTag() != JCTree.ASSIGN)
1906:                    return; // error recovery
1907:                JCAssign assign = (JCAssign) a.args.head;
1908:                Symbol m = TreeInfo.symbol(assign.lhs);
1909:                if (m.name != names.value)
1910:                    return;
1911:                JCTree rhs = assign.rhs;
1912:                if (rhs.getTag() != JCTree.NEWARRAY)
1913:                    return;
1914:                JCNewArray na = (JCNewArray) rhs;
1915:                Set<Symbol> targets = new HashSet<Symbol>();
1916:                for (JCTree elem : na.elems) {
1917:                    if (!targets.add(TreeInfo.symbol(elem))) {
1918:                        log.error(elem.pos(), "repeated.annotation.target");
1919:                    }
1920:                }
1921:            }
1922:
1923:            void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
1924:                if (allowAnnotations
1925:                        && lint.isEnabled(Lint.LintCategory.DEP_ANN)
1926:                        && (s.flags() & DEPRECATED) != 0
1927:                        && !syms.deprecatedType.isErroneous()
1928:                        && s.attribute(syms.deprecatedType.tsym) == null) {
1929:                    log.warning(pos, "missing.deprecated.annotation");
1930:                }
1931:            }
1932:
1933:            /* *************************************************************************
1934:             * Check for recursive annotation elements.
1935:             **************************************************************************/
1936:
1937:            /** Check for cycles in the graph of annotation elements.
1938:             */
1939:            void checkNonCyclicElements(JCClassDecl tree) {
1940:                if ((tree.sym.flags_field & ANNOTATION) == 0)
1941:                    return;
1942:                assert (tree.sym.flags_field & LOCKED) == 0;
1943:                try {
1944:                    tree.sym.flags_field |= LOCKED;
1945:                    for (JCTree def : tree.defs) {
1946:                        if (def.getTag() != JCTree.METHODDEF)
1947:                            continue;
1948:                        JCMethodDecl meth = (JCMethodDecl) def;
1949:                        checkAnnotationResType(meth.pos(), meth.restype.type);
1950:                    }
1951:                } finally {
1952:                    tree.sym.flags_field &= ~LOCKED;
1953:                    tree.sym.flags_field |= ACYCLIC_ANN;
1954:                }
1955:            }
1956:
1957:            void checkNonCyclicElementsInternal(DiagnosticPosition pos,
1958:                    TypeSymbol tsym) {
1959:                if ((tsym.flags_field & ACYCLIC_ANN) != 0)
1960:                    return;
1961:                if ((tsym.flags_field & LOCKED) != 0) {
1962:                    log.error(pos, "cyclic.annotation.element");
1963:                    return;
1964:                }
1965:                try {
1966:                    tsym.flags_field |= LOCKED;
1967:                    for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
1968:                        Symbol s = e.sym;
1969:                        if (s.kind != Kinds.MTH)
1970:                            continue;
1971:                        checkAnnotationResType(pos, ((MethodSymbol) s).type
1972:                                .getReturnType());
1973:                    }
1974:                } finally {
1975:                    tsym.flags_field &= ~LOCKED;
1976:                    tsym.flags_field |= ACYCLIC_ANN;
1977:                }
1978:            }
1979:
1980:            void checkAnnotationResType(DiagnosticPosition pos, Type type) {
1981:                switch (type.tag) {
1982:                case TypeTags.CLASS:
1983:                    if ((type.tsym.flags() & ANNOTATION) != 0)
1984:                        checkNonCyclicElementsInternal(pos, type.tsym);
1985:                    break;
1986:                case TypeTags.ARRAY:
1987:                    checkAnnotationResType(pos, types.elemtype(type));
1988:                    break;
1989:                default:
1990:                    break; // int etc
1991:                }
1992:            }
1993:
1994:            /* *************************************************************************
1995:             * Check for cycles in the constructor call graph.
1996:             **************************************************************************/
1997:
1998:            /** Check for cycles in the graph of constructors calling other
1999:             *  constructors.
2000:             */
2001:            void checkCyclicConstructors(JCClassDecl tree) {
2002:                Map<Symbol, Symbol> callMap = new HashMap<Symbol, Symbol>();
2003:
2004:                // enter each constructor this-call into the map
2005:                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
2006:                    JCMethodInvocation app = TreeInfo
2007:                            .firstConstructorCall(l.head);
2008:                    if (app == null)
2009:                        continue;
2010:                    JCMethodDecl meth = (JCMethodDecl) l.head;
2011:                    if (TreeInfo.name(app.meth) == names._this ) {
2012:                        callMap.put(meth.sym, TreeInfo.symbol(app.meth));
2013:                    } else {
2014:                        meth.sym.flags_field |= ACYCLIC;
2015:                    }
2016:                }
2017:
2018:                // Check for cycles in the map
2019:                Symbol[] ctors = new Symbol[0];
2020:                ctors = callMap.keySet().toArray(ctors);
2021:                for (Symbol caller : ctors) {
2022:                    checkCyclicConstructor(tree, caller, callMap);
2023:                }
2024:            }
2025:
2026:            /** Look in the map to see if the given constructor is part of a
2027:             *  call cycle.
2028:             */
2029:            private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
2030:                    Map<Symbol, Symbol> callMap) {
2031:                if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
2032:                    if ((ctor.flags_field & LOCKED) != 0) {
2033:                        log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
2034:                                "recursive.ctor.invocation");
2035:                    } else {
2036:                        ctor.flags_field |= LOCKED;
2037:                        checkCyclicConstructor(tree, callMap.remove(ctor),
2038:                                callMap);
2039:                        ctor.flags_field &= ~LOCKED;
2040:                    }
2041:                    ctor.flags_field |= ACYCLIC;
2042:                }
2043:            }
2044:
2045:            /* *************************************************************************
2046:             * Miscellaneous
2047:             **************************************************************************/
2048:
2049:            /**
2050:             * Return the opcode of the operator but emit an error if it is an
2051:             * error.
2052:             * @param pos        position for error reporting.
2053:             * @param operator   an operator
2054:             * @param tag        a tree tag
2055:             * @param left       type of left hand side
2056:             * @param right      type of right hand side
2057:             */
2058:            int checkOperator(DiagnosticPosition pos, OperatorSymbol operator,
2059:                    int tag, Type left, Type right) {
2060:                if (operator.opcode == ByteCodes.error) {
2061:                    log.error(pos, "operator.cant.be.applied", treeinfo
2062:                            .operatorName(tag), left + "," + right);
2063:                }
2064:                return operator.opcode;
2065:            }
2066:
2067:            /**
2068:             *  Check for division by integer constant zero
2069:             *	@param pos	     Position for error reporting.
2070:             *	@param operator      The operator for the expression
2071:             *	@param operand       The right hand operand for the expression
2072:             */
2073:            void checkDivZero(DiagnosticPosition pos, Symbol operator,
2074:                    Type operand) {
2075:                if (operand.constValue() != null
2076:                        && lint.isEnabled(Lint.LintCategory.DIVZERO)
2077:                        && operand.tag <= LONG
2078:                        && ((Number) (operand.constValue())).longValue() == 0) {
2079:                    int opc = ((OperatorSymbol) operator).opcode;
2080:                    if (opc == ByteCodes.idiv || opc == ByteCodes.imod
2081:                            || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
2082:                        log.warning(pos, "div.zero");
2083:                    }
2084:                }
2085:            }
2086:
2087:            /**
2088:             * Check for empty statements after if
2089:             */
2090:            void checkEmptyIf(JCIf tree) {
2091:                if (tree.thenpart.getTag() == JCTree.SKIP
2092:                        && tree.elsepart == null
2093:                        && lint.isEnabled(Lint.LintCategory.EMPTY))
2094:                    log.warning(tree.thenpart.pos(), "empty.if");
2095:            }
2096:
2097:            /** Check that symbol is unique in given scope.
2098:             *	@param pos	     Position for error reporting.
2099:             *	@param sym	     The symbol.
2100:             *	@param s	     The scope.
2101:             */
2102:            boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
2103:                if (sym.type.isErroneous())
2104:                    return true;
2105:                if (sym.owner.name == names.any)
2106:                    return false;
2107:                for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e
2108:                        .next()) {
2109:                    if (sym != e.sym
2110:                            && sym.kind == e.sym.kind
2111:                            && sym.name != names.error
2112:                            && (sym.kind != MTH || types.overrideEquivalent(
2113:                                    sym.type, e.sym.type))) {
2114:                        if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS))
2115:                            varargsDuplicateError(pos, sym, e.sym);
2116:                        else
2117:                            duplicateError(pos, e.sym);
2118:                        return false;
2119:                    }
2120:                }
2121:                return true;
2122:            }
2123:
2124:            /** Check that single-type import is not already imported or top-level defined,
2125:             *	but make an exception for two single-type imports which denote the same type.
2126:             *	@param pos	     Position for error reporting.
2127:             *	@param sym	     The symbol.
2128:             *	@param s	     The scope
2129:             */
2130:            boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym,
2131:                    Scope s) {
2132:                return checkUniqueImport(pos, sym, s, false);
2133:            }
2134:
2135:            /** Check that static single-type import is not already imported or top-level defined,
2136:             *	but make an exception for two single-type imports which denote the same type.
2137:             *	@param pos	     Position for error reporting.
2138:             *	@param sym	     The symbol.
2139:             *	@param s	     The scope
2140:             *  @param staticImport  Whether or not this was a static import
2141:             */
2142:            boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym,
2143:                    Scope s) {
2144:                return checkUniqueImport(pos, sym, s, true);
2145:            }
2146:
2147:            /** Check that single-type import is not already imported or top-level defined,
2148:             *	but make an exception for two single-type imports which denote the same type.
2149:             *	@param pos	     Position for error reporting.
2150:             *	@param sym	     The symbol.
2151:             *	@param s	     The scope.
2152:             *  @param staticImport  Whether or not this was a static import
2153:             */
2154:            private boolean checkUniqueImport(DiagnosticPosition pos,
2155:                    Symbol sym, Scope s, boolean staticImport) {
2156:                for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e
2157:                        .next()) {
2158:                    // is encountered class entered via a class declaration?
2159:                    boolean isClassDecl = e.scope == s;
2160:                    if ((isClassDecl || sym != e.sym) && sym.kind == e.sym.kind
2161:                            && sym.name != names.error) {
2162:                        if (!e.sym.type.isErroneous()) {
2163:                            String what = e.sym.toString();
2164:                            if (!isClassDecl) {
2165:                                if (staticImport)
2166:                                    log
2167:                                            .error(
2168:                                                    pos,
2169:                                                    "already.defined.static.single.import",
2170:                                                    what);
2171:                                else
2172:                                    log.error(pos,
2173:                                            "already.defined.single.import",
2174:                                            what);
2175:                            } else if (sym != e.sym)
2176:                                log.error(pos, "already.defined.this.unit",
2177:                                        what);
2178:                        }
2179:                        return false;
2180:                    }
2181:                }
2182:                return true;
2183:            }
2184:
2185:            /** Check that a qualified name is in canonical form (for import decls).
2186:             */
2187:            public void checkCanonical(JCTree tree) {
2188:                if (!isCanonical(tree))
2189:                    log.error(tree.pos(), "import.requires.canonical", TreeInfo
2190:                            .symbol(tree));
2191:            }
2192:
2193:            // where
2194:            private boolean isCanonical(JCTree tree) {
2195:                while (tree.getTag() == JCTree.SELECT) {
2196:                    JCFieldAccess s = (JCFieldAccess) tree;
2197:                    if (s.sym.owner != TreeInfo.symbol(s.selected))
2198:                        return false;
2199:                    tree = s.selected;
2200:                }
2201:                return true;
2202:            }
2203:
2204:            private class ConversionWarner extends Warner {
2205:                final String key;
2206:                final Type found;
2207:                final Type expected;
2208:
2209:                public ConversionWarner(DiagnosticPosition pos, String key,
2210:                        Type found, Type expected) {
2211:                    super (pos);
2212:                    this .key = key;
2213:                    this .found = found;
2214:                    this .expected = expected;
2215:                }
2216:
2217:                public void warnUnchecked() {
2218:                    boolean warned = this .warned;
2219:                    super .warnUnchecked();
2220:                    if (warned)
2221:                        return; // suppress redundant diagnostics
2222:                    Object problem = JCDiagnostic.fragment(key);
2223:                    Check.this .warnUnchecked(pos(), "prob.found.req", problem,
2224:                            found, expected);
2225:                }
2226:            }
2227:
2228:            public Warner castWarner(DiagnosticPosition pos, Type found,
2229:                    Type expected) {
2230:                return new ConversionWarner(pos, "unchecked.cast.to.type",
2231:                        found, expected);
2232:            }
2233:
2234:            public Warner convertWarner(DiagnosticPosition pos, Type found,
2235:                    Type expected) {
2236:                return new ConversionWarner(pos, "unchecked.assign", found,
2237:                        expected);
2238:            }
2239:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.