Source Code Cross Referenced for Environment.java in  » 6.0-JDK-Modules-sun » tools » sun » tools » java » 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 » tools » sun.tools.java 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1994-2003 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 sun.tools.java;
0027:
0028:        import java.util.Stack;
0029:        import java.io.IOException;
0030:        import sun.tools.tree.Context; //JCOV
0031:        import java.io.File;
0032:
0033:        //end JCOV
0034:
0035:        /**
0036:         * This class defines the environment for a compilation.
0037:         * It is used to load classes, resolve class names and
0038:         * report errors. It is an abstract class, a subclass
0039:         * must define implementations for some of the functions.<p>
0040:         *
0041:         * An environment has a source object associated with it.
0042:         * This is the thing against which errors are reported, it
0043:         * is usually a file name, a field or a class.<p>
0044:         *
0045:         * Environments can be nested to change the source object.<p>
0046:         *
0047:         * WARNING: The contents of this source file are not part of any
0048:         * supported API.  Code that depends on them does so at its own risk:
0049:         * they are subject to change or removal without notice.
0050:         *
0051:         * @author 	Arthur van Hoff
0052:         * @version 1.82, 05/05/07
0053:         */
0054:
0055:        public class Environment implements  Constants {
0056:            /**
0057:             * The actual environment to which everything is forwarded.
0058:             */
0059:            Environment env;
0060:
0061:            /**
0062:             * External character encoding name
0063:             */
0064:            String encoding;
0065:
0066:            /**
0067:             * The object that is currently being parsed/compiled.
0068:             * It is either a file name (String) or a field (MemberDefinition)
0069:             * or a class (ClassDeclaration or ClassDefinition).
0070:             */
0071:            Object source;
0072:
0073:            public Environment(Environment env, Object source) {
0074:                if (env != null && env.env != null
0075:                        && env.getClass() == this .getClass())
0076:                    env = env.env; // a small optimization
0077:                this .env = env;
0078:                this .source = source;
0079:            }
0080:
0081:            public Environment() {
0082:                this (null, null);
0083:            }
0084:
0085:            /**
0086:             * Tells whether an Identifier refers to a package which should be
0087:             * exempt from the "exists" check in Imports#resolve().
0088:             */
0089:            public boolean isExemptPackage(Identifier id) {
0090:                return env.isExemptPackage(id);
0091:            }
0092:
0093:            /**
0094:             * Return a class declaration given a fully qualified class name.
0095:             */
0096:            public ClassDeclaration getClassDeclaration(Identifier nm) {
0097:                return env.getClassDeclaration(nm);
0098:            }
0099:
0100:            /**
0101:             * Return a class definition given a fully qualified class name.
0102:             * <p>
0103:             * Should be called only with 'internal' class names, i.e., the result
0104:             * of a call to 'resolveName' or a synthetic class name.
0105:             */
0106:            public final ClassDefinition getClassDefinition(Identifier nm)
0107:                    throws ClassNotFound {
0108:                if (nm.isInner()) {
0109:                    ClassDefinition c = getClassDefinition(nm.getTopName());
0110:                    Identifier tail = nm.getFlatName();
0111:                    walkTail: while (tail.isQualified()) {
0112:                        tail = tail.getTail();
0113:                        Identifier head = tail.getHead();
0114:                        //System.out.println("CLASS: " + c + " HEAD: " + head + " TAIL: " + tail);
0115:                        String hname = head.toString();
0116:                        // If the name is of the form 'ClassName.N$localName', where N is
0117:                        // a number, the field 'N$localName' may not necessarily be a member
0118:                        // of the class named by 'ClassName', but might be a member of some
0119:                        // inaccessible class contained within it.  We use 'getLocalClass'
0120:                        // to do the lookup in this case.  This is part of a fix for bugid
0121:                        // 4054523 and 4030421.  See also 'BatchEnvironment.makeClassDefinition'.
0122:                        // This should also work for anonymous class names of the form
0123:                        // 'ClassName.N'.  Note that the '.' qualifications get converted to
0124:                        // '$' characters when determining the external name of the class and
0125:                        // the name of the class file.
0126:                        if (hname.length() > 0
0127:                                && Character.isDigit(hname.charAt(0))) {
0128:                            ClassDefinition localClass = c.getLocalClass(hname);
0129:                            if (localClass != null) {
0130:                                c = localClass;
0131:                                continue walkTail;
0132:                            }
0133:                        } else {
0134:                            for (MemberDefinition f = c.getFirstMatch(head); f != null; f = f
0135:                                    .getNextMatch()) {
0136:                                if (f.isInnerClass()) {
0137:                                    c = f.getInnerClass();
0138:                                    continue walkTail;
0139:                                }
0140:                            }
0141:                        }
0142:                        throw new ClassNotFound(Identifier.lookupInner(c
0143:                                .getName(), head));
0144:                    }
0145:                    //System.out.println("FOUND " + c + " FOR " + nm);
0146:                    return c;
0147:                }
0148:                return getClassDeclaration(nm).getClassDefinition(this );
0149:            }
0150:
0151:            /**
0152:             * Return a class declaration given a type. Only works for
0153:             * class types.
0154:             */
0155:            public ClassDeclaration getClassDeclaration(Type t) {
0156:                return getClassDeclaration(t.getClassName());
0157:            }
0158:
0159:            /**
0160:             * Return a class definition given a type. Only works for
0161:             * class types.
0162:             */
0163:            public final ClassDefinition getClassDefinition(Type t)
0164:                    throws ClassNotFound {
0165:                return getClassDefinition(t.getClassName());
0166:            }
0167:
0168:            /**
0169:             * Check if a class exists (without actually loading it).
0170:             * (Since inner classes cannot in general be examined without
0171:             * loading source, this method does not accept inner names.)
0172:             */
0173:            public boolean classExists(Identifier nm) {
0174:                return env.classExists(nm);
0175:            }
0176:
0177:            public final boolean classExists(Type t) {
0178:                return !t.isType(TC_CLASS) || classExists(t.getClassName());
0179:            }
0180:
0181:            /**
0182:             * Get the package path for a package
0183:             */
0184:            public Package getPackage(Identifier pkg) throws IOException {
0185:                return env.getPackage(pkg);
0186:            }
0187:
0188:            /**
0189:             * Load the definition of a class.
0190:             */
0191:            public void loadDefinition(ClassDeclaration c) {
0192:                env.loadDefinition(c);
0193:            }
0194:
0195:            /**
0196:             * Return the source of the environment (ie: the thing being compiled/parsed).
0197:             */
0198:            public final Object getSource() {
0199:                return source;
0200:            }
0201:
0202:            /**
0203:             * Resolve a type. Make sure that all the classes referred to by
0204:             * the type have a definition.  Report errors.  Return true if
0205:             * the type is well-formed.  Presently used for types appearing
0206:             * in member declarations, which represent named types internally as
0207:             * qualified identifiers.  Type names appearing in local variable
0208:             * declarations and within expressions are represented as identifier
0209:             * or field expressions, and are resolved by 'toType', which delegates
0210:             * handling of the non-inner portion of the name to this method.
0211:             * <p>
0212:             * In 'toType', the various stages of qualification are represented by
0213:             * separate AST nodes.  Here, we are given a single identifier which
0214:             * contains the entire qualification structure.  It is not possible in
0215:             * general to set the error location to the exact position of a component
0216:             * that is in error, so an error message must refer to the entire qualified
0217:             * name.  An attempt to keep track of the string length of the components of
0218:             * the name and to offset the location accordingly fails because the initial
0219:             * prefix of the name may have been rewritten by an earlier call to 
0220:             * 'resolveName'.  See 'SourceMember.resolveTypeStructure'.  The situation
0221:             * is actually even worse than this, because only a single location is
0222:             * passed in for an entire declaration, which may contain many type names.
0223:             * All error messages are thus poorly localized.  These checks should be 
0224:             * done while traversing the parse tree for the type, not the type descriptor.
0225:             * <p>
0226:             * DESIGN NOTE:
0227:             * As far as I can tell, the two-stage resolution of names represented in
0228:             * string form is an artifact of the late implementation of inner classes
0229:             * and the use of mangled names internally within the compiler.  All
0230:             * qualified names should have their hiearchical structure made explicit
0231:             * in the parse tree at the phase at which they are presented for static
0232:             * semantic checking.  This would affect class names appearing in 'extends',
0233:             * 'implements', and 'throws' clauses, as well as in member declarations.
0234:             */
0235:            public boolean resolve(long where, ClassDefinition c, Type t) {
0236:                switch (t.getTypeCode()) {
0237:                case TC_CLASS: {
0238:                    ClassDefinition def;
0239:                    try {
0240:                        Identifier nm = t.getClassName();
0241:                        if (!nm.isQualified() && !nm.isInner()
0242:                                && !classExists(nm)) {
0243:                            resolve(nm); // elicit complaints about ambiguity
0244:                        }
0245:                        def = getQualifiedClassDefinition(where, nm, c, false);
0246:                        if (!c.canAccess(this , def.getClassDeclaration())) {
0247:                            // Reported error location may be imprecise
0248:                            // if the name is qualified.
0249:                            error(where, "cant.access.class", def);
0250:                            return true; // return false later
0251:                        }
0252:                        def.noteUsedBy(c, where, env);
0253:                    } catch (AmbiguousClass ee) {
0254:                        error(where, "ambig.class", ee.name1, ee.name2);
0255:                        return false;
0256:                    } catch (ClassNotFound e) {
0257:                        // For now, report "class.and.package" only when the code
0258:                        // is going to fail anyway.
0259:                        try {
0260:                            if (e.name.isInner()
0261:                                    && getPackage(e.name.getTopName()).exists()) {
0262:                                env.error(where, "class.and.package", e.name
0263:                                        .getTopName());
0264:                            }
0265:                        } catch (IOException ee) {
0266:                            env.error(where, "io.exception", "package check");
0267:                        }
0268:                        // This error message is also emitted for 'new' expressions.
0269:                        // error(where, "class.not.found", e.name, "declaration");
0270:                        error(where, "class.not.found.no.context", e.name);
0271:                        return false;
0272:                    }
0273:                    return true;
0274:                }
0275:
0276:                case TC_ARRAY:
0277:                    return resolve(where, c, t.getElementType());
0278:
0279:                case TC_METHOD:
0280:                    boolean ok = resolve(where, c, t.getReturnType());
0281:                    Type args[] = t.getArgumentTypes();
0282:                    for (int i = args.length; i-- > 0;) {
0283:                        ok &= resolve(where, c, args[i]);
0284:                    }
0285:                    return ok;
0286:                }
0287:                return true;
0288:            }
0289:
0290:            /**
0291:             * Given its fully-qualified name, verify that a class is defined and accessible.
0292:             * Used to check components of qualified names in contexts where a class is expected.
0293:             * Like 'resolve', but is given a single type name, not a type descriptor.
0294:             */
0295:            public boolean resolveByName(long where, ClassDefinition c,
0296:                    Identifier nm) {
0297:                return resolveByName(where, c, nm, false);
0298:            }
0299:
0300:            public boolean resolveExtendsByName(long where, ClassDefinition c,
0301:                    Identifier nm) {
0302:                return resolveByName(where, c, nm, true);
0303:            }
0304:
0305:            private boolean resolveByName(long where, ClassDefinition c,
0306:                    Identifier nm, boolean isExtends) {
0307:                ClassDefinition def;
0308:                try {
0309:                    if (!nm.isQualified() && !nm.isInner() && !classExists(nm)) {
0310:                        resolve(nm); // elicit complaints about ambiguity
0311:                    }
0312:                    def = getQualifiedClassDefinition(where, nm, c, isExtends);
0313:                    ClassDeclaration decl = def.getClassDeclaration();
0314:                    if (!((!isExtends && c.canAccess(this , decl)) || (isExtends && c
0315:                            .extendsCanAccess(this , decl)))) {
0316:                        error(where, "cant.access.class", def);
0317:                        return true; // return false later
0318:                    }
0319:                } catch (AmbiguousClass ee) {
0320:                    error(where, "ambig.class", ee.name1, ee.name2);
0321:                    return false;
0322:                } catch (ClassNotFound e) {
0323:                    // For now, report "class.and.package" only when the code
0324:                    // is going to fail anyway.
0325:                    try {
0326:                        if (e.name.isInner()
0327:                                && getPackage(e.name.getTopName()).exists()) {
0328:                            env.error(where, "class.and.package", e.name
0329:                                    .getTopName());
0330:                        }
0331:                    } catch (IOException ee) {
0332:                        env.error(where, "io.exception", "package check");
0333:                    }
0334:                    error(where, "class.not.found", e.name, "type name");
0335:                    return false;
0336:                }
0337:                return true;
0338:            }
0339:
0340:            /**
0341:             * Like 'getClassDefinition(env)', but check access on each component.
0342:             * Currently called only by 'resolve' above.  It is doubtful that calls
0343:             * to 'getClassDefinition(env)' are appropriate now.
0344:             */
0345:            public final ClassDefinition getQualifiedClassDefinition(
0346:                    long where, Identifier nm, ClassDefinition ctxClass,
0347:                    boolean isExtends) throws ClassNotFound {
0348:                if (nm.isInner()) {
0349:                    ClassDefinition c = getClassDefinition(nm.getTopName());
0350:                    Identifier tail = nm.getFlatName();
0351:                    walkTail: while (tail.isQualified()) {
0352:                        tail = tail.getTail();
0353:                        Identifier head = tail.getHead();
0354:                        // System.out.println("CLASS: " + c + " HEAD: " + head + " TAIL: " + tail);
0355:                        String hname = head.toString();
0356:                        // Handle synthesized names of local and anonymous classes.
0357:                        // See 'getClassDefinition(env)' above.
0358:                        if (hname.length() > 0
0359:                                && Character.isDigit(hname.charAt(0))) {
0360:                            ClassDefinition localClass = c.getLocalClass(hname);
0361:                            if (localClass != null) {
0362:                                c = localClass;
0363:                                continue walkTail;
0364:                            }
0365:                        } else {
0366:                            for (MemberDefinition f = c.getFirstMatch(head); f != null; f = f
0367:                                    .getNextMatch()) {
0368:                                if (f.isInnerClass()) {
0369:                                    ClassDeclaration rdecl = c
0370:                                            .getClassDeclaration();
0371:                                    c = f.getInnerClass();
0372:                                    ClassDeclaration fdecl = c
0373:                                            .getClassDeclaration();
0374:                                    // This check is presumably applicable even if the
0375:                                    // original source-code name (expanded by 'resolveNames')
0376:                                    // was a simple, unqualified name.  Hopefully, JLS 2e
0377:                                    // will clarify the matter.
0378:                                    if ((!isExtends && !ctxClass.canAccess(env,
0379:                                            fdecl))
0380:                                            || (isExtends && !ctxClass
0381:                                                    .extendsCanAccess(env,
0382:                                                            fdecl))) {
0383:                                        // Reported error location is imprecise.
0384:                                        env.error(where, "no.type.access",
0385:                                                head, rdecl, ctxClass);
0386:                                    }
0387:                                    // The JLS 6.6.2 restrictions on access to protected members
0388:                                    // depend in an essential way upon the syntactic form of the name.
0389:                                    // Since the compiler has previously expanded the class names
0390:                                    // here into fully-qualified form ('resolveNames'), this check
0391:                                    // cannot be performed here.  Unfortunately, the original names
0392:                                    // are clobbered during 'basicCheck', which is also the phase that
0393:                                    // resolves the inheritance structure, required to implement the
0394:                                    // access restrictions.  Pending a large-scale revision of the
0395:                                    // name-resolution machinery, we forgo this check, with the result
0396:                                    // that the JLS 6.6.2 restrictions are not enforced for some cases
0397:                                    // of qualified access to inner classes.  Some qualified names are
0398:                                    // resolved elsewhere via a different mechanism, and will be
0399:                                    // treated correctly -- see 'FieldExpression.checkCommon'.
0400:                                    /*---------------------------------------*
0401:                                    if (f.isProtected()) {
0402:                                    Type rty = Type.tClass(rdecl.getName()); // hack
0403:                                    if (!ctxClass.protectedAccess(env, f, rty)) {
0404:                                        // Reported error location is imprecise.
0405:                                        env.error(where, "invalid.protected.type.use",
0406:                                    	      head, ctxClass, rty);
0407:                                    }
0408:                                    }
0409:                                     *---------------------------------------*/
0410:                                    continue walkTail;
0411:                                }
0412:                            }
0413:                        }
0414:                        throw new ClassNotFound(Identifier.lookupInner(c
0415:                                .getName(), head));
0416:                    }
0417:                    //System.out.println("FOUND " + c + " FOR " + nm);
0418:                    return c;
0419:                }
0420:                return getClassDeclaration(nm).getClassDefinition(this );
0421:            }
0422:
0423:            /**
0424:             * Resolve the names within a type, returning the adjusted type.
0425:             * Adjust class names to reflect scoping.
0426:             * Do not report errors.
0427:             * <p>
0428:             * NOTE: It would be convenient to check for errors here, such as
0429:             * verifying that each component of a qualified name exists and is
0430:             * accessible.  Why must this be done in a separate phase?
0431:             * <p>
0432:             * If the 'synth' argument is true, indicating that the member whose
0433:             * type is being resolved is synthetic, names are resolved with respect
0434:             * to the package scope.  (Fix for 4097882)
0435:             */
0436:            public Type resolveNames(ClassDefinition c, Type t, boolean synth) {
0437:                if (tracing)
0438:                    dtEvent("Environment.resolveNames: " + c + ", " + t);
0439:                switch (t.getTypeCode()) {
0440:                case TC_CLASS: {
0441:                    Identifier name = t.getClassName();
0442:                    Identifier rname;
0443:                    if (synth) {
0444:                        rname = resolvePackageQualifiedName(name);
0445:                    } else {
0446:                        rname = c.resolveName(this , name);
0447:                    }
0448:                    if (name != rname) {
0449:                        t = Type.tClass(rname);
0450:                    }
0451:                    break;
0452:                }
0453:
0454:                case TC_ARRAY:
0455:                    t = Type.tArray(resolveNames(c, t.getElementType(), synth));
0456:                    break;
0457:
0458:                case TC_METHOD: {
0459:                    Type ret = t.getReturnType();
0460:                    Type rret = resolveNames(c, ret, synth);
0461:                    Type args[] = t.getArgumentTypes();
0462:                    Type rargs[] = new Type[args.length];
0463:                    boolean changed = (ret != rret);
0464:                    for (int i = args.length; i-- > 0;) {
0465:                        Type arg = args[i];
0466:                        Type rarg = resolveNames(c, arg, synth);
0467:                        rargs[i] = rarg;
0468:                        if (arg != rarg) {
0469:                            changed = true;
0470:                        }
0471:                    }
0472:                    if (changed) {
0473:                        t = Type.tMethod(rret, rargs);
0474:                    }
0475:                    break;
0476:                }
0477:                }
0478:                return t;
0479:            }
0480:
0481:            /**
0482:             * Resolve a class name, using only package and import directives.
0483:             * Report no errors.
0484:             * <p>
0485:             */
0486:            public Identifier resolveName(Identifier name) {
0487:                // This logic is pretty exactly parallel to that of
0488:                // ClassDefinition.resolveName().
0489:                if (name.isQualified()) {
0490:                    // Try to resolve the first identifier component,
0491:                    // because inner class names take precedence over
0492:                    // package prefixes.  (Cf. ClassDefinition.resolveName.)
0493:                    Identifier rhead = resolveName(name.getHead());
0494:
0495:                    if (rhead.hasAmbigPrefix()) {
0496:                        // The first identifier component refers to an
0497:                        // ambiguous class.  Limp on.  We throw away the
0498:                        // rest of the classname as it is irrelevant.
0499:                        // (part of solution for 4059855).
0500:                        return rhead;
0501:                    }
0502:
0503:                    if (!this .classExists(rhead)) {
0504:                        return this .resolvePackageQualifiedName(name);
0505:                    }
0506:                    try {
0507:                        return this .getClassDefinition(rhead)
0508:                                .resolveInnerClass(this , name.getTail());
0509:                    } catch (ClassNotFound ee) {
0510:                        // return partially-resolved name someone else can fail on
0511:                        return Identifier.lookupInner(rhead, name.getTail());
0512:                    }
0513:                }
0514:                try {
0515:                    return resolve(name);
0516:                } catch (AmbiguousClass ee) {
0517:                    // Don't force a resolution of the name if it is ambiguous.
0518:                    // Forcing the resolution would tack the current package
0519:                    // name onto the front of the class, which would be wrong.
0520:                    // Instead, mark the name as ambiguous and let a later stage
0521:                    // find the error by calling env.resolve(name).
0522:                    // (part of solution for 4059855).
0523:
0524:                    if (name.hasAmbigPrefix()) {
0525:                        return name;
0526:                    } else {
0527:                        return name.addAmbigPrefix();
0528:                    }
0529:                } catch (ClassNotFound ee) {
0530:                    // last chance to make something halfway sensible
0531:                    Imports imports = getImports();
0532:                    if (imports != null)
0533:                        return imports.forceResolve(this , name);
0534:                }
0535:                return name;
0536:            }
0537:
0538:            /**
0539:             * Discover if name consists of a package prefix, followed by the
0540:             * name of a class (that actually exists), followed possibly by
0541:             * some inner class names.  If we can't find a class that exists,
0542:             * return the name unchanged.
0543:             * <p>
0544:             * This routine is used after a class name fails to
0545:             * be resolved by means of imports or inner classes.
0546:             * However, import processing uses this routine directly,
0547:             * since import names must be exactly qualified to start with.
0548:             */
0549:            public final Identifier resolvePackageQualifiedName(Identifier name) {
0550:                Identifier tail = null;
0551:                for (;;) {
0552:                    if (classExists(name)) {
0553:                        break;
0554:                    }
0555:                    if (!name.isQualified()) {
0556:                        name = (tail == null) ? name : Identifier.lookup(name,
0557:                                tail);
0558:                        tail = null;
0559:                        break;
0560:                    }
0561:                    Identifier nm = name.getName();
0562:                    tail = (tail == null) ? nm : Identifier.lookup(nm, tail);
0563:                    name = name.getQualifier();
0564:                }
0565:                if (tail != null)
0566:                    name = Identifier.lookupInner(name, tail);
0567:                return name;
0568:            }
0569:
0570:            /**
0571:             * Resolve a class name, using only package and import directives.
0572:             */
0573:            public Identifier resolve(Identifier nm) throws ClassNotFound {
0574:                if (env == null)
0575:                    return nm; // a pretty useless no-op
0576:                return env.resolve(nm);
0577:            }
0578:
0579:            /**
0580:             * Get the imports used to resolve class names.
0581:             */
0582:            public Imports getImports() {
0583:                if (env == null)
0584:                    return null; // lame default
0585:                return env.getImports();
0586:            }
0587:
0588:            /**
0589:             * Create a new class.
0590:             */
0591:            public ClassDefinition makeClassDefinition(Environment origEnv,
0592:                    long where, IdentifierToken name, String doc,
0593:                    int modifiers, IdentifierToken super Class,
0594:                    IdentifierToken interfaces[], ClassDefinition outerClass) {
0595:                if (env == null)
0596:                    return null; // lame default
0597:                return env.makeClassDefinition(origEnv, where, name, doc,
0598:                        modifiers, super Class, interfaces, outerClass);
0599:            }
0600:
0601:            /**
0602:             * Create a new field.
0603:             */
0604:            public MemberDefinition makeMemberDefinition(Environment origEnv,
0605:                    long where, ClassDefinition clazz, String doc,
0606:                    int modifiers, Type type, Identifier name,
0607:                    IdentifierToken argNames[], IdentifierToken expIds[],
0608:                    Object value) {
0609:                if (env == null)
0610:                    return null; // lame default
0611:                return env.makeMemberDefinition(origEnv, where, clazz, doc,
0612:                        modifiers, type, name, argNames, expIds, value);
0613:            }
0614:
0615:            /**
0616:             * Returns true if the given method is applicable to the given arguments
0617:             */
0618:
0619:            public boolean isApplicable(MemberDefinition m, Type args[])
0620:                    throws ClassNotFound {
0621:                Type mType = m.getType();
0622:                if (!mType.isType(TC_METHOD))
0623:                    return false;
0624:                Type mArgs[] = mType.getArgumentTypes();
0625:                if (args.length != mArgs.length)
0626:                    return false;
0627:                for (int i = args.length; --i >= 0;)
0628:                    if (!isMoreSpecific(args[i], mArgs[i]))
0629:                        return false;
0630:                return true;
0631:            }
0632:
0633:            /** 
0634:             * Returns true if "best" is in every argument at least as good as "other"
0635:             */
0636:            public boolean isMoreSpecific(MemberDefinition best,
0637:                    MemberDefinition other) throws ClassNotFound {
0638:                Type bestType = best.getClassDeclaration().getType();
0639:                Type otherType = other.getClassDeclaration().getType();
0640:                boolean result = isMoreSpecific(bestType, otherType)
0641:                        && isApplicable(other, best.getType()
0642:                                .getArgumentTypes());
0643:                // System.out.println("isMoreSpecific: " + best + "/" + other 
0644:                //                      + " => " + result);
0645:                return result;
0646:            }
0647:
0648:            /**
0649:             * Returns true if "from" is a more specific type than "to"
0650:             */
0651:
0652:            public boolean isMoreSpecific(Type from, Type to)
0653:                    throws ClassNotFound {
0654:                return implicitCast(from, to);
0655:            }
0656:
0657:            /**  
0658:             * Return true if an implicit cast from this type to
0659:             * the given type is allowed.
0660:             */
0661:            public boolean implicitCast(Type from, Type to)
0662:                    throws ClassNotFound {
0663:                if (from == to)
0664:                    return true;
0665:
0666:                int toTypeCode = to.getTypeCode();
0667:
0668:                switch (from.getTypeCode()) {
0669:                case TC_BYTE:
0670:                    if (toTypeCode == TC_SHORT)
0671:                        return true;
0672:                case TC_SHORT:
0673:                case TC_CHAR:
0674:                    if (toTypeCode == TC_INT)
0675:                        return true;
0676:                case TC_INT:
0677:                    if (toTypeCode == TC_LONG)
0678:                        return true;
0679:                case TC_LONG:
0680:                    if (toTypeCode == TC_FLOAT)
0681:                        return true;
0682:                case TC_FLOAT:
0683:                    if (toTypeCode == TC_DOUBLE)
0684:                        return true;
0685:                case TC_DOUBLE:
0686:                default:
0687:                    return false;
0688:
0689:                case TC_NULL:
0690:                    return to.inMask(TM_REFERENCE);
0691:
0692:                case TC_ARRAY:
0693:                    if (!to.isType(TC_ARRAY)) {
0694:                        return (to == Type.tObject || to == Type.tCloneable || to == Type.tSerializable);
0695:                    } else {
0696:                        // both are arrays.  recurse down both until one isn't an array
0697:                        do {
0698:                            from = from.getElementType();
0699:                            to = to.getElementType();
0700:                        } while (from.isType(TC_ARRAY) && to.isType(TC_ARRAY));
0701:                        if (from.inMask(TM_ARRAY | TM_CLASS)
0702:                                && to.inMask(TM_ARRAY | TM_CLASS)) {
0703:                            return isMoreSpecific(from, to);
0704:                        } else {
0705:                            return (from.getTypeCode() == to.getTypeCode());
0706:                        }
0707:                    }
0708:
0709:                case TC_CLASS:
0710:                    if (toTypeCode == TC_CLASS) {
0711:                        ClassDefinition fromDef = getClassDefinition(from);
0712:                        ClassDefinition toDef = getClassDefinition(to);
0713:                        return toDef.implementedBy(this , fromDef
0714:                                .getClassDeclaration());
0715:                    } else {
0716:                        return false;
0717:                    }
0718:                }
0719:            }
0720:
0721:            /**
0722:             * Return true if an explicit cast from this type to
0723:             * the given type is allowed.
0724:             */
0725:            public boolean explicitCast(Type from, Type to)
0726:                    throws ClassNotFound {
0727:                if (implicitCast(from, to)) {
0728:                    return true;
0729:                }
0730:                if (from.inMask(TM_NUMBER)) {
0731:                    return to.inMask(TM_NUMBER);
0732:                }
0733:                if (from.isType(TC_CLASS) && to.isType(TC_CLASS)) {
0734:                    ClassDefinition fromClass = getClassDefinition(from);
0735:                    ClassDefinition toClass = getClassDefinition(to);
0736:                    if (toClass.isFinal()) {
0737:                        return fromClass.implementedBy(this , toClass
0738:                                .getClassDeclaration());
0739:                    }
0740:                    if (fromClass.isFinal()) {
0741:                        return toClass.implementedBy(this , fromClass
0742:                                .getClassDeclaration());
0743:                    }
0744:
0745:                    // The code here used to omit this case.  If both types
0746:                    // involved in a cast are interfaces, then JLS 5.5 requires
0747:                    // that we do a simple test -- make sure none of the methods
0748:                    // in toClass and fromClass have the same signature but
0749:                    // different return types.  (bug number 4028359)
0750:                    if (toClass.isInterface() && fromClass.isInterface()) {
0751:                        return toClass.couldImplement(fromClass);
0752:                    }
0753:
0754:                    return toClass.isInterface()
0755:                            || fromClass.isInterface()
0756:                            || fromClass.super ClassOf(this , toClass
0757:                                    .getClassDeclaration());
0758:                }
0759:                if (to.isType(TC_ARRAY)) {
0760:                    if (from.isType(TC_ARRAY)) {
0761:                        Type t1 = from.getElementType();
0762:                        Type t2 = to.getElementType();
0763:                        while ((t1.getTypeCode() == TC_ARRAY)
0764:                                && (t2.getTypeCode() == TC_ARRAY)) {
0765:                            t1 = t1.getElementType();
0766:                            t2 = t2.getElementType();
0767:                        }
0768:                        if (t1.inMask(TM_ARRAY | TM_CLASS)
0769:                                && t2.inMask(TM_ARRAY | TM_CLASS)) {
0770:                            return explicitCast(t1, t2);
0771:                        }
0772:                    } else if (from == Type.tObject || from == Type.tCloneable
0773:                            || from == Type.tSerializable)
0774:                        return true;
0775:                }
0776:                return false;
0777:            }
0778:
0779:            /**
0780:             * Flags.
0781:             */
0782:            public int getFlags() {
0783:                return env.getFlags();
0784:            }
0785:
0786:            /**
0787:             * Debugging flags.  There used to be a method debug()
0788:             * that has been replaced because -g has changed meaning
0789:             * (it now cooperates with -O and line number, variable
0790:             * range and source file info can be toggled separately).
0791:             */
0792:            public final boolean debug_lines() {
0793:                return (getFlags() & F_DEBUG_LINES) != 0;
0794:            }
0795:
0796:            public final boolean debug_vars() {
0797:                return (getFlags() & F_DEBUG_VARS) != 0;
0798:            }
0799:
0800:            public final boolean debug_source() {
0801:                return (getFlags() & F_DEBUG_SOURCE) != 0;
0802:            }
0803:
0804:            /**
0805:             * Optimization flags.  There used to be a method optimize()
0806:             * that has been replaced because -O has changed meaning in
0807:             * javac to be replaced with -O and -O:interclass.
0808:             */
0809:            public final boolean opt() {
0810:                return (getFlags() & F_OPT) != 0;
0811:            }
0812:
0813:            public final boolean opt_interclass() {
0814:                return (getFlags() & F_OPT_INTERCLASS) != 0;
0815:            }
0816:
0817:            /**
0818:             * Verbose
0819:             */
0820:            public final boolean verbose() {
0821:                return (getFlags() & F_VERBOSE) != 0;
0822:            }
0823:
0824:            /**
0825:             * Dump debugging stuff
0826:             */
0827:            public final boolean dump() {
0828:                return (getFlags() & F_DUMP) != 0;
0829:            }
0830:
0831:            /**
0832:             * Verbose
0833:             */
0834:            public final boolean warnings() {
0835:                return (getFlags() & F_WARNINGS) != 0;
0836:            }
0837:
0838:            /**
0839:             * Dependencies
0840:             */
0841:            public final boolean dependencies() {
0842:                return (getFlags() & F_DEPENDENCIES) != 0;
0843:            }
0844:
0845:            /**
0846:             * Print Dependencies to stdout
0847:             */
0848:            public final boolean print_dependencies() {
0849:                return (getFlags() & F_PRINT_DEPENDENCIES) != 0;
0850:            }
0851:
0852:            /**
0853:             * Deprecation warnings are enabled.
0854:             */
0855:            public final boolean deprecation() {
0856:                return (getFlags() & F_DEPRECATION) != 0;
0857:            }
0858:
0859:            /**
0860:             * Do not support virtual machines before version 1.2.
0861:             * This option is not supported and is only here for testing purposes.
0862:             */
0863:            public final boolean version12() {
0864:                return (getFlags() & F_VERSION12) != 0;
0865:            }
0866:
0867:            /**
0868:             * Floating point is strict by default
0869:             */
0870:            public final boolean strictdefault() {
0871:                return (getFlags() & F_STRICTDEFAULT) != 0;
0872:            }
0873:
0874:            /**
0875:             * Release resources, if any.
0876:             */
0877:            public void shutdown() {
0878:                if (env != null) {
0879:                    env.shutdown();
0880:                }
0881:            }
0882:
0883:            /**
0884:             * Issue an error.
0885:             *  source	 - the input source, usually a file name string
0886:             *  offset   - the offset in the source of the error
0887:             *  err      - the error number (as defined in this interface)
0888:             *  arg1     - an optional argument to the error (null if not applicable)
0889:             *  arg2     - a second optional argument to the error (null if not applicable)
0890:             *  arg3     - a third optional argument to the error (null if not applicable)
0891:             */
0892:            public void error(Object source, long where, String err,
0893:                    Object arg1, Object arg2, Object arg3) {
0894:                env.error(source, where, err, arg1, arg2, arg3);
0895:            }
0896:
0897:            public final void error(long where, String err, Object arg1,
0898:                    Object arg2, Object arg3) {
0899:                error(source, where, err, arg1, arg2, arg3);
0900:            }
0901:
0902:            public final void error(long where, String err, Object arg1,
0903:                    Object arg2) {
0904:                error(source, where, err, arg1, arg2, null);
0905:            }
0906:
0907:            public final void error(long where, String err, Object arg1) {
0908:                error(source, where, err, arg1, null, null);
0909:            }
0910:
0911:            public final void error(long where, String err) {
0912:                error(source, where, err, null, null, null);
0913:            }
0914:
0915:            /**
0916:             * Output a string. This can either be an error message or something
0917:             * for debugging. This should be used instead of println.
0918:             */
0919:            public void output(String msg) {
0920:                env.output(msg);
0921:            }
0922:
0923:            private static boolean debugging = (System
0924:                    .getProperty("javac.debug") != null);
0925:
0926:            public static void debugOutput(Object msg) {
0927:                if (Environment.debugging)
0928:                    System.out.println(msg.toString());
0929:            }
0930:
0931:            /**
0932:             * set character encoding name
0933:             */
0934:            public void setCharacterEncoding(String encoding) {
0935:                this .encoding = encoding;
0936:            }
0937:
0938:            /**
0939:             * Return character encoding name
0940:             */
0941:            public String getCharacterEncoding() {
0942:                return encoding;
0943:            }
0944:
0945:            /**
0946:             * Return major version to use in generated class files.
0947:             */
0948:            public short getMajorVersion() {
0949:                if (env == null)
0950:                    return JAVA_DEFAULT_VERSION; // needed for javah
0951:                return env.getMajorVersion();
0952:            }
0953:
0954:            /**
0955:             * Return minor version to use in generated class files.
0956:             */
0957:            public short getMinorVersion() {
0958:                if (env == null)
0959:                    return JAVA_DEFAULT_MINOR_VERSION; // needed for javah
0960:                return env.getMinorVersion();
0961:            }
0962:
0963:            // JCOV
0964:            /**
0965:             *  get coverage flag 
0966:             */
0967:            public final boolean coverage() {
0968:                return (getFlags() & F_COVERAGE) != 0;
0969:            }
0970:
0971:            /**
0972:             *  get flag of generation the coverage data file
0973:             */
0974:            public final boolean covdata() {
0975:                return (getFlags() & F_COVDATA) != 0;
0976:            }
0977:
0978:            /**
0979:             * Return the coverage data file
0980:             */
0981:            public File getcovFile() {
0982:                return env.getcovFile();
0983:            }
0984:
0985:            // end JCOV
0986:
0987:            /**
0988:             * Debug tracing.
0989:             * Currently, this code is used only for tracing the loading and
0990:             * checking of classes, particularly the demand-driven aspects.
0991:             * This code should probably be integrated with 'debugOutput' above,
0992:             * but we need to give more thought to the issue of classifying debugging
0993:             * messages and allowing those only those of interest to be enabled.
0994:             *
0995:             * Calls to these methods are generally conditioned on the final variable
0996:             * 'Constants.tracing', which allows the calls to be completely omitted
0997:             * in a production release to avoid space and time overhead.
0998:             */
0999:
1000:            private static boolean dependtrace = (System
1001:                    .getProperty("javac.trace.depend") != null);
1002:
1003:            public void dtEnter(String s) {
1004:                if (dependtrace)
1005:                    System.out.println(">>> " + s);
1006:            }
1007:
1008:            public void dtExit(String s) {
1009:                if (dependtrace)
1010:                    System.out.println("<<< " + s);
1011:            }
1012:
1013:            public void dtEvent(String s) {
1014:                if (dependtrace)
1015:                    System.out.println(s);
1016:            }
1017:
1018:            /**
1019:             * Enable diagnostic dump of class modifier bits, including those
1020:             * in InnerClasses attributes, as they are written to the classfile.
1021:             * In the future, may also enable dumping field and method modifiers.
1022:             */
1023:
1024:            private static boolean dumpmodifiers = (System
1025:                    .getProperty("javac.dump.modifiers") != null);
1026:
1027:            public boolean dumpModifiers() {
1028:                return dumpmodifiers;
1029:            }
1030:
1031:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.