Source Code Cross Referenced for Attr.java in  » 6.0-JDK-Modules-sun » javac-compiler » 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 sun » javac compiler » 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:        import javax.lang.model.element.ElementKind;
0031:        import javax.tools.JavaFileObject;
0032:
0033:        import com.sun.tools.javac.code.*;
0034:        import com.sun.tools.javac.jvm.*;
0035:        import com.sun.tools.javac.tree.*;
0036:        import com.sun.tools.javac.util.*;
0037:        import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
0038:        import com.sun.tools.javac.util.List;
0039:
0040:        import com.sun.tools.javac.jvm.Target;
0041:        import com.sun.tools.javac.code.Symbol.*;
0042:        import com.sun.tools.javac.tree.JCTree.*;
0043:        import com.sun.tools.javac.code.Type.*;
0044:
0045:        import com.sun.source.tree.IdentifierTree;
0046:        import com.sun.source.tree.MemberSelectTree;
0047:        import com.sun.source.tree.TreeVisitor;
0048:        import com.sun.source.util.SimpleTreeVisitor;
0049:
0050:        import static com.sun.tools.javac.code.Flags.*;
0051:        import static com.sun.tools.javac.code.Kinds.*;
0052:        import static com.sun.tools.javac.code.TypeTags.*;
0053:
0054:        /** This is the main context-dependent analysis phase in GJC. It
0055:         *  encompasses name resolution, type checking and constant folding as
0056:         *  subtasks. Some subtasks involve auxiliary classes.
0057:         *  @see Check
0058:         *  @see Resolve
0059:         *  @see ConstFold
0060:         *  @see Infer
0061:         *
0062:         *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
0063:         *  you write code that depends on this, you do so at your own risk.
0064:         *  This code and its internal interfaces are subject to change or
0065:         *  deletion without notice.</b>
0066:         */
0067:        @Version("@(#)Attr.java	1.229 07/06/19")
0068:        public class Attr extends JCTree.Visitor {
0069:            protected static final Context.Key<Attr> attrKey = new Context.Key<Attr>();
0070:
0071:            final Name.Table names;
0072:            final Log log;
0073:            final Symtab syms;
0074:            final Resolve rs;
0075:            final Check chk;
0076:            final MemberEnter memberEnter;
0077:            final TreeMaker make;
0078:            final ConstFold cfolder;
0079:            final Enter enter;
0080:            final Target target;
0081:            final Types types;
0082:            final Annotate annotate;
0083:
0084:            public static Attr instance(Context context) {
0085:                Attr instance = context.get(attrKey);
0086:                if (instance == null)
0087:                    instance = new Attr(context);
0088:                return instance;
0089:            }
0090:
0091:            protected Attr(Context context) {
0092:                context.put(attrKey, this );
0093:
0094:                names = Name.Table.instance(context);
0095:                log = Log.instance(context);
0096:                syms = Symtab.instance(context);
0097:                rs = Resolve.instance(context);
0098:                chk = Check.instance(context);
0099:                memberEnter = MemberEnter.instance(context);
0100:                make = TreeMaker.instance(context);
0101:                enter = Enter.instance(context);
0102:                cfolder = ConstFold.instance(context);
0103:                target = Target.instance(context);
0104:                types = Types.instance(context);
0105:                annotate = Annotate.instance(context);
0106:
0107:                Options options = Options.instance(context);
0108:
0109:                Source source = Source.instance(context);
0110:                allowGenerics = source.allowGenerics();
0111:                allowVarargs = source.allowVarargs();
0112:                allowEnums = source.allowEnums();
0113:                allowBoxing = source.allowBoxing();
0114:                allowCovariantReturns = source.allowCovariantReturns();
0115:                allowAnonOuterThis = source.allowAnonOuterThis();
0116:                relax = (options.get("-retrofit") != null || options
0117:                        .get("-relax") != null);
0118:                useBeforeDeclarationWarning = options
0119:                        .get("useBeforeDeclarationWarning") != null;
0120:            }
0121:
0122:            /** Switch: relax some constraints for retrofit mode.
0123:             */
0124:            boolean relax;
0125:
0126:            /** Switch: support generics?
0127:             */
0128:            boolean allowGenerics;
0129:
0130:            /** Switch: allow variable-arity methods.
0131:             */
0132:            boolean allowVarargs;
0133:
0134:            /** Switch: support enums?
0135:             */
0136:            boolean allowEnums;
0137:
0138:            /** Switch: support boxing and unboxing?
0139:             */
0140:            boolean allowBoxing;
0141:
0142:            /** Switch: support covariant result types?
0143:             */
0144:            boolean allowCovariantReturns;
0145:
0146:            /** Switch: allow references to surrounding object from anonymous
0147:             * objects during constructor call?
0148:             */
0149:            boolean allowAnonOuterThis;
0150:
0151:            /**
0152:             * Switch: warn about use of variable before declaration?
0153:             * RFE: 6425594
0154:             */
0155:            boolean useBeforeDeclarationWarning;
0156:
0157:            /** Check kind and type of given tree against protokind and prototype.
0158:             *  If check succeeds, store type in tree and return it.
0159:             *  If check fails, store errType in tree and return it.
0160:             *  No checks are performed if the prototype is a method type.
0161:             *  Its not necessary in this case since we know that kind and type
0162:             *  are correct.
0163:             *
0164:             *  @param tree     The tree whose kind and type is checked
0165:             *  @param owntype  The computed type of the tree
0166:             *  @param ownkind  The computed kind of the tree
0167:             *  @param pkind    The expected kind (or: protokind) of the tree
0168:             *  @param pt       The expected type (or: prototype) of the tree
0169:             */
0170:            Type check(JCTree tree, Type owntype, int ownkind, int pkind,
0171:                    Type pt) {
0172:                if (owntype.tag != ERROR && pt.tag != METHOD
0173:                        && pt.tag != FORALL) {
0174:                    if ((ownkind & ~pkind) == 0) {
0175:                        owntype = chk.checkType(tree.pos(), owntype, pt);
0176:                    } else {
0177:                        log.error(tree.pos(), "unexpected.type", Resolve
0178:                                .kindNames(pkind), Resolve.kindName(ownkind));
0179:                        owntype = syms.errType;
0180:                    }
0181:                }
0182:                tree.type = owntype;
0183:                return owntype;
0184:            }
0185:
0186:            /** Is given blank final variable assignable, i.e. in a scope where it
0187:             *  may be assigned to even though it is final?
0188:             *  @param v      The blank final variable.
0189:             *  @param env    The current environment.
0190:             */
0191:            boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
0192:                Symbol owner = env.info.scope.owner;
0193:                // owner refers to the innermost variable, method or
0194:                // initializer block declaration at this point.
0195:                return v.owner == owner
0196:                        || ((owner.name == names.init || // i.e. we are in a constructor
0197:                                owner.kind == VAR || // i.e. we are in a variable initializer
0198:                                (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block
0199:                                && v.owner == owner.owner && ((v.flags() & STATIC) != 0) == Resolve
0200:                                .isStatic(env));
0201:            }
0202:
0203:            /** Check that variable can be assigned to.
0204:             *  @param pos    The current source code position.
0205:             *  @param v      The assigned varaible
0206:             *  @param base   If the variable is referred to in a Select, the part
0207:             *                to the left of the `.', null otherwise.
0208:             *  @param env    The current environment.
0209:             */
0210:            void checkAssignable(DiagnosticPosition pos, VarSymbol v,
0211:                    JCTree base, Env<AttrContext> env) {
0212:                if ((v.flags() & FINAL) != 0
0213:                        && ((v.flags() & HASINIT) != 0 || !((base == null || (base
0214:                                .getTag() == JCTree.IDENT && TreeInfo
0215:                                .name(base) == names._this )) && isAssignableAsBlankFinal(
0216:                                v, env)))) {
0217:                    log.error(pos, "cant.assign.val.to.final.var", v);
0218:                }
0219:            }
0220:
0221:            /** Does tree represent a static reference to an identifier?
0222:             *  It is assumed that tree is either a SELECT or an IDENT.
0223:             *  We have to weed out selects from non-type names here.
0224:             *  @param tree    The candidate tree.
0225:             */
0226:            boolean isStaticReference(JCTree tree) {
0227:                if (tree.getTag() == JCTree.SELECT) {
0228:                    Symbol lsym = TreeInfo
0229:                            .symbol(((JCFieldAccess) tree).selected);
0230:                    if (lsym == null || lsym.kind != TYP) {
0231:                        return false;
0232:                    }
0233:                }
0234:                return true;
0235:            }
0236:
0237:            /** Is this symbol a type?
0238:             */
0239:            static boolean isType(Symbol sym) {
0240:                return sym != null && sym.kind == TYP;
0241:            }
0242:
0243:            /** The current `this' symbol.
0244:             *  @param env    The current environment.
0245:             */
0246:            Symbol this Sym(DiagnosticPosition pos, Env<AttrContext> env) {
0247:                return rs.resolveSelf(pos, env, env.enclClass.sym, names._this );
0248:            }
0249:
0250:            /** Attribute a parsed identifier.
0251:             * @param tree Parsed identifier name
0252:             * @param topLevel The toplevel to use
0253:             */
0254:            public Symbol attribIdent(JCTree tree, JCCompilationUnit topLevel) {
0255:                Env<AttrContext> localEnv = enter.topLevelEnv(topLevel);
0256:                localEnv.enclClass = make.ClassDef(make.Modifiers(0),
0257:                        syms.errSymbol.name, null, null, null, null);
0258:                localEnv.enclClass.sym = syms.errSymbol;
0259:                return tree.accept(identAttributer, localEnv);
0260:            }
0261:
0262:            // where
0263:            private TreeVisitor<Symbol, Env<AttrContext>> identAttributer = new IdentAttributer();
0264:
0265:            private class IdentAttributer extends
0266:                    SimpleTreeVisitor<Symbol, Env<AttrContext>> {
0267:                @Override
0268:                public Symbol visitMemberSelect(MemberSelectTree node,
0269:                        Env<AttrContext> env) {
0270:                    Symbol site = visit(node.getExpression(), env);
0271:                    if (site.kind == ERR)
0272:                        return site;
0273:                    Name name = (Name) node.getIdentifier();
0274:                    if (site.kind == PCK) {
0275:                        env.toplevel.packge = (PackageSymbol) site;
0276:                        return rs.findIdentInPackage(env, (TypeSymbol) site,
0277:                                name, TYP | PCK);
0278:                    } else {
0279:                        env.enclClass.sym = (ClassSymbol) site;
0280:                        return rs.findMemberType(env, site.asType(), name,
0281:                                (TypeSymbol) site);
0282:                    }
0283:                }
0284:
0285:                @Override
0286:                public Symbol visitIdentifier(IdentifierTree node,
0287:                        Env<AttrContext> env) {
0288:                    return rs.findIdent(env, (Name) node.getName(), TYP | PCK);
0289:                }
0290:            }
0291:
0292:            public Type coerce(Type etype, Type ttype) {
0293:                return cfolder.coerce(etype, ttype);
0294:            }
0295:
0296:            public Type attribType(JCTree node, TypeSymbol sym) {
0297:                Env<AttrContext> env = enter.typeEnvs.get(sym);
0298:                Env<AttrContext> localEnv = env.dup(node, env.info.dup());
0299:                return attribTree(node, localEnv, Kinds.TYP, Type.noType);
0300:            }
0301:
0302:            public Env<AttrContext> attribExprToTree(JCTree expr,
0303:                    Env<AttrContext> env, JCTree tree) {
0304:                breakTree = tree;
0305:                JavaFileObject prev = log.useSource(null);
0306:                try {
0307:                    attribExpr(expr, env);
0308:                } catch (BreakAttr b) {
0309:                    return b.env;
0310:                } finally {
0311:                    breakTree = null;
0312:                    log.useSource(prev);
0313:                }
0314:                return env;
0315:            }
0316:
0317:            public Env<AttrContext> attribStatToTree(JCTree stmt,
0318:                    Env<AttrContext> env, JCTree tree) {
0319:                breakTree = tree;
0320:                JavaFileObject prev = log.useSource(null);
0321:                try {
0322:                    attribStat(stmt, env);
0323:                } catch (BreakAttr b) {
0324:                    return b.env;
0325:                } finally {
0326:                    breakTree = null;
0327:                    log.useSource(prev);
0328:                }
0329:                return env;
0330:            }
0331:
0332:            private JCTree breakTree = null;
0333:
0334:            private static class BreakAttr extends RuntimeException {
0335:                static final long serialVersionUID = -6924771130405446405L;
0336:                private Env<AttrContext> env;
0337:
0338:                private BreakAttr(Env<AttrContext> env) {
0339:                    this .env = env;
0340:                }
0341:            }
0342:
0343:            /* ************************************************************************
0344:             * Visitor methods
0345:             *************************************************************************/
0346:
0347:            /** Visitor argument: the current environment.
0348:             */
0349:            Env<AttrContext> env;
0350:
0351:            /** Visitor argument: the currently expected proto-kind.
0352:             */
0353:            int pkind;
0354:
0355:            /** Visitor argument: the currently expected proto-type.
0356:             */
0357:            Type pt;
0358:
0359:            /** Visitor result: the computed type.
0360:             */
0361:            Type result;
0362:
0363:            /** Visitor method: attribute a tree, catching any completion failure
0364:             *  exceptions. Return the tree's type.
0365:             *
0366:             *  @param tree    The tree to be visited.
0367:             *  @param env     The environment visitor argument.
0368:             *  @param pkind   The protokind visitor argument.
0369:             *  @param pt      The prototype visitor argument.
0370:             */
0371:            Type attribTree(JCTree tree, Env<AttrContext> env, int pkind,
0372:                    Type pt) {
0373:                Env<AttrContext> prevEnv = this .env;
0374:                int prevPkind = this .pkind;
0375:                Type prevPt = this .pt;
0376:                try {
0377:                    this .env = env;
0378:                    this .pkind = pkind;
0379:                    this .pt = pt;
0380:                    tree.accept(this );
0381:                    if (tree == breakTree)
0382:                        throw new BreakAttr(env);
0383:                    return result;
0384:                } catch (CompletionFailure ex) {
0385:                    tree.type = syms.errType;
0386:                    return chk.completionError(tree.pos(), ex);
0387:                } finally {
0388:                    this .env = prevEnv;
0389:                    this .pkind = prevPkind;
0390:                    this .pt = prevPt;
0391:                }
0392:            }
0393:
0394:            /** Derived visitor method: attribute an expression tree.
0395:             */
0396:            public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
0397:                return attribTree(tree, env, VAL, pt.tag != ERROR ? pt
0398:                        : Type.noType);
0399:            }
0400:
0401:            /** Derived visitor method: attribute an expression tree with
0402:             *  no constraints on the computed type.
0403:             */
0404:            Type attribExpr(JCTree tree, Env<AttrContext> env) {
0405:                return attribTree(tree, env, VAL, Type.noType);
0406:            }
0407:
0408:            /** Derived visitor method: attribute a type tree.
0409:             */
0410:            Type attribType(JCTree tree, Env<AttrContext> env) {
0411:                Type result = attribTree(tree, env, TYP, Type.noType);
0412:                return result;
0413:            }
0414:
0415:            /** Derived visitor method: attribute a statement or definition tree.
0416:             */
0417:            public Type attribStat(JCTree tree, Env<AttrContext> env) {
0418:                return attribTree(tree, env, NIL, Type.noType);
0419:            }
0420:
0421:            /** Attribute a list of expressions, returning a list of types.
0422:             */
0423:            List<Type> attribExprs(List<JCExpression> trees,
0424:                    Env<AttrContext> env, Type pt) {
0425:                ListBuffer<Type> ts = new ListBuffer<Type>();
0426:                for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
0427:                    ts.append(attribExpr(l.head, env, pt));
0428:                return ts.toList();
0429:            }
0430:
0431:            /** Attribute a list of statements, returning nothing.
0432:             */
0433:            <T extends JCTree> void attribStats(List<T> trees,
0434:                    Env<AttrContext> env) {
0435:                for (List<T> l = trees; l.nonEmpty(); l = l.tail)
0436:                    attribStat(l.head, env);
0437:            }
0438:
0439:            /** Attribute the arguments in a method call, returning a list of types.
0440:             */
0441:            List<Type> attribArgs(List<JCExpression> trees, Env<AttrContext> env) {
0442:                ListBuffer<Type> argtypes = new ListBuffer<Type>();
0443:                for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
0444:                    argtypes.append(chk.checkNonVoid(l.head.pos(), types
0445:                            .upperBound(attribTree(l.head, env, VAL,
0446:                                    Infer.anyPoly))));
0447:                return argtypes.toList();
0448:            }
0449:
0450:            /** Attribute a type argument list, returning a list of types.
0451:             */
0452:            List<Type> attribTypes(List<JCExpression> trees,
0453:                    Env<AttrContext> env) {
0454:                ListBuffer<Type> argtypes = new ListBuffer<Type>();
0455:                for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
0456:                    argtypes.append(chk.checkRefType(l.head.pos(), attribType(
0457:                            l.head, env)));
0458:                return argtypes.toList();
0459:            }
0460:
0461:            /**
0462:             * Attribute type variables (of generic classes or methods).
0463:             * Compound types are attributed later in attribBounds.
0464:             * @param typarams the type variables to enter
0465:             * @param env      the current environment
0466:             */
0467:            void attribTypeVariables(List<JCTypeParameter> typarams,
0468:                    Env<AttrContext> env) {
0469:                for (JCTypeParameter tvar : typarams) {
0470:                    TypeVar a = (TypeVar) tvar.type;
0471:                    if (!tvar.bounds.isEmpty()) {
0472:                        List<Type> bounds = List.of(attribType(
0473:                                tvar.bounds.head, env));
0474:                        for (JCExpression bound : tvar.bounds.tail)
0475:                            bounds = bounds.prepend(attribType(bound, env));
0476:                        types.setBounds(a, bounds.reverse());
0477:                    } else {
0478:                        // if no bounds are given, assume a single bound of
0479:                        // java.lang.Object.
0480:                        types.setBounds(a, List.of(syms.objectType));
0481:                    }
0482:                }
0483:                for (JCTypeParameter tvar : typarams)
0484:                    chk.checkNonCyclic(tvar.pos(), (TypeVar) tvar.type);
0485:                attribStats(typarams, env);
0486:            }
0487:
0488:            void attribBounds(List<JCTypeParameter> typarams) {
0489:                for (JCTypeParameter typaram : typarams) {
0490:                    Type bound = typaram.type.getUpperBound();
0491:                    if (bound != null && bound.tsym instanceof  ClassSymbol) {
0492:                        ClassSymbol c = (ClassSymbol) bound.tsym;
0493:                        if ((c.flags_field & COMPOUND) != 0) {
0494:                            assert (c.flags_field & UNATTRIBUTED) != 0 : c;
0495:                            attribClass(typaram.pos(), c);
0496:                        }
0497:                    }
0498:                }
0499:            }
0500:
0501:            /**
0502:             * Attribute the type references in a list of annotations.
0503:             */
0504:            void attribAnnotationTypes(List<JCAnnotation> annotations,
0505:                    Env<AttrContext> env) {
0506:                for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
0507:                    JCAnnotation a = al.head;
0508:                    attribType(a.annotationType, env);
0509:                }
0510:            }
0511:
0512:            /** Attribute type reference in an `extends' or `implements' clause.
0513:             *
0514:             *  @param tree              The tree making up the type reference.
0515:             *  @param env               The environment current at the reference.
0516:             *  @param classExpected     true if only a class is expected here.
0517:             *  @param interfaceExpected true if only an interface is expected here.
0518:             */
0519:            Type attribBase(JCTree tree, Env<AttrContext> env,
0520:                    boolean classExpected, boolean interfaceExpected,
0521:                    boolean checkExtensible) {
0522:                Type t = attribType(tree, env);
0523:                return checkBase(t, tree, env, classExpected,
0524:                        interfaceExpected, checkExtensible);
0525:            }
0526:
0527:            Type checkBase(Type t, JCTree tree, Env<AttrContext> env,
0528:                    boolean classExpected, boolean interfaceExpected,
0529:                    boolean checkExtensible) {
0530:                if (t.tag == TYPEVAR && !classExpected && !interfaceExpected) {
0531:                    // check that type variable is already visible
0532:                    if (t.getUpperBound() == null) {
0533:                        log.error(tree.pos(), "illegal.forward.ref");
0534:                        return syms.errType;
0535:                    }
0536:                } else {
0537:                    t = chk.checkClassType(tree.pos(), t, checkExtensible
0538:                            | !allowGenerics);
0539:                }
0540:                if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) {
0541:                    log.error(tree.pos(), "intf.expected.here");
0542:                    // return errType is necessary since otherwise there might
0543:                    // be undetected cycles which cause attribution to loop
0544:                    return syms.errType;
0545:                } else if (checkExtensible && classExpected
0546:                        && (t.tsym.flags() & INTERFACE) != 0) {
0547:                    log.error(tree.pos(), "no.intf.expected.here");
0548:                    return syms.errType;
0549:                }
0550:                if (checkExtensible && ((t.tsym.flags() & FINAL) != 0)) {
0551:                    log.error(tree.pos(), "cant.inherit.from.final", t.tsym);
0552:                }
0553:                chk.checkNonCyclic(tree.pos(), t);
0554:                return t;
0555:            }
0556:
0557:            public void visitClassDef(JCClassDecl tree) {
0558:                // Local classes have not been entered yet, so we need to do it now:
0559:                if ((env.info.scope.owner.kind & (VAR | MTH)) != 0)
0560:                    enter.classEnter(tree, env);
0561:
0562:                ClassSymbol c = tree.sym;
0563:                if (c == null) {
0564:                    // exit in case something drastic went wrong during enter.
0565:                    result = null;
0566:                } else {
0567:                    // make sure class has been completed:
0568:                    c.complete();
0569:
0570:                    // If this class appears as an anonymous class
0571:                    // in a superclass constructor call where
0572:                    // no explicit outer instance is given,
0573:                    // disable implicit outer instance from being passed.
0574:                    // (This would be an illegal access to "this before super").
0575:                    if (env.info.isSelfCall
0576:                            && env.tree.getTag() == JCTree.NEWCLASS
0577:                            && ((JCNewClass) env.tree).encl == null) {
0578:                        c.flags_field |= NOOUTERTHIS;
0579:                    }
0580:                    attribClass(tree.pos(), c);
0581:                    result = tree.type = c.type;
0582:                }
0583:            }
0584:
0585:            public void visitMethodDef(JCMethodDecl tree) {
0586:                MethodSymbol m = tree.sym;
0587:
0588:                Lint lint = env.info.lint
0589:                        .augment(m.attributes_field, m.flags());
0590:                Lint prevLint = chk.setLint(lint);
0591:                try {
0592:                    chk.checkDeprecatedAnnotation(tree.pos(), m);
0593:
0594:                    attribBounds(tree.typarams);
0595:
0596:                    // If we override any other methods, check that we do so properly.
0597:                    // JLS ???
0598:                    chk.checkOverride(tree, m);
0599:
0600:                    // Create a new environment with local scope
0601:                    // for attributing the method.
0602:                    Env<AttrContext> localEnv = memberEnter
0603:                            .methodEnv(tree, env);
0604:
0605:                    localEnv.info.lint = lint;
0606:
0607:                    // Enter all type parameters into the local method scope.
0608:                    for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
0609:                        localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
0610:
0611:                    ClassSymbol owner = env.enclClass.sym;
0612:                    if ((owner.flags() & ANNOTATION) != 0
0613:                            && tree.params.nonEmpty())
0614:                        log.error(tree.params.head.pos(),
0615:                                "intf.annotation.members.cant.have.params");
0616:
0617:                    // Attribute all value parameters.
0618:                    for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
0619:                        attribStat(l.head, localEnv);
0620:                    }
0621:
0622:                    // Check that type parameters are well-formed.
0623:                    chk.validateTypeParams(tree.typarams);
0624:                    if ((owner.flags() & ANNOTATION) != 0
0625:                            && tree.typarams.nonEmpty())
0626:                        log
0627:                                .error(tree.typarams.head.pos(),
0628:                                        "intf.annotation.members.cant.have.type.params");
0629:
0630:                    // Check that result type is well-formed.
0631:                    chk.validate(tree.restype);
0632:                    if ((owner.flags() & ANNOTATION) != 0)
0633:                        chk.validateAnnotationType(tree.restype);
0634:
0635:                    if ((owner.flags() & ANNOTATION) != 0)
0636:                        chk.validateAnnotationMethod(tree.pos(), m);
0637:
0638:                    // Check that all exceptions mentioned in the throws clause extend
0639:                    // java.lang.Throwable.
0640:                    if ((owner.flags() & ANNOTATION) != 0
0641:                            && tree.thrown.nonEmpty())
0642:                        log.error(tree.thrown.head.pos(),
0643:                                "throws.not.allowed.in.intf.annotation");
0644:                    for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail)
0645:                        chk.checkType(l.head.pos(), l.head.type,
0646:                                syms.throwableType);
0647:
0648:                    if (tree.body == null) {
0649:                        // Empty bodies are only allowed for
0650:                        // abstract, native, or interface methods, or for methods
0651:                        // in a retrofit signature class.
0652:                        if ((owner.flags() & INTERFACE) == 0
0653:                                && (tree.mods.flags & (ABSTRACT | NATIVE)) == 0
0654:                                && !relax)
0655:                            log.error(tree.pos(),
0656:                                    "missing.meth.body.or.decl.abstract");
0657:                        if (tree.defaultValue != null) {
0658:                            if ((owner.flags() & ANNOTATION) == 0)
0659:                                log
0660:                                        .error(tree.pos(),
0661:                                                "default.allowed.in.intf.annotation.member");
0662:                        }
0663:                    } else if ((owner.flags() & INTERFACE) != 0) {
0664:                        log.error(tree.body.pos(), "intf.meth.cant.have.body");
0665:                    } else if ((tree.mods.flags & ABSTRACT) != 0) {
0666:                        log.error(tree.pos(), "abstract.meth.cant.have.body");
0667:                    } else if ((tree.mods.flags & NATIVE) != 0) {
0668:                        log.error(tree.pos(), "native.meth.cant.have.body");
0669:                    } else {
0670:                        // Add an implicit super() call unless an explicit call to
0671:                        // super(...) or this(...) is given
0672:                        // or we are compiling class java.lang.Object.
0673:                        if (tree.name == names.init
0674:                                && owner.type != syms.objectType) {
0675:                            JCBlock body = tree.body;
0676:                            if (body.stats.isEmpty()
0677:                                    || !TreeInfo.isSelfCall(body.stats.head)) {
0678:                                body.stats = body.stats
0679:                                        .prepend(memberEnter.SuperCall(make
0680:                                                .at(body.pos), List
0681:                                                .<Type> nil(), List
0682:                                                .<JCVariableDecl> nil(), false));
0683:                            } else if ((env.enclClass.sym.flags() & ENUM) != 0
0684:                                    && (tree.mods.flags & GENERATEDCONSTR) == 0
0685:                                    && TreeInfo.isSuperCall(body.stats.head)) {
0686:                                // enum constructors are not allowed to call super
0687:                                // directly, so make sure there aren't any super calls
0688:                                // in enum constructors, except in the compiler
0689:                                // generated one.
0690:                                log
0691:                                        .error(
0692:                                                tree.body.stats.head.pos(),
0693:                                                "call.to.super.not.allowed.in.enum.ctor",
0694:                                                env.enclClass.sym);
0695:                            }
0696:                        }
0697:
0698:                        // Attribute method body.
0699:                        attribStat(tree.body, localEnv);
0700:                    }
0701:                    localEnv.info.scope.leave();
0702:                    result = tree.type = m.type;
0703:                    chk.validateAnnotations(tree.mods.annotations, m);
0704:
0705:                } finally {
0706:                    chk.setLint(prevLint);
0707:                }
0708:            }
0709:
0710:            public void visitVarDef(JCVariableDecl tree) {
0711:                // Local variables have not been entered yet, so we need to do it now:
0712:                if (env.info.scope.owner.kind == MTH) {
0713:                    if (tree.sym != null) {
0714:                        // parameters have already been entered
0715:                        env.info.scope.enter(tree.sym);
0716:                    } else {
0717:                        memberEnter.memberEnter(tree, env);
0718:                        annotate.flush();
0719:                    }
0720:                }
0721:
0722:                // Check that the variable's declared type is well-formed.
0723:                chk.validate(tree.vartype);
0724:
0725:                VarSymbol v = tree.sym;
0726:                Lint lint = env.info.lint
0727:                        .augment(v.attributes_field, v.flags());
0728:                Lint prevLint = chk.setLint(lint);
0729:
0730:                try {
0731:                    chk.checkDeprecatedAnnotation(tree.pos(), v);
0732:
0733:                    if (tree.init != null) {
0734:                        if ((v.flags_field & FINAL) != 0
0735:                                && tree.init.getTag() != JCTree.NEWCLASS) {
0736:                            // In this case, `v' is final.  Ensure that it's initializer is
0737:                            // evaluated.
0738:                            v.getConstValue(); // ensure initializer is evaluated
0739:                        } else {
0740:                            // Attribute initializer in a new environment
0741:                            // with the declared variable as owner.
0742:                            // Check that initializer conforms to variable's declared type.
0743:                            Env<AttrContext> initEnv = memberEnter.initEnv(
0744:                                    tree, env);
0745:                            initEnv.info.lint = lint;
0746:                            // In order to catch self-references, we set the variable's
0747:                            // declaration position to maximal possible value, effectively
0748:                            // marking the variable as undefined.
0749:                            v.pos = Position.MAXPOS;
0750:                            attribExpr(tree.init, initEnv, v.type);
0751:                            v.pos = tree.pos;
0752:                        }
0753:                    }
0754:                    result = tree.type = v.type;
0755:                    chk.validateAnnotations(tree.mods.annotations, v);
0756:                } finally {
0757:                    chk.setLint(prevLint);
0758:                }
0759:            }
0760:
0761:            public void visitSkip(JCSkip tree) {
0762:                result = null;
0763:            }
0764:
0765:            public void visitBlock(JCBlock tree) {
0766:                if (env.info.scope.owner.kind == TYP) {
0767:                    // Block is a static or instance initializer;
0768:                    // let the owner of the environment be a freshly
0769:                    // created BLOCK-method.
0770:                    Env<AttrContext> localEnv = env.dup(tree, env.info
0771:                            .dup(env.info.scope.dupUnshared()));
0772:                    localEnv.info.scope.owner = new MethodSymbol(tree.flags
0773:                            | BLOCK, names.empty, null, env.info.scope.owner);
0774:                    if ((tree.flags & STATIC) != 0)
0775:                        localEnv.info.staticLevel++;
0776:                    attribStats(tree.stats, localEnv);
0777:                } else {
0778:                    // Create a new local environment with a local scope.
0779:                    Env<AttrContext> localEnv = env.dup(tree, env.info
0780:                            .dup(env.info.scope.dup()));
0781:                    attribStats(tree.stats, localEnv);
0782:                    localEnv.info.scope.leave();
0783:                }
0784:                result = null;
0785:            }
0786:
0787:            public void visitDoLoop(JCDoWhileLoop tree) {
0788:                attribStat(tree.body, env.dup(tree));
0789:                attribExpr(tree.cond, env, syms.booleanType);
0790:                result = null;
0791:            }
0792:
0793:            public void visitWhileLoop(JCWhileLoop tree) {
0794:                attribExpr(tree.cond, env, syms.booleanType);
0795:                attribStat(tree.body, env.dup(tree));
0796:                result = null;
0797:            }
0798:
0799:            public void visitForLoop(JCForLoop tree) {
0800:                Env<AttrContext> loopEnv = env.dup(env.tree, env.info
0801:                        .dup(env.info.scope.dup()));
0802:                attribStats(tree.init, loopEnv);
0803:                if (tree.cond != null)
0804:                    attribExpr(tree.cond, loopEnv, syms.booleanType);
0805:                loopEnv.tree = tree; // before, we were not in loop!
0806:                attribStats(tree.step, loopEnv);
0807:                attribStat(tree.body, loopEnv);
0808:                loopEnv.info.scope.leave();
0809:                result = null;
0810:            }
0811:
0812:            public void visitForeachLoop(JCEnhancedForLoop tree) {
0813:                Env<AttrContext> loopEnv = env.dup(env.tree, env.info
0814:                        .dup(env.info.scope.dup()));
0815:                attribStat(tree.var, loopEnv);
0816:                Type exprType = types
0817:                        .upperBound(attribExpr(tree.expr, loopEnv));
0818:                chk.checkNonVoid(tree.pos(), exprType);
0819:                Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
0820:                if (elemtype == null) {
0821:                    // or perhaps expr implements Iterable<T>?
0822:                    Type base = types.asSuper(exprType, syms.iterableType.tsym);
0823:                    if (base == null) {
0824:                        log.error(tree.expr.pos(),
0825:                                "foreach.not.applicable.to.type");
0826:                        elemtype = syms.errType;
0827:                    } else {
0828:                        List<Type> iterableParams = base.allparams();
0829:                        elemtype = iterableParams.isEmpty() ? syms.objectType
0830:                                : types.upperBound(iterableParams.head);
0831:                    }
0832:                }
0833:                chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
0834:                loopEnv.tree = tree; // before, we were not in loop!
0835:                attribStat(tree.body, loopEnv);
0836:                loopEnv.info.scope.leave();
0837:                result = null;
0838:            }
0839:
0840:            public void visitLabelled(JCLabeledStatement tree) {
0841:                // Check that label is not used in an enclosing statement
0842:                Env<AttrContext> env1 = env;
0843:                while (env1 != null && env1.tree.getTag() != JCTree.CLASSDEF) {
0844:                    if (env1.tree.getTag() == JCTree.LABELLED
0845:                            && ((JCLabeledStatement) env1.tree).label == tree.label) {
0846:                        log.error(tree.pos(), "label.already.in.use",
0847:                                tree.label);
0848:                        break;
0849:                    }
0850:                    env1 = env1.next;
0851:                }
0852:
0853:                attribStat(tree.body, env.dup(tree));
0854:                result = null;
0855:            }
0856:
0857:            public void visitSwitch(JCSwitch tree) {
0858:                Type seltype = attribExpr(tree.selector, env);
0859:
0860:                Env<AttrContext> switchEnv = env.dup(tree, env.info
0861:                        .dup(env.info.scope.dup()));
0862:
0863:                boolean enumSwitch = allowEnums
0864:                        && (seltype.tsym.flags() & Flags.ENUM) != 0;
0865:                if (!enumSwitch)
0866:                    seltype = chk.checkType(tree.selector.pos(), seltype,
0867:                            syms.intType);
0868:
0869:                // Attribute all cases and
0870:                // check that there are no duplicate case labels or default clauses.
0871:                Set<Object> labels = new HashSet<Object>(); // The set of case labels.
0872:                boolean hasDefault = false; // Is there a default label?
0873:                for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
0874:                    JCCase c = l.head;
0875:                    Env<AttrContext> caseEnv = switchEnv.dup(c, env.info
0876:                            .dup(switchEnv.info.scope.dup()));
0877:                    if (c.pat != null) {
0878:                        if (enumSwitch) {
0879:                            Symbol sym = enumConstant(c.pat, seltype);
0880:                            if (sym == null) {
0881:                                log.error(c.pat.pos(), "enum.const.req");
0882:                            } else if (!labels.add(sym)) {
0883:                                log.error(c.pos(), "duplicate.case.label");
0884:                            }
0885:                        } else {
0886:                            Type pattype = attribExpr(c.pat, switchEnv, seltype);
0887:                            if (pattype.tag != ERROR) {
0888:                                if (pattype.constValue() == null) {
0889:                                    log.error(c.pat.pos(), "const.expr.req");
0890:                                } else if (labels
0891:                                        .contains(pattype.constValue())) {
0892:                                    log.error(c.pos(), "duplicate.case.label");
0893:                                } else {
0894:                                    labels.add(pattype.constValue());
0895:                                }
0896:                            }
0897:                        }
0898:                    } else if (hasDefault) {
0899:                        log.error(c.pos(), "duplicate.default.label");
0900:                    } else {
0901:                        hasDefault = true;
0902:                    }
0903:                    attribStats(c.stats, caseEnv);
0904:                    caseEnv.info.scope.leave();
0905:                    addVars(c.stats, switchEnv.info.scope);
0906:                }
0907:
0908:                switchEnv.info.scope.leave();
0909:                result = null;
0910:            }
0911:
0912:            // where
0913:            /** Add any variables defined in stats to the switch scope. */
0914:            private static void addVars(List<JCStatement> stats,
0915:                    Scope switchScope) {
0916:                for (; stats.nonEmpty(); stats = stats.tail) {
0917:                    JCTree stat = stats.head;
0918:                    if (stat.getTag() == JCTree.VARDEF)
0919:                        switchScope.enter(((JCVariableDecl) stat).sym);
0920:                }
0921:            }
0922:
0923:            // where
0924:            /** Return the selected enumeration constant symbol, or null. */
0925:            private Symbol enumConstant(JCTree tree, Type enumType) {
0926:                if (tree.getTag() != JCTree.IDENT) {
0927:                    log
0928:                            .error(tree.pos(),
0929:                                    "enum.label.must.be.unqualified.enum");
0930:                    return syms.errSymbol;
0931:                }
0932:                JCIdent ident = (JCIdent) tree;
0933:                Name name = ident.name;
0934:                for (Scope.Entry e = enumType.tsym.members().lookup(name); e.scope != null; e = e
0935:                        .next()) {
0936:                    if (e.sym.kind == VAR) {
0937:                        Symbol s = ident.sym = e.sym;
0938:                        ((VarSymbol) s).getConstValue(); // ensure initializer is evaluated
0939:                        ident.type = s.type;
0940:                        return ((s.flags_field & Flags.ENUM) == 0) ? null : s;
0941:                    }
0942:                }
0943:                return null;
0944:            }
0945:
0946:            public void visitSynchronized(JCSynchronized tree) {
0947:                chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
0948:                attribStat(tree.body, env);
0949:                result = null;
0950:            }
0951:
0952:            public void visitTry(JCTry tree) {
0953:                // Attribute body
0954:                attribStat(tree.body, env.dup(tree, env.info.dup()));
0955:
0956:                // Attribute catch clauses
0957:                for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
0958:                    JCCatch c = l.head;
0959:                    Env<AttrContext> catchEnv = env.dup(c, env.info
0960:                            .dup(env.info.scope.dup()));
0961:                    Type ctype = attribStat(c.param, catchEnv);
0962:                    if (c.param.type.tsym.kind == Kinds.VAR) {
0963:                        c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
0964:                    }
0965:                    chk.checkType(c.param.vartype.pos(), chk.checkClassType(
0966:                            c.param.vartype.pos(), ctype), syms.throwableType);
0967:                    attribStat(c.body, catchEnv);
0968:                    catchEnv.info.scope.leave();
0969:                }
0970:
0971:                // Attribute finalizer
0972:                if (tree.finalizer != null)
0973:                    attribStat(tree.finalizer, env);
0974:                result = null;
0975:            }
0976:
0977:            public void visitConditional(JCConditional tree) {
0978:                attribExpr(tree.cond, env, syms.booleanType);
0979:                attribExpr(tree.truepart, env);
0980:                attribExpr(tree.falsepart, env);
0981:                result = check(tree,
0982:                        capture(condType(tree.pos(), tree.cond.type,
0983:                                tree.truepart.type, tree.falsepart.type)), VAL,
0984:                        pkind, pt);
0985:            }
0986:
0987:            //where
0988:            /** Compute the type of a conditional expression, after
0989:             *  checking that it exists. See Spec 15.25.
0990:             *
0991:             *  @param pos      The source position to be used for
0992:             *                  error diagnostics.
0993:             *  @param condtype The type of the expression's condition.
0994:             *  @param thentype The type of the expression's then-part.
0995:             *  @param elsetype The type of the expression's else-part.
0996:             */
0997:            private Type condType(DiagnosticPosition pos, Type condtype,
0998:                    Type thentype, Type elsetype) {
0999:                Type ctype = condType1(pos, condtype, thentype, elsetype);
1000:
1001:                // If condition and both arms are numeric constants,
1002:                // evaluate at compile-time.
1003:                return ((condtype.constValue() != null)
1004:                        && (thentype.constValue() != null) && (elsetype
1005:                        .constValue() != null)) ? cfolder.coerce(condtype
1006:                        .isTrue() ? thentype : elsetype, ctype) : ctype;
1007:            }
1008:
1009:            /** Compute the type of a conditional expression, after
1010:             *  checking that it exists.  Does not take into
1011:             *  account the special case where condition and both arms
1012:             *  are constants.
1013:             *
1014:             *  @param pos      The source position to be used for error
1015:             *                  diagnostics.
1016:             *  @param condtype The type of the expression's condition.
1017:             *  @param thentype The type of the expression's then-part.
1018:             *  @param elsetype The type of the expression's else-part.
1019:             */
1020:            private Type condType1(DiagnosticPosition pos, Type condtype,
1021:                    Type thentype, Type elsetype) {
1022:                // If same type, that is the result
1023:                if (types.isSameType(thentype, elsetype))
1024:                    return thentype.baseType();
1025:
1026:                Type thenUnboxed = (!allowBoxing || thentype.isPrimitive()) ? thentype
1027:                        : types.unboxedType(thentype);
1028:                Type elseUnboxed = (!allowBoxing || elsetype.isPrimitive()) ? elsetype
1029:                        : types.unboxedType(elsetype);
1030:
1031:                // Otherwise, if both arms can be converted to a numeric
1032:                // type, return the least numeric type that fits both arms
1033:                // (i.e. return larger of the two, or return int if one
1034:                // arm is short, the other is char).
1035:                if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) {
1036:                    // If one arm has an integer subrange type (i.e., byte,
1037:                    // short, or char), and the other is an integer constant
1038:                    // that fits into the subrange, return the subrange type.
1039:                    if (thenUnboxed.tag < INT && elseUnboxed.tag == INT
1040:                            && types.isAssignable(elseUnboxed, thenUnboxed))
1041:                        return thenUnboxed.baseType();
1042:                    if (elseUnboxed.tag < INT && thenUnboxed.tag == INT
1043:                            && types.isAssignable(thenUnboxed, elseUnboxed))
1044:                        return elseUnboxed.baseType();
1045:
1046:                    for (int i = BYTE; i < VOID; i++) {
1047:                        Type candidate = syms.typeOfTag[i];
1048:                        if (types.isSubtype(thenUnboxed, candidate)
1049:                                && types.isSubtype(elseUnboxed, candidate))
1050:                            return candidate;
1051:                    }
1052:                }
1053:
1054:                // Those were all the cases that could result in a primitive
1055:                if (allowBoxing) {
1056:                    if (thentype.isPrimitive())
1057:                        thentype = types.boxedClass(thentype).type;
1058:                    if (elsetype.isPrimitive())
1059:                        elsetype = types.boxedClass(elsetype).type;
1060:                }
1061:
1062:                if (types.isSubtype(thentype, elsetype))
1063:                    return elsetype.baseType();
1064:                if (types.isSubtype(elsetype, thentype))
1065:                    return thentype.baseType();
1066:
1067:                if (!allowBoxing || thentype.tag == VOID
1068:                        || elsetype.tag == VOID) {
1069:                    log.error(pos, "neither.conditional.subtype", thentype,
1070:                            elsetype);
1071:                    return thentype.baseType();
1072:                }
1073:
1074:                // both are known to be reference types.  The result is
1075:                // lub(thentype,elsetype). This cannot fail, as it will
1076:                // always be possible to infer "Object" if nothing better.
1077:                return types.lub(thentype.baseType(), elsetype.baseType());
1078:            }
1079:
1080:            public void visitIf(JCIf tree) {
1081:                attribExpr(tree.cond, env, syms.booleanType);
1082:                attribStat(tree.thenpart, env);
1083:                if (tree.elsepart != null)
1084:                    attribStat(tree.elsepart, env);
1085:                chk.checkEmptyIf(tree);
1086:                result = null;
1087:            }
1088:
1089:            public void visitExec(JCExpressionStatement tree) {
1090:                attribExpr(tree.expr, env);
1091:                result = null;
1092:            }
1093:
1094:            public void visitBreak(JCBreak tree) {
1095:                tree.target = findJumpTarget(tree.pos(), tree.getTag(),
1096:                        tree.label, env);
1097:                result = null;
1098:            }
1099:
1100:            public void visitContinue(JCContinue tree) {
1101:                tree.target = findJumpTarget(tree.pos(), tree.getTag(),
1102:                        tree.label, env);
1103:                result = null;
1104:            }
1105:
1106:            //where
1107:            /** Return the target of a break or continue statement, if it exists,
1108:             *  report an error if not.
1109:             *  Note: The target of a labelled break or continue is the
1110:             *  (non-labelled) statement tree referred to by the label,
1111:             *  not the tree representing the labelled statement itself.
1112:             *
1113:             *  @param pos     The position to be used for error diagnostics
1114:             *  @param tag     The tag of the jump statement. This is either
1115:             *                 Tree.BREAK or Tree.CONTINUE.
1116:             *  @param label   The label of the jump statement, or null if no
1117:             *                 label is given.
1118:             *  @param env     The environment current at the jump statement.
1119:             */
1120:            private JCTree findJumpTarget(DiagnosticPosition pos, int tag,
1121:                    Name label, Env<AttrContext> env) {
1122:                // Search environments outwards from the point of jump.
1123:                Env<AttrContext> env1 = env;
1124:                LOOP: while (env1 != null) {
1125:                    switch (env1.tree.getTag()) {
1126:                    case JCTree.LABELLED:
1127:                        JCLabeledStatement labelled = (JCLabeledStatement) env1.tree;
1128:                        if (label == labelled.label) {
1129:                            // If jump is a continue, check that target is a loop.
1130:                            if (tag == JCTree.CONTINUE) {
1131:                                if (labelled.body.getTag() != JCTree.DOLOOP
1132:                                        && labelled.body.getTag() != JCTree.WHILELOOP
1133:                                        && labelled.body.getTag() != JCTree.FORLOOP
1134:                                        && labelled.body.getTag() != JCTree.FOREACHLOOP)
1135:                                    log.error(pos, "not.loop.label", label);
1136:                                // Found labelled statement target, now go inwards
1137:                                // to next non-labelled tree.
1138:                                return TreeInfo.referencedStatement(labelled);
1139:                            } else {
1140:                                return labelled;
1141:                            }
1142:                        }
1143:                        break;
1144:                    case JCTree.DOLOOP:
1145:                    case JCTree.WHILELOOP:
1146:                    case JCTree.FORLOOP:
1147:                    case JCTree.FOREACHLOOP:
1148:                        if (label == null)
1149:                            return env1.tree;
1150:                        break;
1151:                    case JCTree.SWITCH:
1152:                        if (label == null && tag == JCTree.BREAK)
1153:                            return env1.tree;
1154:                        break;
1155:                    case JCTree.METHODDEF:
1156:                    case JCTree.CLASSDEF:
1157:                        break LOOP;
1158:                    default:
1159:                    }
1160:                    env1 = env1.next;
1161:                }
1162:                if (label != null)
1163:                    log.error(pos, "undef.label", label);
1164:                else if (tag == JCTree.CONTINUE)
1165:                    log.error(pos, "cont.outside.loop");
1166:                else
1167:                    log.error(pos, "break.outside.switch.loop");
1168:                return null;
1169:            }
1170:
1171:            public void visitReturn(JCReturn tree) {
1172:                // Check that there is an enclosing method which is
1173:                // nested within than the enclosing class.
1174:                if (env.enclMethod == null
1175:                        || env.enclMethod.sym.owner != env.enclClass.sym) {
1176:                    log.error(tree.pos(), "ret.outside.meth");
1177:
1178:                } else {
1179:                    // Attribute return expression, if it exists, and check that
1180:                    // it conforms to result type of enclosing method.
1181:                    Symbol m = env.enclMethod.sym;
1182:                    if (m.type.getReturnType().tag == VOID) {
1183:                        if (tree.expr != null)
1184:                            log.error(tree.expr.pos(),
1185:                                    "cant.ret.val.from.meth.decl.void");
1186:                    } else if (tree.expr == null) {
1187:                        log.error(tree.pos(), "missing.ret.val");
1188:                    } else {
1189:                        attribExpr(tree.expr, env, m.type.getReturnType());
1190:                    }
1191:                }
1192:                result = null;
1193:            }
1194:
1195:            public void visitThrow(JCThrow tree) {
1196:                attribExpr(tree.expr, env, syms.throwableType);
1197:                result = null;
1198:            }
1199:
1200:            public void visitAssert(JCAssert tree) {
1201:                attribExpr(tree.cond, env, syms.booleanType);
1202:                if (tree.detail != null) {
1203:                    chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail,
1204:                            env));
1205:                }
1206:                result = null;
1207:            }
1208:
1209:            /** Visitor method for method invocations.
1210:             *  NOTE: The method part of an application will have in its type field
1211:             *        the return type of the method, not the method's type itself!
1212:             */
1213:            public void visitApply(JCMethodInvocation tree) {
1214:                // The local environment of a method application is
1215:                // a new environment nested in the current one.
1216:                Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
1217:
1218:                // The types of the actual method arguments.
1219:                List<Type> argtypes;
1220:
1221:                // The types of the actual method type arguments.
1222:                List<Type> typeargtypes = null;
1223:
1224:                Name methName = TreeInfo.name(tree.meth);
1225:
1226:                boolean isConstructorCall = methName == names._this 
1227:                        || methName == names._super ;
1228:
1229:                if (isConstructorCall) {
1230:                    // We are seeing a ...this(...) or ...super(...) call.
1231:                    // Check that this is the first statement in a constructor.
1232:                    if (checkFirstConstructorStat(tree, env)) {
1233:
1234:                        // Record the fact
1235:                        // that this is a constructor call (using isSelfCall).
1236:                        localEnv.info.isSelfCall = true;
1237:
1238:                        // Attribute arguments, yielding list of argument types.
1239:                        argtypes = attribArgs(tree.args, localEnv);
1240:                        typeargtypes = attribTypes(tree.typeargs, localEnv);
1241:
1242:                        // Variable `site' points to the class in which the called
1243:                        // constructor is defined.
1244:                        Type site = env.enclClass.sym.type;
1245:                        if (methName == names._super ) {
1246:                            if (site == syms.objectType) {
1247:                                log.error(tree.meth.pos(), "no.superclass",
1248:                                        site);
1249:                                site = syms.errType;
1250:                            } else {
1251:                                site = types.super type(site);
1252:                            }
1253:                        }
1254:
1255:                        if (site.tag == CLASS) {
1256:                            if (site.getEnclosingType().tag == CLASS) {
1257:                                // we are calling a nested class
1258:
1259:                                if (tree.meth.getTag() == JCTree.SELECT) {
1260:                                    JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
1261:
1262:                                    // We are seeing a prefixed call, of the form
1263:                                    //     <expr>.super(...).
1264:                                    // Check that the prefix expression conforms
1265:                                    // to the outer instance type of the class.
1266:                                    chk.checkRefType(qualifier.pos(),
1267:                                            attribExpr(qualifier, localEnv,
1268:                                                    site.getEnclosingType()));
1269:                                } else if (methName == names._super ) {
1270:                                    // qualifier omitted; check for existence
1271:                                    // of an appropriate implicit qualifier.
1272:                                    rs.resolveImplicitThis(tree.meth.pos(),
1273:                                            localEnv, site);
1274:                                }
1275:                            } else if (tree.meth.getTag() == JCTree.SELECT) {
1276:                                log.error(tree.meth.pos(),
1277:                                        "illegal.qual.not.icls", site.tsym);
1278:                            }
1279:
1280:                            // if we're calling a java.lang.Enum constructor,
1281:                            // prefix the implicit String and int parameters
1282:                            if (site.tsym == syms.enumSym && allowEnums)
1283:                                argtypes = argtypes.prepend(syms.intType)
1284:                                        .prepend(syms.stringType);
1285:
1286:                            // Resolve the called constructor under the assumption
1287:                            // that we are referring to a superclass instance of the
1288:                            // current instance (JLS ???).
1289:                            boolean selectSuperPrev = localEnv.info.selectSuper;
1290:                            localEnv.info.selectSuper = true;
1291:                            localEnv.info.varArgs = false;
1292:                            Symbol sym = rs.resolveConstructor(tree.meth.pos(),
1293:                                    localEnv, site, argtypes, typeargtypes);
1294:                            localEnv.info.selectSuper = selectSuperPrev;
1295:
1296:                            // Set method symbol to resolved constructor...
1297:                            TreeInfo.setSymbol(tree.meth, sym);
1298:
1299:                            // ...and check that it is legal in the current context.
1300:                            // (this will also set the tree's type)
1301:                            Type mpt = newMethTemplate(argtypes, typeargtypes);
1302:                            checkId(tree.meth, site, sym, localEnv, MTH, mpt,
1303:                                    tree.varargsElement != null);
1304:                        }
1305:                        // Otherwise, `site' is an error type and we do nothing
1306:                    }
1307:                    result = tree.type = syms.voidType;
1308:                } else {
1309:                    // Otherwise, we are seeing a regular method call.
1310:                    // Attribute the arguments, yielding list of argument types, ...
1311:                    argtypes = attribArgs(tree.args, localEnv);
1312:                    typeargtypes = attribTypes(tree.typeargs, localEnv);
1313:
1314:                    // ... and attribute the method using as a prototype a methodtype
1315:                    // whose formal argument types is exactly the list of actual
1316:                    // arguments (this will also set the method symbol).
1317:                    Type mpt = newMethTemplate(argtypes, typeargtypes);
1318:                    localEnv.info.varArgs = false;
1319:                    Type mtype = attribExpr(tree.meth, localEnv, mpt);
1320:                    if (localEnv.info.varArgs)
1321:                        assert mtype.isErroneous()
1322:                                || tree.varargsElement != null;
1323:
1324:                    // Compute the result type.
1325:                    Type restype = mtype.getReturnType();
1326:                    assert restype.tag != WILDCARD : mtype;
1327:
1328:                    // as a special case, array.clone() has a result that is
1329:                    // the same as static type of the array being cloned
1330:                    if (tree.meth.getTag() == JCTree.SELECT
1331:                            && allowCovariantReturns
1332:                            && methName == names.clone
1333:                            && types
1334:                                    .isArray(((JCFieldAccess) tree.meth).selected.type))
1335:                        restype = ((JCFieldAccess) tree.meth).selected.type;
1336:
1337:                    // as a special case, x.getClass() has type Class<? extends |X|>
1338:                    if (allowGenerics && methName == names.getClass
1339:                            && tree.args.isEmpty()) {
1340:                        Type qualifier = (tree.meth.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree.meth).selected.type
1341:                                : env.enclClass.sym.type;
1342:                        restype = new ClassType(restype.getEnclosingType(),
1343:                                List.<Type> of(new WildcardType(types
1344:                                        .erasure(qualifier), BoundKind.EXTENDS,
1345:                                        syms.boundClass)), restype.tsym);
1346:                    }
1347:
1348:                    // Check that value of resulting type is admissible in the
1349:                    // current context.  Also, capture the return type
1350:                    result = check(tree, capture(restype), VAL, pkind, pt);
1351:                }
1352:                chk.validate(tree.typeargs);
1353:            }
1354:
1355:            //where
1356:            /** Check that given application node appears as first statement
1357:             *  in a constructor call.
1358:             *  @param tree   The application node
1359:             *  @param env    The environment current at the application.
1360:             */
1361:            boolean checkFirstConstructorStat(JCMethodInvocation tree,
1362:                    Env<AttrContext> env) {
1363:                JCMethodDecl enclMethod = env.enclMethod;
1364:                if (enclMethod != null && enclMethod.name == names.init) {
1365:                    JCBlock body = enclMethod.body;
1366:                    if (body.stats.head.getTag() == JCTree.EXEC
1367:                            && ((JCExpressionStatement) body.stats.head).expr == tree)
1368:                        return true;
1369:                }
1370:                log.error(tree.pos(), "call.must.be.first.stmt.in.ctor",
1371:                        TreeInfo.name(tree.meth));
1372:                return false;
1373:            }
1374:
1375:            /** Obtain a method type with given argument types.
1376:             */
1377:            Type newMethTemplate(List<Type> argtypes, List<Type> typeargtypes) {
1378:                MethodType mt = new MethodType(argtypes, null, null,
1379:                        syms.methodClass);
1380:                return (typeargtypes == null) ? mt : (Type) new ForAll(
1381:                        typeargtypes, mt);
1382:            }
1383:
1384:            public void visitNewClass(JCNewClass tree) {
1385:                Type owntype = syms.errType;
1386:
1387:                // The local environment of a class creation is
1388:                // a new environment nested in the current one.
1389:                Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
1390:
1391:                // The anonymous inner class definition of the new expression,
1392:                // if one is defined by it.
1393:                JCClassDecl cdef = tree.def;
1394:
1395:                // If enclosing class is given, attribute it, and
1396:                // complete class name to be fully qualified
1397:                JCExpression clazz = tree.clazz; // Class field following new
1398:                JCExpression clazzid = // Identifier in class field
1399:                (clazz.getTag() == JCTree.TYPEAPPLY) ? ((JCTypeApply) clazz).clazz
1400:                        : clazz;
1401:
1402:                JCExpression clazzid1 = clazzid; // The same in fully qualified form
1403:
1404:                if (tree.encl != null) {
1405:                    // We are seeing a qualified new, of the form
1406:                    //    <expr>.new C <...> (...) ...
1407:                    // In this case, we let clazz stand for the name of the
1408:                    // allocated class C prefixed with the type of the qualifier
1409:                    // expression, so that we can
1410:                    // resolve it with standard techniques later. I.e., if
1411:                    // <expr> has type T, then <expr>.new C <...> (...)
1412:                    // yields a clazz T.C.
1413:                    Type encltype = chk.checkRefType(tree.encl.pos(),
1414:                            attribExpr(tree.encl, env));
1415:                    clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
1416:                            ((JCIdent) clazzid).name);
1417:                    if (clazz.getTag() == JCTree.TYPEAPPLY)
1418:                        clazz = make.at(tree.pos).TypeApply(clazzid1,
1419:                                ((JCTypeApply) clazz).arguments);
1420:                    else
1421:                        clazz = clazzid1;
1422:                    //          System.out.println(clazz + " generated.");//DEBUG
1423:                }
1424:
1425:                // Attribute clazz expression and store
1426:                // symbol + type back into the attributed tree.
1427:                Type clazztype = chk.checkClassType(tree.clazz.pos(),
1428:                        attribType(clazz, env), true);
1429:                chk.validate(clazz);
1430:                if (tree.encl != null) {
1431:                    // We have to work in this case to store
1432:                    // symbol + type back into the attributed tree.
1433:                    tree.clazz.type = clazztype;
1434:                    TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
1435:                    clazzid.type = ((JCIdent) clazzid).sym.type;
1436:                    if (!clazztype.isErroneous()) {
1437:                        if (cdef != null && clazztype.tsym.isInterface()) {
1438:                            log.error(tree.encl.pos(),
1439:                                    "anon.class.impl.intf.no.qual.for.new");
1440:                        } else if (clazztype.tsym.isStatic()) {
1441:                            log.error(tree.encl.pos(),
1442:                                    "qualified.new.of.static.class",
1443:                                    clazztype.tsym);
1444:                        }
1445:                    }
1446:                } else if (!clazztype.tsym.isInterface()
1447:                        && clazztype.getEnclosingType().tag == CLASS) {
1448:                    // Check for the existence of an apropos outer instance
1449:                    rs.resolveImplicitThis(tree.pos(), env, clazztype);
1450:                }
1451:
1452:                // Attribute constructor arguments.
1453:                List<Type> argtypes = attribArgs(tree.args, localEnv);
1454:                List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
1455:
1456:                // If we have made no mistakes in the class type...
1457:                if (clazztype.tag == CLASS) {
1458:                    // Enums may not be instantiated except implicitly
1459:                    if (allowEnums
1460:                            && (clazztype.tsym.flags_field & Flags.ENUM) != 0
1461:                            && (env.tree.getTag() != JCTree.VARDEF
1462:                                    || (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 || ((JCVariableDecl) env.tree).init != tree))
1463:                        log.error(tree.pos(), "enum.cant.be.instantiated");
1464:                    // Check that class is not abstract
1465:                    if (cdef == null
1466:                            && (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
1467:                        log.error(tree.pos(), "abstract.cant.be.instantiated",
1468:                                clazztype.tsym);
1469:                    } else if (cdef != null && clazztype.tsym.isInterface()) {
1470:                        // Check that no constructor arguments are given to
1471:                        // anonymous classes implementing an interface
1472:                        if (!argtypes.isEmpty())
1473:                            log.error(tree.args.head.pos(),
1474:                                    "anon.class.impl.intf.no.args");
1475:
1476:                        if (!typeargtypes.isEmpty())
1477:                            log.error(tree.typeargs.head.pos(),
1478:                                    "anon.class.impl.intf.no.typeargs");
1479:
1480:                        // Error recovery: pretend no arguments were supplied.
1481:                        argtypes = List.nil();
1482:                        typeargtypes = List.nil();
1483:                    }
1484:
1485:                    // Resolve the called constructor under the assumption
1486:                    // that we are referring to a superclass instance of the
1487:                    // current instance (JLS ???).
1488:                    else {
1489:                        localEnv.info.selectSuper = cdef != null;
1490:                        localEnv.info.varArgs = false;
1491:                        tree.constructor = rs.resolveConstructor(tree.pos(),
1492:                                localEnv, clazztype, argtypes, typeargtypes);
1493:                        Type ctorType = checkMethod(clazztype,
1494:                                tree.constructor, localEnv, tree.args,
1495:                                argtypes, typeargtypes, localEnv.info.varArgs);
1496:                        if (localEnv.info.varArgs)
1497:                            assert ctorType.isErroneous()
1498:                                    || tree.varargsElement != null;
1499:                    }
1500:
1501:                    if (cdef != null) {
1502:                        // We are seeing an anonymous class instance creation.
1503:                        // In this case, the class instance creation
1504:                        // expression
1505:                        //
1506:                        //    E.new <typeargs1>C<typargs2>(args) { ... }
1507:                        //
1508:                        // is represented internally as
1509:                        //
1510:                        //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
1511:                        //
1512:                        // This expression is then *transformed* as follows:
1513:                        //
1514:                        // (1) add a STATIC flag to the class definition
1515:                        //     if the current environment is static
1516:                        // (2) add an extends or implements clause
1517:                        // (3) add a constructor.
1518:                        //
1519:                        // For instance, if C is a class, and ET is the type of E,
1520:                        // the expression
1521:                        //
1522:                        //    E.new <typeargs1>C<typargs2>(args) { ... }
1523:                        //
1524:                        // is translated to (where X is a fresh name and typarams is the
1525:                        // parameter list of the super constructor):
1526:                        //
1527:                        //   new <typeargs1>X(<*nullchk*>E, args) where
1528:                        //     X extends C<typargs2> {
1529:                        //       <typarams> X(ET e, args) {
1530:                        //         e.<typeargs1>super(args)
1531:                        //       }
1532:                        //       ...
1533:                        //     }
1534:                        if (Resolve.isStatic(env))
1535:                            cdef.mods.flags |= STATIC;
1536:
1537:                        if (clazztype.tsym.isInterface()) {
1538:                            cdef.implementing = List.of(clazz);
1539:                        } else {
1540:                            cdef.extending = clazz;
1541:                        }
1542:
1543:                        attribStat(cdef, localEnv);
1544:
1545:                        // If an outer instance is given,
1546:                        // prefix it to the constructor arguments
1547:                        // and delete it from the new expression
1548:                        if (tree.encl != null && !clazztype.tsym.isInterface()) {
1549:                            tree.args = tree.args
1550:                                    .prepend(makeNullCheck(tree.encl));
1551:                            argtypes = argtypes.prepend(tree.encl.type);
1552:                            tree.encl = null;
1553:                        }
1554:
1555:                        // Reassign clazztype and recompute constructor.
1556:                        clazztype = cdef.sym.type;
1557:                        Symbol sym = rs.resolveConstructor(tree.pos(),
1558:                                localEnv, clazztype, argtypes, typeargtypes,
1559:                                true, tree.varargsElement != null);
1560:                        assert sym.kind < AMBIGUOUS
1561:                                || tree.constructor.type.isErroneous();
1562:                        tree.constructor = sym;
1563:                    }
1564:
1565:                    if (tree.constructor != null
1566:                            && tree.constructor.kind == MTH)
1567:                        owntype = clazztype;
1568:                }
1569:                result = check(tree, owntype, VAL, pkind, pt);
1570:                chk.validate(tree.typeargs);
1571:            }
1572:
1573:            /** Make an attributed null check tree.
1574:             */
1575:            public JCExpression makeNullCheck(JCExpression arg) {
1576:                // optimization: X.this is never null; skip null check
1577:                Name name = TreeInfo.name(arg);
1578:                if (name == names._this  || name == names._super )
1579:                    return arg;
1580:
1581:                int optag = JCTree.NULLCHK;
1582:                JCUnary tree = make.at(arg.pos).Unary(optag, arg);
1583:                tree.operator = syms.nullcheck;
1584:                tree.type = arg.type;
1585:                return tree;
1586:            }
1587:
1588:            public void visitNewArray(JCNewArray tree) {
1589:                Type owntype = syms.errType;
1590:                Type elemtype;
1591:                if (tree.elemtype != null) {
1592:                    elemtype = attribType(tree.elemtype, env);
1593:                    chk.validate(tree.elemtype);
1594:                    owntype = elemtype;
1595:                    for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
1596:                        attribExpr(l.head, env, syms.intType);
1597:                        owntype = new ArrayType(owntype, syms.arrayClass);
1598:                    }
1599:                } else {
1600:                    // we are seeing an untyped aggregate { ... }
1601:                    // this is allowed only if the prototype is an array
1602:                    if (pt.tag == ARRAY) {
1603:                        elemtype = types.elemtype(pt);
1604:                    } else {
1605:                        if (pt.tag != ERROR) {
1606:                            log.error(tree.pos(),
1607:                                    "illegal.initializer.for.type", pt);
1608:                        }
1609:                        elemtype = syms.errType;
1610:                    }
1611:                }
1612:                if (tree.elems != null) {
1613:                    attribExprs(tree.elems, env, elemtype);
1614:                    owntype = new ArrayType(elemtype, syms.arrayClass);
1615:                }
1616:                if (!types.isReifiable(elemtype))
1617:                    log.error(tree.pos(), "generic.array.creation");
1618:                result = check(tree, owntype, VAL, pkind, pt);
1619:            }
1620:
1621:            public void visitParens(JCParens tree) {
1622:                Type owntype = attribTree(tree.expr, env, pkind, pt);
1623:                result = check(tree, owntype, pkind, pkind, pt);
1624:                Symbol sym = TreeInfo.symbol(tree);
1625:                if (sym != null && (sym.kind & (TYP | PCK)) != 0)
1626:                    log.error(tree.pos(), "illegal.start.of.type");
1627:            }
1628:
1629:            public void visitAssign(JCAssign tree) {
1630:                Type owntype = attribTree(tree.lhs, env.dup(tree), VAR,
1631:                        Type.noType);
1632:                Type capturedType = capture(owntype);
1633:                attribExpr(tree.rhs, env, owntype);
1634:                result = check(tree, capturedType, VAL, pkind, pt);
1635:            }
1636:
1637:            public void visitAssignop(JCAssignOp tree) {
1638:                // Attribute arguments.
1639:                Type owntype = attribTree(tree.lhs, env, VAR, Type.noType);
1640:                Type operand = attribExpr(tree.rhs, env);
1641:                // Find operator.
1642:                Symbol operator = tree.operator = rs.resolveBinaryOperator(tree
1643:                        .pos(), tree.getTag() - JCTree.ASGOffset, env, owntype,
1644:                        operand);
1645:
1646:                if (operator.kind == MTH) {
1647:                    chk.checkOperator(tree.pos(), (OperatorSymbol) operator,
1648:                            tree.getTag() - JCTree.ASGOffset, owntype, operand);
1649:                    if (types.isSameType(operator.type.getReturnType(),
1650:                            syms.stringType)) {
1651:                        // String assignment; make sure the lhs is a string
1652:                        chk.checkType(tree.lhs.pos(), owntype, syms.stringType);
1653:                    } else {
1654:                        chk.checkDivZero(tree.rhs.pos(), operator, operand);
1655:                        chk.checkCastable(tree.rhs.pos(), operator.type
1656:                                .getReturnType(), owntype);
1657:                    }
1658:                }
1659:                result = check(tree, owntype, VAL, pkind, pt);
1660:            }
1661:
1662:            public void visitUnary(JCUnary tree) {
1663:                // Attribute arguments.
1664:                Type argtype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) ? attribTree(
1665:                        tree.arg, env, VAR, Type.noType)
1666:                        : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg,
1667:                                env));
1668:
1669:                // Find operator.
1670:                Symbol operator = tree.operator = rs.resolveUnaryOperator(tree
1671:                        .pos(), tree.getTag(), env, argtype);
1672:
1673:                Type owntype = syms.errType;
1674:                if (operator.kind == MTH) {
1675:                    owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) ? tree.arg.type
1676:                            : operator.type.getReturnType();
1677:                    int opc = ((OperatorSymbol) operator).opcode;
1678:
1679:                    // If the argument is constant, fold it.
1680:                    if (argtype.constValue() != null) {
1681:                        Type ctype = cfolder.fold1(opc, argtype);
1682:                        if (ctype != null) {
1683:                            owntype = cfolder.coerce(ctype, owntype);
1684:
1685:                            // Remove constant types from arguments to
1686:                            // conserve space. The parser will fold concatenations
1687:                            // of string literals; the code here also
1688:                            // gets rid of intermediate results when some of the
1689:                            // operands are constant identifiers.
1690:                            if (tree.arg.type.tsym == syms.stringType.tsym) {
1691:                                tree.arg.type = syms.stringType;
1692:                            }
1693:                        }
1694:                    }
1695:                }
1696:                result = check(tree, owntype, VAL, pkind, pt);
1697:            }
1698:
1699:            public void visitBinary(JCBinary tree) {
1700:                // Attribute arguments.
1701:                Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(
1702:                        tree.lhs, env));
1703:                Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(
1704:                        tree.rhs, env));
1705:
1706:                // Find operator.
1707:                Symbol operator = tree.operator = rs.resolveBinaryOperator(tree
1708:                        .pos(), tree.getTag(), env, left, right);
1709:
1710:                Type owntype = syms.errType;
1711:                if (operator.kind == MTH) {
1712:                    owntype = operator.type.getReturnType();
1713:                    int opc = chk.checkOperator(tree.lhs.pos(),
1714:                            (OperatorSymbol) operator, tree.getTag(), left,
1715:                            right);
1716:
1717:                    // If both arguments are constants, fold them.
1718:                    if (left.constValue() != null && right.constValue() != null) {
1719:                        Type ctype = cfolder.fold2(opc, left, right);
1720:                        if (ctype != null) {
1721:                            owntype = cfolder.coerce(ctype, owntype);
1722:
1723:                            // Remove constant types from arguments to
1724:                            // conserve space. The parser will fold concatenations
1725:                            // of string literals; the code here also
1726:                            // gets rid of intermediate results when some of the
1727:                            // operands are constant identifiers.
1728:                            if (tree.lhs.type.tsym == syms.stringType.tsym) {
1729:                                tree.lhs.type = syms.stringType;
1730:                            }
1731:                            if (tree.rhs.type.tsym == syms.stringType.tsym) {
1732:                                tree.rhs.type = syms.stringType;
1733:                            }
1734:                        }
1735:                    }
1736:
1737:                    // Check that argument types of a reference ==, != are
1738:                    // castable to each other, (JLS???).
1739:                    if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
1740:                        if (!types.isCastable(left, right, new Warner(tree
1741:                                .pos()))) {
1742:                            log.error(tree.pos(), "incomparable.types", left,
1743:                                    right);
1744:                        }
1745:                    }
1746:
1747:                    chk.checkDivZero(tree.rhs.pos(), operator, right);
1748:                }
1749:                result = check(tree, owntype, VAL, pkind, pt);
1750:            }
1751:
1752:            public void visitTypeCast(JCTypeCast tree) {
1753:                Type clazztype = attribType(tree.clazz, env);
1754:                Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
1755:                Type owntype = chk.checkCastable(tree.expr.pos(), exprtype,
1756:                        clazztype);
1757:                if (exprtype.constValue() != null)
1758:                    owntype = cfolder.coerce(exprtype, owntype);
1759:                result = check(tree, capture(owntype), VAL, pkind, pt);
1760:            }
1761:
1762:            public void visitTypeTest(JCInstanceOf tree) {
1763:                Type exprtype = chk.checkNullOrRefType(tree.expr.pos(),
1764:                        attribExpr(tree.expr, env));
1765:                Type clazztype = chk.checkReifiableReferenceType(tree.clazz
1766:                        .pos(), attribType(tree.clazz, env));
1767:                chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
1768:                result = check(tree, syms.booleanType, VAL, pkind, pt);
1769:            }
1770:
1771:            public void visitIndexed(JCArrayAccess tree) {
1772:                Type owntype = syms.errType;
1773:                Type atype = attribExpr(tree.indexed, env);
1774:                attribExpr(tree.index, env, syms.intType);
1775:                if (types.isArray(atype))
1776:                    owntype = types.elemtype(atype);
1777:                else if (atype.tag != ERROR)
1778:                    log.error(tree.pos(), "array.req.but.found", atype);
1779:                if ((pkind & VAR) == 0)
1780:                    owntype = capture(owntype);
1781:                result = check(tree, owntype, VAR, pkind, pt);
1782:            }
1783:
1784:            public void visitIdent(JCIdent tree) {
1785:                Symbol sym;
1786:                boolean varArgs = false;
1787:
1788:                // Find symbol
1789:                if (pt.tag == METHOD || pt.tag == FORALL) {
1790:                    // If we are looking for a method, the prototype `pt' will be a
1791:                    // method type with the type of the call's arguments as parameters.
1792:                    env.info.varArgs = false;
1793:                    sym = rs.resolveMethod(tree.pos(), env, tree.name, pt
1794:                            .getParameterTypes(), pt.getTypeArguments());
1795:                    varArgs = env.info.varArgs;
1796:                } else if (tree.sym != null && tree.sym.kind != VAR) {
1797:                    sym = tree.sym;
1798:                } else {
1799:                    sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind);
1800:                }
1801:                tree.sym = sym;
1802:
1803:                // (1) Also find the environment current for the class where
1804:                //     sym is defined (`symEnv').
1805:                // Only for pre-tiger versions (1.4 and earlier):
1806:                // (2) Also determine whether we access symbol out of an anonymous
1807:                //     class in a this or super call.  This is illegal for instance
1808:                //     members since such classes don't carry a this$n link.
1809:                //     (`noOuterThisPath').
1810:                Env<AttrContext> symEnv = env;
1811:                boolean noOuterThisPath = false;
1812:                if (env.enclClass.sym.owner.kind != PCK
1813:                        && // we are in an inner class
1814:                        (sym.kind & (VAR | MTH | TYP)) != 0
1815:                        && sym.owner.kind == TYP && tree.name != names._this 
1816:                        && tree.name != names._super ) {
1817:
1818:                    // Find environment in which identifier is defined.
1819:                    while (symEnv.outer != null
1820:                            && !sym.isMemberOf(symEnv.enclClass.sym, types)) {
1821:                        if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0)
1822:                            noOuterThisPath = !allowAnonOuterThis;
1823:                        symEnv = symEnv.outer;
1824:                    }
1825:                }
1826:
1827:                // If symbol is a variable, ...
1828:                if (sym.kind == VAR) {
1829:                    VarSymbol v = (VarSymbol) sym;
1830:
1831:                    // ..., evaluate its initializer, if it has one, and check for
1832:                    // illegal forward reference.
1833:                    checkInit(tree, env, v, false);
1834:
1835:                    // If symbol is a local variable accessed from an embedded
1836:                    // inner class check that it is final.
1837:                    if (v.owner.kind == MTH && v.owner != env.info.scope.owner
1838:                            && (v.flags_field & FINAL) == 0) {
1839:                        log.error(tree.pos(),
1840:                                "local.var.accessed.from.icls.needs.final", v);
1841:                    }
1842:
1843:                    // If we are expecting a variable (as opposed to a value), check
1844:                    // that the variable is assignable in the current environment.
1845:                    if (pkind == VAR)
1846:                        checkAssignable(tree.pos(), v, null, env);
1847:                }
1848:
1849:                // In a constructor body,
1850:                // if symbol is a field or instance method, check that it is
1851:                // not accessed before the supertype constructor is called.
1852:                if ((symEnv.info.isSelfCall || noOuterThisPath)
1853:                        && (sym.kind & (VAR | MTH)) != 0
1854:                        && sym.owner.kind == TYP && (sym.flags() & STATIC) == 0) {
1855:                    chk.earlyRefError(tree.pos(), sym.kind == VAR ? sym
1856:                            : this Sym(tree.pos(), env));
1857:                }
1858:                Env<AttrContext> env1 = env;
1859:                if (sym.kind != ERR && sym.owner != null
1860:                        && sym.owner != env1.enclClass.sym) {
1861:                    // If the found symbol is inaccessible, then it is
1862:                    // accessed through an enclosing instance.  Locate this
1863:                    // enclosing instance:
1864:                    while (env1.outer != null
1865:                            && !rs.isAccessible(env, env1.enclClass.sym.type,
1866:                                    sym))
1867:                        env1 = env1.outer;
1868:                }
1869:                result = checkId(tree, env1.enclClass.sym.type, sym, env,
1870:                        pkind, pt, varArgs);
1871:            }
1872:
1873:            public void visitSelect(JCFieldAccess tree) {
1874:                // Determine the expected kind of the qualifier expression.
1875:                int skind = 0;
1876:                if (tree.name == names._this  || tree.name == names._super 
1877:                        || tree.name == names._class) {
1878:                    skind = TYP;
1879:                } else {
1880:                    if ((pkind & PCK) != 0)
1881:                        skind = skind | PCK;
1882:                    if ((pkind & TYP) != 0)
1883:                        skind = skind | TYP | PCK;
1884:                    if ((pkind & (VAL | MTH)) != 0)
1885:                        skind = skind | VAL | TYP;
1886:                }
1887:
1888:                // Attribute the qualifier expression, and determine its symbol (if any).
1889:                Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);
1890:                if ((pkind & (PCK | TYP)) == 0)
1891:                    site = capture(site); // Capture field access
1892:
1893:                // don't allow T.class T[].class, etc
1894:                if (skind == TYP) {
1895:                    Type elt = site;
1896:                    while (elt.tag == ARRAY)
1897:                        elt = ((ArrayType) elt).elemtype;
1898:                    if (elt.tag == TYPEVAR) {
1899:                        log.error(tree.pos(), "type.var.cant.be.deref");
1900:                        result = syms.errType;
1901:                        return;
1902:                    }
1903:                }
1904:
1905:                // If qualifier symbol is a type or `super', assert `selectSuper'
1906:                // for the selection. This is relevant for determining whether
1907:                // protected symbols are accessible.
1908:                Symbol sitesym = TreeInfo.symbol(tree.selected);
1909:                boolean selectSuperPrev = env.info.selectSuper;
1910:                env.info.selectSuper = sitesym != null
1911:                        && sitesym.name == names._super ;
1912:
1913:                // If selected expression is polymorphic, strip
1914:                // type parameters and remember in env.info.tvars, so that
1915:                // they can be added later (in Attr.checkId and Infer.instantiateMethod).
1916:                if (tree.selected.type.tag == FORALL) {
1917:                    ForAll pstype = (ForAll) tree.selected.type;
1918:                    env.info.tvars = pstype.tvars;
1919:                    site = tree.selected.type = pstype.qtype;
1920:                }
1921:
1922:                // Determine the symbol represented by the selection.
1923:                env.info.varArgs = false;
1924:                Symbol sym = selectSym(tree, site, env, pt, pkind);
1925:                if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) {
1926:                    site = capture(site);
1927:                    sym = selectSym(tree, site, env, pt, pkind);
1928:                }
1929:                boolean varArgs = env.info.varArgs;
1930:                tree.sym = sym;
1931:
1932:                if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR)
1933:                    site = capture(site.getUpperBound());
1934:
1935:                // If that symbol is a variable, ...
1936:                if (sym.kind == VAR) {
1937:                    VarSymbol v = (VarSymbol) sym;
1938:
1939:                    // ..., evaluate its initializer, if it has one, and check for
1940:                    // illegal forward reference.
1941:                    checkInit(tree, env, v, true);
1942:
1943:                    // If we are expecting a variable (as opposed to a value), check
1944:                    // that the variable is assignable in the current environment.
1945:                    if (pkind == VAR)
1946:                        checkAssignable(tree.pos(), v, tree.selected, env);
1947:                }
1948:
1949:                // Disallow selecting a type from an expression
1950:                if (isType(sym)
1951:                        && (sitesym == null || (sitesym.kind & (TYP | PCK)) == 0)) {
1952:                    tree.type = check(tree.selected, pt, sitesym == null ? VAL
1953:                            : sitesym.kind, TYP | PCK, pt);
1954:                }
1955:
1956:                if (isType(sitesym)) {
1957:                    if (sym.name == names._this ) {
1958:                        // If `C' is the currently compiled class, check that
1959:                        // C.this' does not appear in a call to a super(...)
1960:                        if (env.info.isSelfCall
1961:                                && site.tsym == env.enclClass.sym) {
1962:                            chk.earlyRefError(tree.pos(), sym);
1963:                        }
1964:                    } else {
1965:                        // Check if type-qualified fields or methods are static (JLS)
1966:                        if ((sym.flags() & STATIC) == 0
1967:                                && sym.name != names._super 
1968:                                && (sym.kind == VAR || sym.kind == MTH)) {
1969:                            rs.access(rs.new StaticError(sym), tree.pos(),
1970:                                    site, sym.name, true);
1971:                        }
1972:                    }
1973:                }
1974:
1975:                // If we are selecting an instance member via a `super', ...
1976:                if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
1977:
1978:                    // Check that super-qualified symbols are not abstract (JLS)
1979:                    rs.checkNonAbstract(tree.pos(), sym);
1980:
1981:                    if (site.isRaw()) {
1982:                        // Determine argument types for site.
1983:                        Type site1 = types.asSuper(env.enclClass.sym.type,
1984:                                site.tsym);
1985:                        if (site1 != null)
1986:                            site = site1;
1987:                    }
1988:                }
1989:
1990:                env.info.selectSuper = selectSuperPrev;
1991:                result = checkId(tree, site, sym, env, pkind, pt, varArgs);
1992:                env.info.tvars = List.nil();
1993:            }
1994:
1995:            //where
1996:            /** Determine symbol referenced by a Select expression,
1997:             *
1998:             *  @param tree   The select tree.
1999:             *  @param site   The type of the selected expression,
2000:             *  @param env    The current environment.
2001:             *  @param pt     The current prototype.
2002:             *  @param pkind  The expected kind(s) of the Select expression.
2003:             */
2004:            private Symbol selectSym(JCFieldAccess tree, Type site,
2005:                    Env<AttrContext> env, Type pt, int pkind) {
2006:                DiagnosticPosition pos = tree.pos();
2007:                Name name = tree.name;
2008:
2009:                switch (site.tag) {
2010:                case PACKAGE:
2011:                    return rs.access(rs.findIdentInPackage(env, site.tsym,
2012:                            name, pkind), pos, site, name, true);
2013:                case ARRAY:
2014:                case CLASS:
2015:                    if (pt.tag == METHOD || pt.tag == FORALL) {
2016:                        return rs.resolveQualifiedMethod(pos, env, site, name,
2017:                                pt.getParameterTypes(), pt.getTypeArguments());
2018:                    } else if (name == names._this  || name == names._super ) {
2019:                        return rs.resolveSelf(pos, env, site.tsym, name);
2020:                    } else if (name == names._class) {
2021:                        // In this case, we have already made sure in
2022:                        // visitSelect that qualifier expression is a type.
2023:                        Type t = syms.classType;
2024:                        List<Type> typeargs = allowGenerics ? List.of(types
2025:                                .erasure(site)) : List.<Type> nil();
2026:                        t = new ClassType(t.getEnclosingType(), typeargs,
2027:                                t.tsym);
2028:                        return new VarSymbol(STATIC | PUBLIC | FINAL,
2029:                                names._class, t, site.tsym);
2030:                    } else {
2031:                        // We are seeing a plain identifier as selector.
2032:                        Symbol sym = rs.findIdentInType(env, site, name, pkind);
2033:                        if ((pkind & ERRONEOUS) == 0)
2034:                            sym = rs.access(sym, pos, site, name, true);
2035:                        return sym;
2036:                    }
2037:                case WILDCARD:
2038:                    throw new AssertionError(tree);
2039:                case TYPEVAR:
2040:                    // Normally, site.getUpperBound() shouldn't be null.
2041:                    // It should only happen during memberEnter/attribBase
2042:                    // when determining the super type which *must* be
2043:                    // done before attributing the type variables.  In
2044:                    // other words, we are seeing this illegal program:
2045:                    // class B<T> extends A<T.foo> {}
2046:                    Symbol sym = (site.getUpperBound() != null) ? selectSym(
2047:                            tree, capture(site.getUpperBound()), env, pt, pkind)
2048:                            : null;
2049:                    if (sym == null || isType(sym)) {
2050:                        log.error(pos, "type.var.cant.be.deref");
2051:                        return syms.errSymbol;
2052:                    } else {
2053:                        return sym;
2054:                    }
2055:                case ERROR:
2056:                    // preserve identifier names through errors
2057:                    return new ErrorType(name, site.tsym).tsym;
2058:                default:
2059:                    // The qualifier expression is of a primitive type -- only
2060:                    // .class is allowed for these.
2061:                    if (name == names._class) {
2062:                        // In this case, we have already made sure in Select that
2063:                        // qualifier expression is a type.
2064:                        Type t = syms.classType;
2065:                        Type arg = types.boxedClass(site).type;
2066:                        t = new ClassType(t.getEnclosingType(), List.of(arg),
2067:                                t.tsym);
2068:                        return new VarSymbol(STATIC | PUBLIC | FINAL,
2069:                                names._class, t, site.tsym);
2070:                    } else {
2071:                        log.error(pos, "cant.deref", site);
2072:                        return syms.errSymbol;
2073:                    }
2074:                }
2075:            }
2076:
2077:            /** Determine type of identifier or select expression and check that
2078:             *  (1) the referenced symbol is not deprecated
2079:             *  (2) the symbol's type is safe (@see checkSafe)
2080:             *  (3) if symbol is a variable, check that its type and kind are
2081:             *      compatible with the prototype and protokind.
2082:             *  (4) if symbol is an instance field of a raw type,
2083:             *      which is being assigned to, issue an unchecked warning if its
2084:             *      type changes under erasure.
2085:             *  (5) if symbol is an instance method of a raw type, issue an
2086:             *      unchecked warning if its argument types change under erasure.
2087:             *  If checks succeed:
2088:             *    If symbol is a constant, return its constant type
2089:             *    else if symbol is a method, return its result type
2090:             *    otherwise return its type.
2091:             *  Otherwise return errType.
2092:             *
2093:             *  @param tree       The syntax tree representing the identifier
2094:             *  @param site       If this is a select, the type of the selected
2095:             *                    expression, otherwise the type of the current class.
2096:             *  @param sym        The symbol representing the identifier.
2097:             *  @param env        The current environment.
2098:             *  @param pkind      The set of expected kinds.
2099:             *  @param pt         The expected type.
2100:             */
2101:            Type checkId(JCTree tree, Type site, Symbol sym,
2102:                    Env<AttrContext> env, int pkind, Type pt, boolean useVarargs) {
2103:                if (pt.isErroneous())
2104:                    return syms.errType;
2105:                Type owntype; // The computed type of this identifier occurrence.
2106:                switch (sym.kind) {
2107:                case TYP:
2108:                    // For types, the computed type equals the symbol's type,
2109:                    // except for two situations:
2110:                    owntype = sym.type;
2111:                    if (owntype.tag == CLASS) {
2112:                        Type ownOuter = owntype.getEnclosingType();
2113:
2114:                        // (a) If the symbol's type is parameterized, erase it
2115:                        // because no type parameters were given.
2116:                        // We recover generic outer type later in visitTypeApply.
2117:                        if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
2118:                            owntype = types.erasure(owntype);
2119:                        }
2120:
2121:                        // (b) If the symbol's type is an inner class, then
2122:                        // we have to interpret its outer type as a superclass
2123:                        // of the site type. Example:
2124:                        //
2125:                        // class Tree<A> { class Visitor { ... } }
2126:                        // class PointTree extends Tree<Point> { ... }
2127:                        // ...PointTree.Visitor...
2128:                        //
2129:                        // Then the type of the last expression above is
2130:                        // Tree<Point>.Visitor.
2131:                        else if (ownOuter.tag == CLASS && site != ownOuter) {
2132:                            Type normOuter = site;
2133:                            if (normOuter.tag == CLASS)
2134:                                normOuter = types.asEnclosingSuper(site,
2135:                                        ownOuter.tsym);
2136:                            if (normOuter == null) // perhaps from an import
2137:                                normOuter = types.erasure(ownOuter);
2138:                            if (normOuter != ownOuter)
2139:                                owntype = new ClassType(normOuter, List
2140:                                        .<Type> nil(), owntype.tsym);
2141:                        }
2142:                    }
2143:                    break;
2144:                case VAR:
2145:                    VarSymbol v = (VarSymbol) sym;
2146:                    // Test (4): if symbol is an instance field of a raw type,
2147:                    // which is being assigned to, issue an unchecked warning if
2148:                    // its type changes under erasure.
2149:                    if (allowGenerics && pkind == VAR && v.owner.kind == TYP
2150:                            && (v.flags() & STATIC) == 0
2151:                            && (site.tag == CLASS || site.tag == TYPEVAR)) {
2152:                        Type s = types.asOuterSuper(site, v.owner);
2153:                        if (s != null && s.isRaw()
2154:                                && !types.isSameType(v.type, v.erasure(types))) {
2155:                            chk.warnUnchecked(tree.pos(),
2156:                                    "unchecked.assign.to.var", v, s);
2157:                        }
2158:                    }
2159:                    // The computed type of a variable is the type of the
2160:                    // variable symbol, taken as a member of the site type.
2161:                    owntype = (sym.owner.kind == TYP && sym.name != names._this  && sym.name != names._super ) ? types
2162:                            .memberType(site, sym)
2163:                            : sym.type;
2164:
2165:                    if (env.info.tvars.nonEmpty()) {
2166:                        Type owntype1 = new ForAll(env.info.tvars, owntype);
2167:                        for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail)
2168:                            if (!owntype.contains(l.head)) {
2169:                                log.error(tree.pos(), "undetermined.type",
2170:                                        owntype1);
2171:                                owntype1 = syms.errType;
2172:                            }
2173:                        owntype = owntype1;
2174:                    }
2175:
2176:                    // If the variable is a constant, record constant value in
2177:                    // computed type.
2178:                    if (v.getConstValue() != null && isStaticReference(tree))
2179:                        owntype = owntype.constType(v.getConstValue());
2180:
2181:                    if (pkind == VAL) {
2182:                        owntype = capture(owntype); // capture "names as expressions"
2183:                    }
2184:                    break;
2185:                case MTH: {
2186:                    JCMethodInvocation app = (JCMethodInvocation) env.tree;
2187:                    owntype = checkMethod(site, sym, env, app.args, pt
2188:                            .getParameterTypes(), pt.getTypeArguments(),
2189:                            env.info.varArgs);
2190:                    break;
2191:                }
2192:                case PCK:
2193:                case ERR:
2194:                    owntype = sym.type;
2195:                    break;
2196:                default:
2197:                    throw new AssertionError("unexpected kind: " + sym.kind
2198:                            + " in tree " + tree);
2199:                }
2200:
2201:                // Test (1): emit a `deprecation' warning if symbol is deprecated.
2202:                // (for constructors, the error was given when the constructor was
2203:                // resolved)
2204:                if (sym.name != names.init
2205:                        && (sym.flags() & DEPRECATED) != 0
2206:                        && (env.info.scope.owner.flags() & DEPRECATED) == 0
2207:                        && sym.outermostClass() != env.info.scope.owner
2208:                                .outermostClass())
2209:                    chk.warnDeprecated(tree.pos(), sym);
2210:
2211:                if ((sym.flags() & PROPRIETARY) != 0)
2212:                    log.strictWarning(tree.pos(), "sun.proprietary", sym);
2213:
2214:                // Test (3): if symbol is a variable, check that its type and
2215:                // kind are compatible with the prototype and protokind.
2216:                return check(tree, owntype, sym.kind, pkind, pt);
2217:            }
2218:
2219:            /** Check that variable is initialized and evaluate the variable's
2220:             *  initializer, if not yet done. Also check that variable is not
2221:             *  referenced before it is defined.
2222:             *  @param tree    The tree making up the variable reference.
2223:             *  @param env     The current environment.
2224:             *  @param v       The variable's symbol.
2225:             */
2226:            private void checkInit(JCTree tree, Env<AttrContext> env,
2227:                    VarSymbol v, boolean onlyWarning) {
2228:                //          System.err.println(v + " " + ((v.flags() & STATIC) != 0) + " " +
2229:                //                             tree.pos + " " + v.pos + " " +
2230:                //                             Resolve.isStatic(env));//DEBUG
2231:
2232:                // A forward reference is diagnosed if the declaration position
2233:                // of the variable is greater than the current tree position
2234:                // and the tree and variable definition occur in the same class
2235:                // definition.  Note that writes don't count as references.
2236:                // This check applies only to class and instance
2237:                // variables.  Local variables follow different scope rules,
2238:                // and are subject to definite assignment checking.
2239:                if (v.pos > tree.pos
2240:                        && v.owner.kind == TYP
2241:                        && canOwnInitializer(env.info.scope.owner)
2242:                        && v.owner == env.info.scope.owner.enclClass()
2243:                        && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env)
2244:                        && (env.tree.getTag() != JCTree.ASSIGN || TreeInfo
2245:                                .skipParens(((JCAssign) env.tree).lhs) != tree)) {
2246:
2247:                    if (!onlyWarning || isNonStaticEnumField(v)) {
2248:                        log.error(tree.pos(), "illegal.forward.ref");
2249:                    } else if (useBeforeDeclarationWarning) {
2250:                        log.warning(tree.pos(), "forward.ref", v);
2251:                    }
2252:                }
2253:
2254:                v.getConstValue(); // ensure initializer is evaluated
2255:
2256:                checkEnumInitializer(tree, env, v);
2257:            }
2258:
2259:            /**
2260:             * Check for illegal references to static members of enum.  In
2261:             * an enum type, constructors and initializers may not
2262:             * reference its static members unless they are constant.
2263:             *
2264:             * @param tree    The tree making up the variable reference.
2265:             * @param env     The current environment.
2266:             * @param v       The variable's symbol.
2267:             * @see JLS 3rd Ed. (8.9 Enums)
2268:             */
2269:            private void checkEnumInitializer(JCTree tree,
2270:                    Env<AttrContext> env, VarSymbol v) {
2271:                // JLS 3rd Ed.:
2272:                //
2273:                // "It is a compile-time error to reference a static field
2274:                // of an enum type that is not a compile-time constant
2275:                // (15.28) from constructors, instance initializer blocks,
2276:                // or instance variable initializer expressions of that
2277:                // type. It is a compile-time error for the constructors,
2278:                // instance initializer blocks, or instance variable
2279:                // initializer expressions of an enum constant e to refer
2280:                // to itself or to an enum constant of the same type that
2281:                // is declared to the right of e."
2282:                if (isNonStaticEnumField(v)) {
2283:                    ClassSymbol enclClass = env.info.scope.owner.enclClass();
2284:
2285:                    if (enclClass == null || enclClass.owner == null)
2286:                        return;
2287:
2288:                    // See if the enclosing class is the enum (or a
2289:                    // subclass thereof) declaring v.  If not, this
2290:                    // reference is OK.
2291:                    if (v.owner != enclClass
2292:                            && !types.isSubtype(enclClass.type, v.owner.type))
2293:                        return;
2294:
2295:                    // If the reference isn't from an initializer, then
2296:                    // the reference is OK.
2297:                    if (!Resolve.isInitializer(env))
2298:                        return;
2299:
2300:                    log.error(tree.pos(), "illegal.enum.static.ref");
2301:                }
2302:            }
2303:
2304:            private boolean isNonStaticEnumField(VarSymbol v) {
2305:                return Flags.isEnum(v.owner) && Flags.isStatic(v)
2306:                        && !Flags.isConstant(v);
2307:            }
2308:
2309:            /** Can the given symbol be the owner of code which forms part
2310:             *  if class initialization? This is the case if the symbol is
2311:             *  a type or field, or if the symbol is the synthetic method.
2312:             *  owning a block.
2313:             */
2314:            private boolean canOwnInitializer(Symbol sym) {
2315:                return (sym.kind & (VAR | TYP)) != 0
2316:                        || (sym.kind == MTH && (sym.flags() & BLOCK) != 0);
2317:            }
2318:
2319:            Warner noteWarner = new Warner();
2320:
2321:            /**
2322:             * Check that method arguments conform to its instantation.
2323:             **/
2324:            public Type checkMethod(Type site, Symbol sym,
2325:                    Env<AttrContext> env, final List<JCExpression> argtrees,
2326:                    List<Type> argtypes, List<Type> typeargtypes,
2327:                    boolean useVarargs) {
2328:                // Test (5): if symbol is an instance method of a raw type, issue
2329:                // an unchecked warning if its argument types change under erasure.
2330:                if (allowGenerics && (sym.flags() & STATIC) == 0
2331:                        && (site.tag == CLASS || site.tag == TYPEVAR)) {
2332:                    Type s = types.asOuterSuper(site, sym.owner);
2333:                    if (s != null
2334:                            && s.isRaw()
2335:                            && !types.isSameTypes(sym.type.getParameterTypes(),
2336:                                    sym.erasure(types).getParameterTypes())) {
2337:                        chk.warnUnchecked(env.tree.pos(),
2338:                                "unchecked.call.mbr.of.raw.type", sym, s);
2339:                    }
2340:                }
2341:
2342:                // Compute the identifier's instantiated type.
2343:                // For methods, we need to compute the instance type by
2344:                // Resolve.instantiate from the symbol's type as well as
2345:                // any type arguments and value arguments.
2346:                noteWarner.warned = false;
2347:                Type owntype = rs.instantiate(env, site, sym, argtypes,
2348:                        typeargtypes, true, useVarargs, noteWarner);
2349:                boolean warned = noteWarner.warned;
2350:
2351:                // If this fails, something went wrong; we should not have
2352:                // found the identifier in the first place.
2353:                if (owntype == null) {
2354:                    if (!pt.isErroneous())
2355:                        log.error(env.tree.pos(),
2356:                                "internal.error.cant.instantiate", sym, site,
2357:                                Type.toString(pt.getParameterTypes()));
2358:                    owntype = syms.errType;
2359:                } else {
2360:                    // System.out.println("call   : " + env.tree);
2361:                    // System.out.println("method : " + owntype);
2362:                    // System.out.println("actuals: " + argtypes);
2363:                    List<Type> formals = owntype.getParameterTypes();
2364:                    Type last = useVarargs ? formals.last() : null;
2365:                    if (sym.name == names.init && sym.owner == syms.enumSym)
2366:                        formals = formals.tail.tail;
2367:                    List<JCExpression> args = argtrees;
2368:                    while (formals.head != last) {
2369:                        JCTree arg = args.head;
2370:                        Warner warn = chk.convertWarner(arg.pos(), arg.type,
2371:                                formals.head);
2372:                        assertConvertible(arg, arg.type, formals.head, warn);
2373:                        warned |= warn.warned;
2374:                        args = args.tail;
2375:                        formals = formals.tail;
2376:                    }
2377:                    if (useVarargs) {
2378:                        Type varArg = types.elemtype(last);
2379:                        while (args.tail != null) {
2380:                            JCTree arg = args.head;
2381:                            Warner warn = chk.convertWarner(arg.pos(),
2382:                                    arg.type, varArg);
2383:                            assertConvertible(arg, arg.type, varArg, warn);
2384:                            warned |= warn.warned;
2385:                            args = args.tail;
2386:                        }
2387:                    } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
2388:                        // non-varargs call to varargs method
2389:                        Type varParam = owntype.getParameterTypes().last();
2390:                        Type lastArg = argtypes.last();
2391:                        if (types.isSubtypeUnchecked(lastArg, types
2392:                                .elemtype(varParam))
2393:                                && !types.isSameType(types.erasure(varParam),
2394:                                        types.erasure(lastArg)))
2395:                            log.warning(argtrees.last().pos(),
2396:                                    "inexact.non-varargs.call", types
2397:                                            .elemtype(varParam), varParam);
2398:                    }
2399:
2400:                    if (warned && sym.type.tag == FORALL) {
2401:                        String typeargs = "";
2402:                        if (typeargtypes != null && typeargtypes.nonEmpty()) {
2403:                            typeargs = "<" + Type.toString(typeargtypes) + ">";
2404:                        }
2405:                        chk.warnUnchecked(env.tree.pos(),
2406:                                "unchecked.meth.invocation.applied", sym, sym
2407:                                        .location(), typeargs, Type
2408:                                        .toString(argtypes));
2409:                        owntype = new MethodType(owntype.getParameterTypes(),
2410:                                types.erasure(owntype.getReturnType()), owntype
2411:                                        .getThrownTypes(), syms.methodClass);
2412:                    }
2413:                    if (useVarargs) {
2414:                        JCTree tree = env.tree;
2415:                        Type argtype = owntype.getParameterTypes().last();
2416:                        if (!types.isReifiable(argtype))
2417:                            chk
2418:                                    .warnUnchecked(env.tree.pos(),
2419:                                            "unchecked.generic.array.creation",
2420:                                            argtype);
2421:                        Type elemtype = types.elemtype(argtype);
2422:                        switch (tree.getTag()) {
2423:                        case JCTree.APPLY:
2424:                            ((JCMethodInvocation) tree).varargsElement = elemtype;
2425:                            break;
2426:                        case JCTree.NEWCLASS:
2427:                            ((JCNewClass) tree).varargsElement = elemtype;
2428:                            break;
2429:                        default:
2430:                            throw new AssertionError("" + tree);
2431:                        }
2432:                    }
2433:                }
2434:                return owntype;
2435:            }
2436:
2437:            private void assertConvertible(JCTree tree, Type actual,
2438:                    Type formal, Warner warn) {
2439:                if (types.isConvertible(actual, formal, warn))
2440:                    return;
2441:
2442:                if (formal.isCompound()
2443:                        && types.isSubtype(actual, types.super type(formal))
2444:                        && types.isSubtypeUnchecked(actual, types
2445:                                .interfaces(formal), warn))
2446:                    return;
2447:
2448:                if (false) {
2449:                    // TODO: make assertConvertible work
2450:                    chk.typeError(tree.pos(), JCDiagnostic
2451:                            .fragment("incompatible.types"), actual, formal);
2452:                    throw new AssertionError("Tree: " + tree + " actual:"
2453:                            + actual + " formal: " + formal);
2454:                }
2455:            }
2456:
2457:            public void visitLiteral(JCLiteral tree) {
2458:                result = check(tree, litType(tree.typetag)
2459:                        .constType(tree.value), VAL, pkind, pt);
2460:            }
2461:
2462:            //where
2463:            /** Return the type of a literal with given type tag.
2464:             */
2465:            Type litType(int tag) {
2466:                return (tag == TypeTags.CLASS) ? syms.stringType
2467:                        : syms.typeOfTag[tag];
2468:            }
2469:
2470:            public void visitTypeIdent(JCPrimitiveTypeTree tree) {
2471:                result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind,
2472:                        pt);
2473:            }
2474:
2475:            public void visitTypeArray(JCArrayTypeTree tree) {
2476:                Type etype = attribType(tree.elemtype, env);
2477:                Type type = new ArrayType(etype, syms.arrayClass);
2478:                result = check(tree, type, TYP, pkind, pt);
2479:            }
2480:
2481:            /** Visitor method for parameterized types.
2482:             *  Bound checking is left until later, since types are attributed
2483:             *  before supertype structure is completely known
2484:             */
2485:            public void visitTypeApply(JCTypeApply tree) {
2486:                Type owntype = syms.errType;
2487:
2488:                // Attribute functor part of application and make sure it's a class.
2489:                Type clazztype = chk.checkClassType(tree.clazz.pos(),
2490:                        attribType(tree.clazz, env));
2491:
2492:                // Attribute type parameters
2493:                List<Type> actuals = attribTypes(tree.arguments, env);
2494:
2495:                if (clazztype.tag == CLASS) {
2496:                    List<Type> formals = clazztype.tsym.type.getTypeArguments();
2497:
2498:                    if (actuals.length() == formals.length()) {
2499:                        List<Type> a = actuals;
2500:                        List<Type> f = formals;
2501:                        while (a.nonEmpty()) {
2502:                            a.head = a.head.withTypeVar(f.head);
2503:                            a = a.tail;
2504:                            f = f.tail;
2505:                        }
2506:                        // Compute the proper generic outer
2507:                        Type clazzOuter = clazztype.getEnclosingType();
2508:                        if (clazzOuter.tag == CLASS) {
2509:                            Type site;
2510:                            if (tree.clazz.getTag() == JCTree.IDENT) {
2511:                                site = env.enclClass.sym.type;
2512:                            } else if (tree.clazz.getTag() == JCTree.SELECT) {
2513:                                site = ((JCFieldAccess) tree.clazz).selected.type;
2514:                            } else
2515:                                throw new AssertionError("" + tree);
2516:                            if (clazzOuter.tag == CLASS && site != clazzOuter) {
2517:                                if (site.tag == CLASS)
2518:                                    site = types.asOuterSuper(site,
2519:                                            clazzOuter.tsym);
2520:                                if (site == null)
2521:                                    site = types.erasure(clazzOuter);
2522:                                clazzOuter = site;
2523:                            }
2524:                        }
2525:                        owntype = new ClassType(clazzOuter, actuals,
2526:                                clazztype.tsym);
2527:                    } else {
2528:                        if (formals.length() != 0) {
2529:                            log.error(tree.pos(), "wrong.number.type.args",
2530:                                    Integer.toString(formals.length()));
2531:                        } else {
2532:                            log.error(tree.pos(), "type.doesnt.take.params",
2533:                                    clazztype.tsym);
2534:                        }
2535:                        owntype = syms.errType;
2536:                    }
2537:                }
2538:                result = check(tree, owntype, TYP, pkind, pt);
2539:            }
2540:
2541:            public void visitTypeParameter(JCTypeParameter tree) {
2542:                TypeVar a = (TypeVar) tree.type;
2543:                Set<Type> boundSet = new HashSet<Type>();
2544:                if (a.bound.isErroneous())
2545:                    return;
2546:                List<Type> bs = types.getBounds(a);
2547:                if (tree.bounds.nonEmpty()) {
2548:                    // accept class or interface or typevar as first bound.
2549:                    Type b = checkBase(bs.head, tree.bounds.head, env, false,
2550:                            false, false);
2551:                    boundSet.add(types.erasure(b));
2552:                    if (b.tag == TYPEVAR) {
2553:                        // if first bound was a typevar, do not accept further bounds.
2554:                        if (tree.bounds.tail.nonEmpty()) {
2555:                            log
2556:                                    .error(tree.bounds.tail.head.pos(),
2557:                                            "type.var.may.not.be.followed.by.other.bounds");
2558:                            tree.bounds = List.of(tree.bounds.head);
2559:                        }
2560:                    } else {
2561:                        // if first bound was a class or interface, accept only interfaces
2562:                        // as further bounds.
2563:                        for (JCExpression bound : tree.bounds.tail) {
2564:                            bs = bs.tail;
2565:                            Type i = checkBase(bs.head, bound, env, false,
2566:                                    true, false);
2567:                            if (i.tag == CLASS)
2568:                                chk.checkNotRepeated(bound.pos(), types
2569:                                        .erasure(i), boundSet);
2570:                        }
2571:                    }
2572:                }
2573:                bs = types.getBounds(a);
2574:
2575:                // in case of multiple bounds ...
2576:                if (bs.length() > 1) {
2577:                    // ... the variable's bound is a class type flagged COMPOUND
2578:                    // (see comment for TypeVar.bound).
2579:                    // In this case, generate a class tree that represents the
2580:                    // bound class, ...
2581:                    JCTree extending;
2582:                    List<JCExpression> implementing;
2583:                    if ((bs.head.tsym.flags() & INTERFACE) == 0) {
2584:                        extending = tree.bounds.head;
2585:                        implementing = tree.bounds.tail;
2586:                    } else {
2587:                        extending = null;
2588:                        implementing = tree.bounds;
2589:                    }
2590:                    JCClassDecl cd = make.at(tree.pos).ClassDef(
2591:                            make.Modifiers(PUBLIC | ABSTRACT), tree.name,
2592:                            List.<JCTypeParameter> nil(), extending,
2593:                            implementing, List.<JCTree> nil());
2594:
2595:                    ClassSymbol c = (ClassSymbol) a.getUpperBound().tsym;
2596:                    assert (c.flags() & COMPOUND) != 0;
2597:                    cd.sym = c;
2598:                    c.sourcefile = env.toplevel.sourcefile;
2599:
2600:                    // ... and attribute the bound class
2601:                    c.flags_field |= UNATTRIBUTED;
2602:                    Env<AttrContext> cenv = enter.classEnv(cd, env);
2603:                    enter.typeEnvs.put(c, cenv);
2604:                }
2605:            }
2606:
2607:            public void visitWildcard(JCWildcard tree) {
2608:                //- System.err.println("visitWildcard("+tree+");");//DEBUG
2609:                Type type = (tree.kind.kind == BoundKind.UNBOUND) ? syms.objectType
2610:                        : attribType(tree.inner, env);
2611:                result = check(tree, new WildcardType(chk.checkRefType(tree
2612:                        .pos(), type), tree.kind.kind, syms.boundClass), TYP,
2613:                        pkind, pt);
2614:            }
2615:
2616:            public void visitAnnotation(JCAnnotation tree) {
2617:                log.error(tree.pos(), "annotation.not.valid.for.type", pt);
2618:                result = tree.type = syms.errType;
2619:            }
2620:
2621:            public void visitErroneous(JCErroneous tree) {
2622:                if (tree.errs != null)
2623:                    for (JCTree err : tree.errs)
2624:                        attribTree(err, env, ERR, pt);
2625:                result = tree.type = syms.errType;
2626:            }
2627:
2628:            /** Default visitor method for all other trees.
2629:             */
2630:            public void visitTree(JCTree tree) {
2631:                throw new AssertionError();
2632:            }
2633:
2634:            /** Main method: attribute class definition associated with given class symbol.
2635:             *  reporting completion failures at the given position.
2636:             *  @param pos The source position at which completion errors are to be
2637:             *             reported.
2638:             *  @param c   The class symbol whose definition will be attributed.
2639:             */
2640:            public void attribClass(DiagnosticPosition pos, ClassSymbol c) {
2641:                try {
2642:                    annotate.flush();
2643:                    attribClass(c);
2644:                } catch (CompletionFailure ex) {
2645:                    chk.completionError(pos, ex);
2646:                }
2647:            }
2648:
2649:            /** Attribute class definition associated with given class symbol.
2650:             *  @param c   The class symbol whose definition will be attributed.
2651:             */
2652:            void attribClass(ClassSymbol c) throws CompletionFailure {
2653:                if (c.type.tag == ERROR)
2654:                    return;
2655:
2656:                // Check for cycles in the inheritance graph, which can arise from
2657:                // ill-formed class files.
2658:                chk.checkNonCyclic(null, c.type);
2659:
2660:                Type st = types.super type(c.type);
2661:                if ((c.flags_field & Flags.COMPOUND) == 0) {
2662:                    // First, attribute superclass.
2663:                    if (st.tag == CLASS)
2664:                        attribClass((ClassSymbol) st.tsym);
2665:
2666:                    // Next attribute owner, if it is a class.
2667:                    if (c.owner.kind == TYP && c.owner.type.tag == CLASS)
2668:                        attribClass((ClassSymbol) c.owner);
2669:                }
2670:
2671:                // The previous operations might have attributed the current class
2672:                // if there was a cycle. So we test first whether the class is still
2673:                // UNATTRIBUTED.
2674:                if ((c.flags_field & UNATTRIBUTED) != 0) {
2675:                    c.flags_field &= ~UNATTRIBUTED;
2676:
2677:                    // Get environment current at the point of class definition.
2678:                    Env<AttrContext> env = enter.typeEnvs.get(c);
2679:
2680:                    // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
2681:                    // because the annotations were not available at the time the env was created. Therefore,
2682:                    // we look up the environment chain for the first enclosing environment for which the
2683:                    // lint value is set. Typically, this is the parent env, but might be further if there
2684:                    // are any envs created as a result of TypeParameter nodes.
2685:                    Env<AttrContext> lintEnv = env;
2686:                    while (lintEnv.info.lint == null)
2687:                        lintEnv = lintEnv.next;
2688:
2689:                    // Having found the enclosing lint value, we can initialize the lint value for this class
2690:                    env.info.lint = lintEnv.info.lint.augment(
2691:                            c.attributes_field, c.flags());
2692:
2693:                    Lint prevLint = chk.setLint(env.info.lint);
2694:                    JavaFileObject prev = log.useSource(c.sourcefile);
2695:
2696:                    try {
2697:                        // java.lang.Enum may not be subclassed by a non-enum
2698:                        if (st.tsym == syms.enumSym
2699:                                && ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0))
2700:                            log.error(env.tree.pos(), "enum.no.subclassing");
2701:
2702:                        // Enums may not be extended by source-level classes
2703:                        if (st.tsym != null
2704:                                && ((st.tsym.flags_field & Flags.ENUM) != 0)
2705:                                && ((c.flags_field & Flags.ENUM) == 0)
2706:                                && !target.compilerBootstrap(c)) {
2707:                            log.error(env.tree.pos(),
2708:                                    "enum.types.not.extensible");
2709:                        }
2710:                        attribClassBody(env, c);
2711:
2712:                        chk.checkDeprecatedAnnotation(env.tree.pos(), c);
2713:                    } finally {
2714:                        log.useSource(prev);
2715:                        chk.setLint(prevLint);
2716:                    }
2717:
2718:                }
2719:            }
2720:
2721:            public void visitImport(JCImport tree) {
2722:                // nothing to do
2723:            }
2724:
2725:            /** Finish the attribution of a class. */
2726:            private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
2727:                JCClassDecl tree = (JCClassDecl) env.tree;
2728:                assert c == tree.sym;
2729:
2730:                // Validate annotations
2731:                chk.validateAnnotations(tree.mods.annotations, c);
2732:
2733:                // Validate type parameters, supertype and interfaces.
2734:                attribBounds(tree.typarams);
2735:                chk.validateTypeParams(tree.typarams);
2736:                chk.validate(tree.extending);
2737:                chk.validate(tree.implementing);
2738:
2739:                // If this is a non-abstract class, check that it has no abstract
2740:                // methods or unimplemented methods of an implemented interface.
2741:                if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
2742:                    if (!relax)
2743:                        chk.checkAllDefined(tree.pos(), c);
2744:                }
2745:
2746:                if ((c.flags() & ANNOTATION) != 0) {
2747:                    if (tree.implementing.nonEmpty())
2748:                        log.error(tree.implementing.head.pos(),
2749:                                "cant.extend.intf.annotation");
2750:                    if (tree.typarams.nonEmpty())
2751:                        log.error(tree.typarams.head.pos(),
2752:                                "intf.annotation.cant.have.type.params");
2753:                } else {
2754:                    // Check that all extended classes and interfaces
2755:                    // are compatible (i.e. no two define methods with same arguments
2756:                    // yet different return types).  (JLS 8.4.6.3)
2757:                    chk.checkCompatibleSupertypes(tree.pos(), c.type);
2758:                }
2759:
2760:                // Check that class does not import the same parameterized interface
2761:                // with two different argument lists.
2762:                chk.checkClassBounds(tree.pos(), c.type);
2763:
2764:                tree.type = c.type;
2765:
2766:                boolean assertsEnabled = false;
2767:                assert assertsEnabled = true;
2768:                if (assertsEnabled) {
2769:                    for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
2770:                        assert env.info.scope.lookup(l.head.name).scope != null;
2771:                }
2772:
2773:                // Check that a generic class doesn't extend Throwable
2774:                if (!c.type.allparams().isEmpty()
2775:                        && types.isSubtype(c.type, syms.throwableType))
2776:                    log.error(tree.extending.pos(), "generic.throwable");
2777:
2778:                // Check that all methods which implement some
2779:                // method conform to the method they implement.
2780:                chk.checkImplementations(tree);
2781:
2782:                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
2783:                    // Attribute declaration
2784:                    attribStat(l.head, env);
2785:                    // Check that declarations in inner classes are not static (JLS 8.1.2)
2786:                    // Make an exception for static constants.
2787:                    if (c.owner.kind != PCK
2788:                            && ((c.flags() & STATIC) == 0 || c.name == names.empty)
2789:                            && (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
2790:                        Symbol sym = null;
2791:                        if (l.head.getTag() == JCTree.VARDEF)
2792:                            sym = ((JCVariableDecl) l.head).sym;
2793:                        if (sym == null || sym.kind != VAR
2794:                                || ((VarSymbol) sym).getConstValue() == null)
2795:                            log.error(l.head.pos(),
2796:                                    "icls.cant.have.static.decl");
2797:                    }
2798:                }
2799:
2800:                // Check for cycles among non-initial constructors.
2801:                chk.checkCyclicConstructors(tree);
2802:
2803:                // Check for cycles among annotation elements.
2804:                chk.checkNonCyclicElements(tree);
2805:
2806:                // Check for proper use of serialVersionUID
2807:                if (env.info.lint.isEnabled(Lint.LintCategory.SERIAL)
2808:                        && isSerializable(c) && (c.flags() & Flags.ENUM) == 0
2809:                        && (c.flags() & ABSTRACT) == 0) {
2810:                    checkSerialVersionUID(tree, c);
2811:                }
2812:            }
2813:
2814:            // where
2815:            /** check if a class is a subtype of Serializable, if that is available. */
2816:            private boolean isSerializable(ClassSymbol c) {
2817:                try {
2818:                    syms.serializableType.complete();
2819:                } catch (CompletionFailure e) {
2820:                    return false;
2821:                }
2822:                return types.isSubtype(c.type, syms.serializableType);
2823:            }
2824:
2825:            /** Check that an appropriate serialVersionUID member is defined. */
2826:            private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) {
2827:
2828:                // check for presence of serialVersionUID
2829:                Scope.Entry e = c.members().lookup(names.serialVersionUID);
2830:                while (e.scope != null && e.sym.kind != VAR)
2831:                    e = e.next();
2832:                if (e.scope == null) {
2833:                    log.warning(tree.pos(), "missing.SVUID", c);
2834:                    return;
2835:                }
2836:
2837:                // check that it is static final
2838:                VarSymbol svuid = (VarSymbol) e.sym;
2839:                if ((svuid.flags() & (STATIC | FINAL)) != (STATIC | FINAL))
2840:                    log.warning(TreeInfo.diagnosticPositionFor(svuid, tree),
2841:                            "improper.SVUID", c);
2842:
2843:                // check that it is long
2844:                else if (svuid.type.tag != TypeTags.LONG)
2845:                    log.warning(TreeInfo.diagnosticPositionFor(svuid, tree),
2846:                            "long.SVUID", c);
2847:
2848:                // check constant
2849:                else if (svuid.getConstValue() == null)
2850:                    log.warning(TreeInfo.diagnosticPositionFor(svuid, tree),
2851:                            "constant.SVUID", c);
2852:            }
2853:
2854:            private Type capture(Type type) {
2855:                return types.capture(type);
2856:            }
2857:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.