Source Code Cross Referenced for JavaEntities.java in  » Parser » Rats-Parser-Generators » xtc » lang » 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 » Parser » Rats Parser Generators » xtc.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * xtc - The eXTensible Compiler
0003:         * Copyright (C) 2005-2007 IBM Corp.
0004:         *
0005:         * This program is free software; you can redistribute it and/or
0006:         * modify it under the terms of the GNU General Public License
0007:         * version 2 as published by the Free Software Foundation.
0008:         *
0009:         * This program is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012:         * GNU General Public License for more details.
0013:         *
0014:         * You should have received a copy of the GNU General Public License
0015:         * along with this program; if not, write to the Free Software
0016:         * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
0017:         * USA.
0018:         */
0019:        package xtc.lang;
0020:
0021:        import java.io.CharArrayWriter;
0022:        import java.io.File;
0023:        import java.io.FileReader;
0024:        import java.io.IOException;
0025:        import java.io.Reader;
0026:        import java.io.StringReader;
0027:        import java.lang.reflect.Constructor;
0028:        import java.lang.reflect.Method;
0029:        import java.util.ArrayList;
0030:        import java.util.Collections;
0031:        import java.util.Formatter;
0032:        import java.util.HashMap;
0033:        import java.util.HashSet;
0034:        import java.util.Iterator;
0035:        import java.util.LinkedList;
0036:        import java.util.List;
0037:        import java.util.Map;
0038:        import java.util.Set;
0039:        import java.util.TreeSet;
0040:
0041:        import xtc.Constants;
0042:        import xtc.parser.ParseException;
0043:        import xtc.parser.Result;
0044:        import xtc.tree.Attribute;
0045:        import xtc.tree.GNode;
0046:        import xtc.tree.LineMarker;
0047:        import xtc.tree.Location;
0048:        import xtc.tree.Node;
0049:        import xtc.tree.Printer;
0050:        import xtc.tree.Visitor;
0051:        import xtc.type.AliasT;
0052:        import xtc.type.AnnotatedT;
0053:        import xtc.type.ArrayT;
0054:        import xtc.type.BooleanT;
0055:        import xtc.type.ClassOrInterfaceT;
0056:        import xtc.type.ClassT;
0057:        import xtc.type.DynamicReference;
0058:        import xtc.type.FunctionOrMethodT;
0059:        import xtc.type.IntegerT;
0060:        import xtc.type.InterfaceT;
0061:        import xtc.type.MethodT;
0062:        import xtc.type.NullReference;
0063:        import xtc.type.NumberT;
0064:        import xtc.type.PackageT;
0065:        import xtc.type.Type;
0066:        import xtc.type.TypePrinter;
0067:        import xtc.type.VariableT;
0068:        import xtc.type.VoidT;
0069:        import xtc.type.WrappedT;
0070:        import xtc.util.Runtime;
0071:        import xtc.util.SymbolTable;
0072:        import xtc.util.Utilities;
0073:        import xtc.util.SymbolTable.Scope;
0074:
0075:        /**
0076:         * Common functionality for handling Java entities outside the AST.
0077:         * 
0078:         * <p><u>Composite types</u>
0079:         * <table border=0>
0080:         * <tr><td>ExpressionT       <td>&gt; <td>GeneralLValueT, GeneralRValueT
0081:         * <tr><td>GeneralLValueT    <td>&gt; <td><b>LValueT</b>, FieldT, LocalT, ParameterT
0082:         * <tr><td><b>LValueT</b>    <td>=    <td>RValueT
0083:         * <tr><td>FieldT            <td>&gt; <td><b>VariableT</b>:(FIELD Name WrappedRValueT)
0084:         * <tr><td>LocalT            <td>&gt; <td><b>VariableT</b>:(LOCAL Name WrappedRValueT)
0085:         * <tr><td>ParameterT        <td>&gt; <td><b>VariableT</b>:(PARAMETER Name RValueT)
0086:         * <tr><td>GeneralRValueT    <td>&gt; <td><b>NullT</b>, WrappedRValueT
0087:         * <tr><td>RValueT           <td>&gt; <td>PrimitiveT, <b>ArrayT</b>, WrappedClassT, WrappedInterfaceT
0088:         * <tr><td><b>ArrayT</b>     <td>=    <td><b>LValueT</b>
0089:         * <tr><td><b>ClassT</b>     <td>=    <td>Name WrappedClassT WrappedInterfaceT* Members
0090:         * <tr><td><b>InterfaceT</b> <td>=    <td>Name WrappedInterfaceT* Members
0091:         * <tr><td>Members</b>       <td>=    <td>FieldT* MethodT* WrappedClassT* WrappedInterfaceT*
0092:         * <tr><td><b>MethodT</b>    <td>=    <td>ReturnT Name ParameterT* WrappedClassT*
0093:         * <tr><td>NotAValueT        <td>&gt; <td><b>PackageT</b>, <b>AnnotatedT</b>:ReturnT --- annotated with Constants.ATT_NOT_A_VALUE
0094:         * <tr><td>ReturnT           <td>&gt; <td><b>VoidT</b>, RValueT
0095:         * </table>
0096:         * 
0097:         * <p><u>Wrapped types</u>
0098:         * <table border=0>
0099:         * <tr><td>WrappedRValueT</td>     <td>&gt; <td><b>ConstantT</b>:RValueT / RValueT
0100:         * <tr><td>WrappedClassT</td>      <td>&gt; <td><b>AliasT</b>:Name / <b>AliasT</b>:<b>ClassT</b> / <b>ClassT</b>
0101:         * <tr><td>WrappedInterfaceT</td>  <td>&gt; <td><b>AliasT</b>:Name / <b>AliasT</b>:<b>InterfaceT</b> / <b>InterfaceT</b>
0102:         * </table>
0103:         * 
0104:         * <p><u>Basetypes</u>
0105:         * <table border=0>
0106:         * <tr><td>PrimitiveT      <td>&gt; <td><b>BooleanT</b>, <b>NumberT</b>
0107:         * <tr><td><b>NumberT</b>  <td>&gt; <td><b>IntegerT</b>, <b>FloatT</b>
0108:         * <tr><td>NullT           <td>=    <td><b>ConstantT</b>:<b>VoidT</b>
0109:         * </table>
0110:         * </table>
0111:         *  
0112:         * <p><u>Explanation</u>
0113:         * <table border=0>
0114:         * <tr><td><b>Bold font entities</b>          <td>are represented explicitly in xtc.type
0115:         * <tr><td><i>Super &gt;  Sub1, ..., SubN</i> <td>any of the <i>SubI</i> can appear where a <i>Super</i> is expected
0116:         * <tr><td><i>Whole = Part1, ..., PartN</i>   <td>the <i>Whole</i> consists of all the parts <i>PartI</i>
0117:         * <tr><td><i>Whole = Part1 / ... / PartN</i> <td>the <i>Whole</i> consists of one of the parts <i>PartI</i>
0118:         * <tr><td><i>Wrapper:Contents</i>            <td>the <i>Wrapper</i> must wrap an instance of <i>Contents</i>
0119:         * <tr><td><i>Repetee</i>*                    <td>zero or more occurences
0120:         * </table>
0121:         * 
0122:         * @author Martin Hirzel
0123:         */
0124:        public final class JavaEntities {
0125:            public static final class JavaTypePrinter extends TypePrinter {
0126:                private boolean _showDetails;
0127:
0128:                private final SymbolTable _table;
0129:
0130:                public JavaTypePrinter(final SymbolTable tab,
0131:                        final boolean showDetails, final Printer initPrinter) {
0132:                    super (initPrinter);
0133:                    _showDetails = showDetails;
0134:                    _table = tab;
0135:                }
0136:
0137:                private boolean isJavaLangObject(final Type t) {
0138:                    if (null == t)
0139:                        return false;
0140:                    if (t.isClass())
0141:                        return t.toClass().getQName()
0142:                                .equals("java.lang.Object");
0143:                    assert t.isAlias();
0144:                    final String n = t.toAlias().getName();
0145:                    return n.equals("Object") || n.equals("java.lang.Object");
0146:                }
0147:
0148:                public final boolean printAnnotations(final Type t) {
0149:                    printAttributes(t);
0150:                    return t.hasAttributes();
0151:                }
0152:
0153:                public final void printAttributes(final Type t) {
0154:                    if (t.hasAttributes())
0155:                        for (final Attribute att : t.attributes())
0156:                            printer.p(modifierToName(att)).p(' ');
0157:                }
0158:
0159:                private final void printMethodNoDetails(final MethodT t) {
0160:                    assert !_showDetails;
0161:                    dispatch(JavaEntities.declaringType(_table, t));
0162:                    printer.p('.').p(t.getName());
0163:                }
0164:
0165:                public final void printSignature(final FunctionOrMethodT t) {
0166:                    if (!_showDetails)
0167:                        throw new Error();
0168:                    _showDetails = false;
0169:                    printer.p('(');
0170:                    for (final Iterator<Type> iter = t.getParameters()
0171:                            .iterator(); iter.hasNext();) {
0172:                        printer.p(iter.next());
0173:                        if (iter.hasNext() || t.isVarArgs())
0174:                            printer.p(", ");
0175:                    }
0176:                    if (t.isVarArgs())
0177:                        printer.p("...");
0178:                    printer.p(") -> ");
0179:                    if (t.getResult().resolve().isFunction())
0180:                        printer.p('(').p(t.getResult()).p(')');
0181:                    else
0182:                        printer.p(t.getResult());
0183:                    if ((null != t.getExceptions())
0184:                            && (!t.getExceptions().isEmpty())) {
0185:                        printer.p(" throws ");
0186:                        for (Iterator<Type> iter = t.getExceptions().iterator(); iter
0187:                                .hasNext();) {
0188:                            printer.p(iter.next());
0189:                            if (iter.hasNext())
0190:                                printer.p(", ");
0191:                        }
0192:                    }
0193:                    _showDetails = true;
0194:                }
0195:
0196:                public final void visit(final AliasT t) {
0197:                    printer.p(t.getName());
0198:                }
0199:
0200:                public final void visit(final AnnotatedT t) {
0201:                    if (JavaEntities.isNullT(t)) {
0202:                        printer.p("null");
0203:                        return;
0204:                    }
0205:                    if (_showDetails)
0206:                        printAttributes(t);
0207:                    printer.p(t.getType());
0208:                }
0209:
0210:                public final void visit(final ArrayT t) {
0211:                    printer.p(arrayElementType(t)).p("[]");
0212:                }
0213:
0214:                public final void visit(final BooleanT t) {
0215:                    printer.p("boolean");
0216:                }
0217:
0218:                public final void visit(final ClassT t) {
0219:                    if (!_showDetails) {
0220:                        printer.p(t.getQName());
0221:                        return;
0222:                    }
0223:                    printAttributes(t);
0224:                    printer.p("class ").p(t.getQName());
0225:                    if (!isJavaLangObject(t.getParent()))
0226:                        printer.p(" extends ").p(t.getParent());
0227:                    if (!t.getInterfaces().isEmpty()) {
0228:                        printer.p(" implements ");
0229:                        for (final Iterator<Type> i = t.getInterfaces()
0230:                                .iterator(); i.hasNext();) {
0231:                            printer.p(i.next());
0232:                            if (i.hasNext())
0233:                                printer.p(", ");
0234:                        }
0235:                    }
0236:                    printer.p("{");
0237:                    final Scope scope = _table.getScope(typeToScopeName(t));
0238:                    final TreeSet<String> sortedMembers = new TreeSet<String>();
0239:                    for (final Iterator<String> i = scope.symbols(); i
0240:                            .hasNext();)
0241:                        sortedMembers.add(i.next());
0242:                    for (final String s : sortedMembers) {
0243:                        final Type m = (Type) scope.lookupLocally(s);
0244:                        assert null != m;
0245:                        dispatch(m);
0246:                        printer.p("; ");
0247:                    }
0248:                    printer.p("}");
0249:                }
0250:
0251:                public final void visit(final InterfaceT t) {
0252:                    if (!_showDetails) {
0253:                        printer.p(t.getQName());
0254:                        return;
0255:                    }
0256:                    printAttributes(t);
0257:                    printer.p("interface ").p(t.getQName());
0258:                    if (!t.getInterfaces().isEmpty()) {
0259:                        printer.p(" extends ");
0260:                        for (final Iterator<Type> i = t.getInterfaces()
0261:                                .iterator(); i.hasNext();) {
0262:                            printer.p(i.next());
0263:                            if (i.hasNext())
0264:                                printer.p(", ");
0265:                        }
0266:                    }
0267:                    printer.p("{");
0268:                    final Scope scope = _table.getScope(typeToScopeName(t));
0269:                    final TreeSet<String> sortedMembers = new TreeSet<String>();
0270:                    for (final Iterator<String> i = scope.symbols(); i
0271:                            .hasNext();)
0272:                        sortedMembers.add(i.next());
0273:                    for (final String s : sortedMembers) {
0274:                        final Type m = (Type) scope.lookupLocally(s);
0275:                        assert null != m;
0276:                        dispatch(m);
0277:                        printer.p("; ");
0278:                    }
0279:                    printer.p("}");
0280:                }
0281:
0282:                public final void visit(final MethodT t) {
0283:                    if (_showDetails)
0284:                        super .visit(t);
0285:                    else
0286:                        printMethodNoDetails(t);
0287:                }
0288:            }
0289:
0290:            static class MiniVisitor_allUsedIdentifiers extends Visitor {
0291:                public final Set<String> visit(final LineMarker m) {
0292:                    final Node n = m.getNode();
0293:                    return null == n ? EMPTY_SET : stringSet(dispatch(n));
0294:                }
0295:
0296:                public final Set<String> visit(final Node n) {
0297:                    final Set<String> result = new HashSet<String>();
0298:                    for (int i = 0; i < n.size(); i++) {
0299:                        if (n.get(i) instanceof  String)
0300:                            result.add(n.getString(i));
0301:                        else if (n.get(i) instanceof  Node)
0302:                            result.addAll(stringSet(dispatch(n.getNode(i))));
0303:                    }
0304:                    return result;
0305:                }
0306:
0307:                public final Set<String> visitBinaryExpression(final GNode n) {
0308:                    final Set<String> result = new HashSet<String>();
0309:                    result.addAll(stringSet(dispatch(n.getNode(0))));
0310:                    result.addAll(stringSet(dispatch(n.getNode(2))));
0311:                    return result;
0312:                }
0313:
0314:                public final Set<String> visitBlockDeclaration(final GNode n) {
0315:                    return stringSet(dispatch(n.getNode(1)));
0316:                }
0317:
0318:                public final Set<String> visitBooleanLiteral(final GNode n) {
0319:                    return EMPTY_SET;
0320:                }
0321:
0322:                public final Set<String> visitCharacterLiteral(final GNode n) {
0323:                    return EMPTY_SET;
0324:                }
0325:
0326:                public final Set<String> visitFieldDeclaration(final GNode n) {
0327:                    final Set<String> result = new HashSet<String>();
0328:                    result.addAll(stringSet(dispatch(n.getNode(1))));
0329:                    result.addAll(stringSet(dispatch(n.getNode(2))));
0330:                    return result;
0331:                }
0332:
0333:                public final Set<String> visitFloatingPointLiteral(final GNode n) {
0334:                    return EMPTY_SET;
0335:                }
0336:
0337:                public final Set<String> visitForInit(final GNode n) {
0338:                    if (1 == n.size())
0339:                        return stringSet(dispatch(n.getNode(0)));
0340:                    return stringSet(dispatch(n.getNode(1)));
0341:                }
0342:
0343:                public final Set<String> visitFormalParameter(final GNode n) {
0344:                    final Set<String> result = new HashSet<String>();
0345:                    result.addAll(stringSet(dispatch(n.getNode(1))));
0346:                    result.add(n.getString(3));
0347:                    return result;
0348:                }
0349:
0350:                public final Set<String> visitImportDeclaration(final GNode n) {
0351:                    return stringSet(dispatch(n.getNode(1)));
0352:                }
0353:
0354:                public final Set<String> visitIntegerLiteral(final GNode n) {
0355:                    return EMPTY_SET;
0356:                }
0357:
0358:                public final Set<String> visitNullLiteral(final GNode n) {
0359:                    return EMPTY_SET;
0360:                }
0361:
0362:                public final Set<String> visitPostfixUnaryExpression(
0363:                        final GNode n) {
0364:                    return stringSet(dispatch(n.getNode(0)));
0365:                }
0366:
0367:                public final Set<String> visitPrefixUnaryExpression(
0368:                        final GNode n) {
0369:                    return stringSet(dispatch(n.getNode(1)));
0370:                }
0371:
0372:                public final Set<String> visitStringLiteral(final GNode n) {
0373:                    return EMPTY_SET;
0374:                }
0375:
0376:                public final Set<String> visitType(final GNode n) {
0377:                    return stringSet(dispatch(n.getNode(0)));
0378:                }
0379:            }
0380:
0381:            static class MiniVisitor_scrubLocations extends Visitor {
0382:                public final void visit(final Node n) {
0383:                    n.setLocation((Location) null);
0384:                    for (final Object o : n)
0385:                        if (o instanceof  Node)
0386:                            dispatch((Node) o);
0387:                }
0388:            }
0389:
0390:            /**
0391:             * Enumerates all the types from which this type may inherit methods or
0392:             * fields. For classes and interfaces, this means all reflexive or transitive
0393:             * super-classes/insterfaces. For arrays, this means Object, Cloneable, or
0394:             * Serializable. This iterator will resolve any aliases it encounters on the
0395:             * way. This iterator only applies to reference types.
0396:             */
0397:            static final class SuperTypesIter implements  Iterator<Type> {
0398:                private static String key(final Type type) {
0399:                    final Type t = type.isAlias() ? ((AliasT) type).getType()
0400:                            : type;
0401:                    if (t.isArray())
0402:                        return key(JavaEntities.arrayElementType(t.toArray()))
0403:                                + "[]";
0404:                    if (JavaEntities.isPrimitiveT(type))
0405:                        return type.toString();
0406:                    return JavaEntities.resolveToRawClassOrInterfaceT(t)
0407:                            .getQName();
0408:                }
0409:
0410:                private final List<File> _paths;
0411:
0412:                /** Set of String keys: current and former contents of todo. */
0413:                private final Set<String> _seen = new HashSet<String>();
0414:
0415:                private final SymbolTable _tab;
0416:
0417:                /** List of Types; add to end, remove from front. */
0418:                private final LinkedList<Type> _todo = new LinkedList<Type>();
0419:
0420:                public SuperTypesIter(final SymbolTable tab,
0421:                        final List<File> paths, final Type start) {
0422:                    this (tab, paths, start, true);
0423:                }
0424:
0425:                public SuperTypesIter(final SymbolTable tab,
0426:                        final List<File> paths, final Type start,
0427:                        final boolean reflexive) {
0428:                    _tab = tab;
0429:                    _paths = paths;
0430:                    final Type rStart = JavaEntities.resolveToRValue(start);
0431:                    if (reflexive)
0432:                        add(rStart);
0433:                    else
0434:                        addDirectSupertypes(rStart);
0435:                }
0436:
0437:                private final void add(final Type type) {
0438:                    assert null != type;
0439:                    assert JavaEntities.isReferenceT(type);
0440:                    if (_seen.add(key(type)))
0441:                        _todo.addLast(type);
0442:                }
0443:
0444:                private void addDirectSupertypes(final Type sub) {
0445:                    for (final ClassOrInterfaceT sup : JavaEntities
0446:                            .directSuperTypes(_tab, _paths, sub))
0447:                        add(sup);
0448:                }
0449:
0450:                public final boolean hasNext() {
0451:                    return !_todo.isEmpty();
0452:                }
0453:
0454:                public final Type next() {
0455:                    if (_todo.isEmpty())
0456:                        return null;
0457:                    final Type result = _todo.removeFirst();
0458:                    addDirectSupertypes(result);
0459:                    return result;
0460:                }
0461:
0462:                public final void remove() {
0463:                    throw new UnsupportedOperationException();
0464:                }
0465:            }
0466:
0467:            public static final class UnicodeUnescaper extends Reader {
0468:                private boolean _havePeek;
0469:                private int _peek;
0470:                private final Reader _reader;
0471:
0472:                public UnicodeUnescaper(final Reader reader) {
0473:                    _havePeek = false;
0474:                    _peek = -1;
0475:                    _reader = reader;
0476:                }
0477:
0478:                public final void close() throws IOException {
0479:                    _reader.close();
0480:                }
0481:
0482:                public final int read() throws IOException {
0483:                    if (_havePeek) {
0484:                        _havePeek = false;
0485:                        return _peek;
0486:                    }
0487:                    final int a = _reader.read();
0488:                    if ('\\' != a)
0489:                        return a;
0490:                    _peek = _reader.read();
0491:                    if ('u' != _peek) {
0492:                        _havePeek = true;
0493:                        return a;
0494:                    }
0495:                    int curr = _peek;
0496:                    while ('u' == curr)
0497:                        curr = _reader.read();
0498:                    final byte[] digits = new byte[4];
0499:                    for (int i = 0; i < 4; i++) {
0500:                        if (0 != i)
0501:                            curr = _reader.read();
0502:                        switch (curr) {
0503:                        case '0':
0504:                        case '1':
0505:                        case '2':
0506:                        case '3':
0507:                        case '4':
0508:                        case '5':
0509:                        case '6':
0510:                        case '7':
0511:                        case '8':
0512:                        case '9':
0513:                            digits[i] = (byte) (curr - '0');
0514:                            break;
0515:                        case 'a':
0516:                        case 'b':
0517:                        case 'c':
0518:                        case 'd':
0519:                        case 'e':
0520:                        case 'f':
0521:                            digits[i] = (byte) (10 + curr - 'a');
0522:                            break;
0523:                        case 'A':
0524:                        case 'B':
0525:                        case 'C':
0526:                        case 'D':
0527:                        case 'E':
0528:                        case 'F':
0529:                            digits[i] = (byte) (10 + curr - 'A');
0530:                            break;
0531:                        default:
0532:                            throw new Error("illegal unicode sequence");
0533:                        }
0534:                    }
0535:                    int result = 0;
0536:                    for (int i = 0; i < 4; i++)
0537:                        result = (result << 4) | digits[i];
0538:                    return result;
0539:                }
0540:
0541:                public final int read(final char[] cbuf, final int off,
0542:                        final int len) throws IOException {
0543:                    int result = 0;
0544:                    while (result < len) {
0545:                        final int c = read();
0546:                        if (-1 == c)
0547:                            return -1;
0548:                        cbuf[off + result] = (char) c;
0549:                        result++;
0550:                    }
0551:                    return result;
0552:                }
0553:            }
0554:
0555:            public static final Set<String> EMPTY_SET = Collections.emptySet();
0556:
0557:            private static final Map<Attribute, String> MODIFIER_TO_NAME = new HashMap<Attribute, String>();
0558:
0559:            private static final Map<String, Type> NAME_TO_BASETYPE = new HashMap<String, Type>();
0560:
0561:            private static final Map<String, Attribute> NAME_TO_MODIFIER = new HashMap<String, Attribute>();
0562:
0563:            private static boolean recursiveTypeDotType = false;
0564:
0565:            static {
0566:                NAME_TO_MODIFIER.put("public", Constants.ATT_PUBLIC);
0567:                NAME_TO_MODIFIER.put("protected", Constants.ATT_PROTECTED);
0568:                NAME_TO_MODIFIER.put("private", Constants.ATT_PRIVATE);
0569:                NAME_TO_MODIFIER.put("static", Constants.ATT_STORAGE_STATIC);
0570:                NAME_TO_MODIFIER.put("abstract", Constants.ATT_ABSTRACT);
0571:                NAME_TO_MODIFIER.put("final", Constants.ATT_CONSTANT);
0572:                NAME_TO_MODIFIER.put("native", Constants.ATT_NATIVE);
0573:                NAME_TO_MODIFIER
0574:                        .put("synchronized", Constants.ATT_SYNCHRONIZED);
0575:                NAME_TO_MODIFIER.put("transient", Constants.ATT_TRANSIENT);
0576:                NAME_TO_MODIFIER.put("volatile", Constants.ATT_VOLATILE);
0577:                NAME_TO_MODIFIER.put("strictfp", Constants.ATT_STRICT_FP);
0578:                for (final Map.Entry<String, Attribute> e : NAME_TO_MODIFIER
0579:                        .entrySet())
0580:                    MODIFIER_TO_NAME.put(e.getValue(), e.getKey());
0581:                NAME_TO_BASETYPE.put("boolean", BooleanT.TYPE);
0582:                NAME_TO_BASETYPE.put("byte", NumberT.BYTE);
0583:                NAME_TO_BASETYPE.put("char", NumberT.CHAR);
0584:                NAME_TO_BASETYPE.put("double", NumberT.DOUBLE);
0585:                NAME_TO_BASETYPE.put("float", NumberT.FLOAT);
0586:                NAME_TO_BASETYPE.put("int", NumberT.INT);
0587:                NAME_TO_BASETYPE.put("long", NumberT.LONG);
0588:                NAME_TO_BASETYPE.put("null", VoidT.TYPE.annotate().constant(
0589:                        NullReference.NULL));
0590:                NAME_TO_BASETYPE.put("short", NumberT.SHORT);
0591:                NAME_TO_BASETYPE.put("void", VoidT.TYPE);
0592:            }
0593:
0594:            public static void addBaseTypes(final SymbolTable tab) {
0595:                if (null == tab.lookup("int")) {
0596:                    final String oldScope = JavaEntities
0597:                            .enterScopeByQualifiedName(tab, "");
0598:                    for (final String name : NAME_TO_BASETYPE.keySet())
0599:                        tab.current().define(name, nameToBaseType(name));
0600:                    JavaEntities.enterScopeByQualifiedName(tab, oldScope);
0601:                }
0602:            }
0603:
0604:            public static List<MethodT> allAbstractMethods(
0605:                    final SymbolTable tab, final List<File> paths,
0606:                    final ClassT clazz) {
0607:                final List<MethodT> all = allMethods(tab, paths, clazz);
0608:                final List<MethodT> specific = mostSpecificMethods(tab, paths,
0609:                        all);
0610:                final List<MethodT> result = new ArrayList<MethodT>();
0611:                for (final MethodT method : specific)
0612:                    if (hasModifier(method, "abstract"))
0613:                        result.add(method);
0614:                return result;
0615:            }
0616:
0617:            public static List<MethodT> allMethods(final SymbolTable tab,
0618:                    final List<File> paths, final ClassT base) {
0619:                final List<MethodT> result = new ArrayList<MethodT>();
0620:                for (final Iterator<Type> i = new SuperTypesIter(tab, paths,
0621:                        base); i.hasNext();)
0622:                    result.addAll(methodsOwn(i.next()));
0623:                return result;
0624:            }
0625:
0626:            public static Set<String> allUsedIdentifiers(final GNode ast) {
0627:                final MiniVisitor_allUsedIdentifiers v = new MiniVisitor_allUsedIdentifiers();
0628:                final Set<String> result = stringSet(v.dispatch(ast));
0629:                return result;
0630:            }
0631:
0632:            public static Type arrayElementType(final ArrayT arrayT) {
0633:                final AnnotatedT l = (AnnotatedT) arrayT.getType();
0634:                final Type result = l.getType();
0635:                assert isRValueT(result);
0636:                return result;
0637:            }
0638:
0639:            public static VariableT arrayLengthField() {
0640:                final VariableT result = VariableT.newField(
0641:                        nameToBaseType("int"), "length");
0642:                result.addAttribute(nameToModifier("final"));
0643:                result.addAttribute(nameToModifier("public"));
0644:                result.scope(".package(java.lang).file().Object");
0645:                assert isFieldT(result);
0646:                return result;
0647:            }
0648:
0649:            public static String baseTypeToName(final Type baseType) {
0650:                return typeToString(null, false, baseType);
0651:            }
0652:
0653:            public static ClassOrInterfaceT canonicalAliasToType(
0654:                    final SymbolTable tab, final List<File> paths,
0655:                    final AliasT alias, final boolean mayBeInUnnamedPackage) {
0656:                if (alias.getType() == null)
0657:                    alias.setType(canonicalNameToType(tab, paths, alias
0658:                            .getName(), mayBeInUnnamedPackage));
0659:                return (ClassOrInterfaceT) alias.getType();
0660:            }
0661:
0662:            public static String canonicalName(final SymbolTable tab,
0663:                    final String simpleName) {
0664:                final ClassOrInterfaceT enclosingClass = currentType(tab);
0665:                if (enclosingClass != null)
0666:                    return Utilities.qualify(enclosingClass.getQName(),
0667:                            simpleName);
0668:                final PackageT enclosingPackage = currentPackage(tab);
0669:                if (enclosingPackage == null) {
0670:                    final Error e = new Error();
0671:                    e.printStackTrace();
0672:                    throw e;
0673:                }
0674:                if ("".equals(enclosingPackage.getName()))
0675:                    return simpleName;
0676:                return Utilities
0677:                        .qualify(enclosingPackage.getName(), simpleName);
0678:            }
0679:
0680:            public static PackageT canonicalNameToPackage(
0681:                    final SymbolTable tab, final String name) {
0682:                if (name.indexOf('.') == -1)
0683:                    return simpleNameToPackage(tab, name);
0684:                final PackageT base = canonicalNameToPackage( //
0685:                        tab, Utilities.getQualifier(name));
0686:                return packageDotPackage(tab, base, Utilities.unqualify(name));
0687:            }
0688:
0689:            public static Type canonicalNameToPackageOrType(
0690:                    final SymbolTable tab, final List<File> paths,
0691:                    final String name, final boolean mayBeInUnnamedPackage) {
0692:                final Type t = canonicalNameToType(tab, paths, name,
0693:                        mayBeInUnnamedPackage);
0694:                return t != null ? t : canonicalNameToPackage(tab, name);
0695:            }
0696:
0697:            public static ClassOrInterfaceT canonicalNameToType(
0698:                    final SymbolTable tab, final List<File> paths,
0699:                    final String name, final boolean mayBeInUnnamedPackage) {
0700:                if (name.indexOf('.') == -1) {
0701:                    if (mayBeInUnnamedPackage)
0702:                        return packageDotType(tab, paths, simpleNameToPackage(
0703:                                tab, ""), name);
0704:                    return null;
0705:                }
0706:                final String qualifier = Utilities.getQualifier(name);
0707:                final String selector = Utilities.unqualify(name);
0708:                if (qualifier.indexOf('.') == -1)
0709:                    return packageDotType(tab, paths, simpleNameToPackage(tab,
0710:                            qualifier), selector);
0711:                final Type base = canonicalNameToPackageOrType(tab, paths,
0712:                        qualifier, mayBeInUnnamedPackage);
0713:                if (base.isPackage())
0714:                    return packageDotType(tab, paths, base.toPackage(),
0715:                            selector);
0716:                return typeDotType(tab, paths, (ClassOrInterfaceT) base, false,
0717:                        selector);
0718:            }
0719:
0720:            public static List<File> classpath(final Runtime runtime) {
0721:                return runtime.getFileList(Runtime.INPUT_DIRECTORY);
0722:            }
0723:
0724:            public static boolean constructorsReturnVoid() {
0725:                return true;
0726:            }
0727:
0728:            /** Can only create concrete subclass that implements all abstract methods if there
0729:             * is no pair of abstract methods with the same signature, but different return types. */
0730:            public static boolean couldCreateConcreteSubclass(
0731:                    final SymbolTable tab, final List<File> paths,
0732:                    final ClassT clazz) {
0733:                final List<MethodT> abstractMethods = allAbstractMethods(tab,
0734:                        paths, clazz);
0735:                for (final MethodT m : abstractMethods)
0736:                    resolveIfAliasMethod(tab, paths, m);
0737:                for (final MethodT m1 : abstractMethods)
0738:                    for (final MethodT m2 : abstractMethods)
0739:                        if (m1.getName().equals(m2.getName())
0740:                                && sameMethodSignature(m1, m2))
0741:                            if (!JavaTypeConverter.isIdentical(m1.getResult(),
0742:                                    m2.getResult()))
0743:                                return false;
0744:                return true;
0745:            }
0746:
0747:            public static List<Type> currentImports(final SymbolTable tab) {
0748:                for (SymbolTable.Scope s = tab.current(); !s.isRoot(); s = s
0749:                        .getParent()) {
0750:                    final String n = s.getName();
0751:                    if (SymbolTable.isInNameSpace(n, "file"))
0752:                        return imports(tab, currentPackage(tab), SymbolTable
0753:                                .fromNameSpace(n));
0754:                }
0755:                return imports(tab, null, null);
0756:            }
0757:
0758:            public static MethodT currentMethod(final SymbolTable tab) {
0759:                for (SymbolTable.Scope s = tab.current(); !s.isRoot(); s = s
0760:                        .getParent()) {
0761:                    final String name = s.getName();
0762:                    if (SymbolTable.isInNameSpace(name, "method")) {
0763:                        final ClassOrInterfaceT type = currentType(tab);
0764:                        for (final Type method : type.getMethods()) {
0765:                            assert method.isMethod();
0766:                            final String s2;
0767:                            assert method.hasScope(false);
0768:                            s2 = method.getScope();
0769:                            if (s.getQualifiedName().equals(s2))
0770:                                return method.toMethod();
0771:                        }
0772:                    }
0773:                }
0774:                return null;
0775:            }
0776:
0777:            public static PackageT currentPackage(final SymbolTable tab) {
0778:                for (SymbolTable.Scope s = tab.current(); !s.isRoot(); s = s
0779:                        .getParent()) {
0780:                    final String n = s.getName();
0781:                    if (n.startsWith("package("))
0782:                        return canonicalNameToPackage(tab, SymbolTable
0783:                                .fromNameSpace(n));
0784:                }
0785:                return canonicalNameToPackage(tab, "");
0786:            }
0787:
0788:            public static ClassOrInterfaceT currentType(final SymbolTable tab) {
0789:                for (SymbolTable.Scope s = tab.current(); !s.isRoot(); s = s
0790:                        .getParent()) {
0791:                    final String tagName = SymbolTable.toTagName(s.getName());
0792:                    final ClassOrInterfaceT result = (ClassOrInterfaceT) s
0793:                            .getParent().lookup(tagName);
0794:                    if (result != null)
0795:                        return result;
0796:                }
0797:                return null;
0798:            }
0799:
0800:            public static PackageT declaringPackage(final SymbolTable tab,
0801:                    final Type type) {
0802:                if (type.isPackage())
0803:                    return (PackageT) type;
0804:                if (type instanceof  ClassOrInterfaceT
0805:                        && isTypeTopLevel((ClassOrInterfaceT) type)) {
0806:                    final String oldScope = enterScopeByQualifiedName(tab,
0807:                            typeToScopeName(type));
0808:                    final PackageT result = currentPackage(tab);
0809:                    enterScopeByQualifiedName(tab, oldScope);
0810:                    return result;
0811:                }
0812:                if (isTypeMember(type))
0813:                    return declaringPackage(tab, declaringType(tab, type));
0814:                final String oldScope = enterScopeByQualifiedName(tab,
0815:                        declaringScopeName(type));
0816:                final PackageT result = currentPackage(tab);
0817:                enterScopeByQualifiedName(tab, oldScope);
0818:                return result;
0819:            }
0820:
0821:            public static String declaringScopeName(final Type type) {
0822:                assert !type.isAlias();
0823:                final Type u = isConstantT(type) ? ((AnnotatedT) type)
0824:                        .getType() : type;
0825:                if (u.hasScope(false)) {
0826:                    final String ownScope = u.getScope();
0827:                    if (isLocalT(type) || isParameterT(type) || isFieldT(type))
0828:                        return ownScope;
0829:                    return Utilities.getQualifier(ownScope);
0830:                }
0831:                return null;
0832:            }
0833:
0834:            public static ClassOrInterfaceT declaringType(
0835:                    final SymbolTable tab, final Type member) {
0836:                assert member.isMethod() || isFieldT(member)
0837:                        || isWrappedClassT(member)
0838:                        || isWrappedInterfaceT(member);
0839:                final String declaringScope = declaringScopeName(member);
0840:                assert null != declaringScope;
0841:                assert isScopeForMember(declaringScope);
0842:                final String oldScope = enterScopeByQualifiedName(tab,
0843:                        declaringScope);
0844:                final ClassOrInterfaceT result = currentType(tab);
0845:                assert null != result;
0846:                enterScopeByQualifiedName(tab, oldScope);
0847:                return result;
0848:            }
0849:
0850:            public static Type dereference(final Type generalLValue) {
0851:                assert isGeneralLValueT(generalLValue);
0852:                final WrappedT wrapped = isLValueT(generalLValue) ? (AnnotatedT) generalLValue
0853:                        : resolveToRawLValue(generalLValue);
0854:                final Type result = wrapped.getType();
0855:                assert isGeneralRValueT(result);
0856:                return result;
0857:            }
0858:
0859:            public static List<ClassOrInterfaceT> directSuperTypes(
0860:                    final SymbolTable tab, final List<File> paths,
0861:                    final Type sub) {
0862:                if (sub.isArray()) {
0863:                    final List<ClassOrInterfaceT> result = new ArrayList<ClassOrInterfaceT>();
0864:                    result.add(JavaEntities.tObject(tab));
0865:                    result.add(JavaEntities.tCloneable(tab));
0866:                    result.add(JavaEntities.tSerializable(tab));
0867:                    return result;
0868:                }
0869:                final ClassOrInterfaceT rawSub = JavaEntities
0870:                        .resolveToRawClassOrInterfaceT(sub);
0871:                final List<AliasT> aliases = new ArrayList<AliasT>();
0872:                if (JavaEntities.isWrappedClassT(sub)) {
0873:                    final Type sup = rawSub.toClass().getParent();
0874:                    if (null != sup)
0875:                        aliases.add(sup.toAlias());
0876:                }
0877:                for (final Type i : rawSub.getInterfaces())
0878:                    aliases.add(i.toAlias());
0879:                final String scope = JavaEntities.typeToScopeName(sub);
0880:                return JavaEntities.qualifiedAliasesToTypes(tab, paths, scope,
0881:                        aliases);
0882:            }
0883:
0884:            public static String enterScopeByQualifiedName(
0885:                    final SymbolTable tab, final String name) {
0886:                final String oldScopeName = tab.current().getQualifiedName();
0887:                assert null != name;
0888:                tab.setScope(tab.getScope(name));
0889:                return oldScopeName;
0890:            }
0891:
0892:            public static List<VariableT> fieldsApplicableAndAccessible(
0893:                    final SymbolTable tab, final List<File> paths,
0894:                    final Type base, final boolean parents, final String name) {
0895:                final List<VariableT> fields = parents ? fieldsOwnAndInherited(
0896:                        tab, paths, base) : fieldsOwn(base);
0897:                final List<VariableT> result = new ArrayList<VariableT>();
0898:                for (final VariableT field : fields)
0899:                    if (isAccessibleIn(tab, paths, field, base))
0900:                        if (isApplicableField(tab, paths, field, name))
0901:                            result.add(field);
0902:                return result;
0903:            }
0904:
0905:            public static List<VariableT> fieldsInherited(
0906:                    final SymbolTable tab, final List<File> paths,
0907:                    final Type base) {
0908:                //gosling_et_al_2000 8.3 (before subsections)
0909:                final List<VariableT> result = new ArrayList<VariableT>();
0910:                final List<VariableT> fieldsOwn = fieldsOwn(base);
0911:                final String baseScope = declaringScopeName(base);
0912:                assert null != baseScope || base.isArray();
0913:                final List<ClassOrInterfaceT> super Types = directSuperTypes(
0914:                        tab, paths, base);
0915:                for (final ClassOrInterfaceT super Type : super Types) {
0916:                    final List<VariableT> super Fields = fieldsOwnAndInherited(
0917:                            tab, paths, super Type);
0918:                    super Fields: for (final VariableT f : super Fields) {
0919:                        if (hasModifier(f, "private"))
0920:                            continue super Fields;
0921:                        if (null != baseScope
0922:                                && !isAccessibleFromIn(tab, paths, baseScope,
0923:                                        f, super Type))
0924:                            continue super Fields;
0925:                        for (final VariableT o : fieldsOwn)
0926:                            if (f.getName().equals(o.getName()))
0927:                                continue super Fields;
0928:                        for (final VariableT r : result)
0929:                            if (f == r)
0930:                                continue super Fields;
0931:                        result.add(f);
0932:                    }
0933:                }
0934:                return result;
0935:            }
0936:
0937:            public static List<VariableT> fieldsOwn(final Type base) {
0938:                final List<VariableT> result = new ArrayList<VariableT>(1);
0939:                if (base.isArray())
0940:                    result.add(arrayLengthField());
0941:                else
0942:                    for (final Type f : resolveToRawClassOrInterfaceT(base)
0943:                            .getFields())
0944:                        result.add(f.toVariable());
0945:                return result;
0946:            }
0947:
0948:            public static List<VariableT> fieldsOwnAndInherited(
0949:                    final SymbolTable tab, final List<File> paths,
0950:                    final Type base) {
0951:                final List<VariableT> result = new ArrayList<VariableT>();
0952:                result.addAll(fieldsInherited(tab, paths, base));
0953:                result.addAll(fieldsOwn(base));
0954:                return result;
0955:            }
0956:
0957:            public static String fileNameToScopeName(final String absolutePath) {
0958:                return SymbolTable.toNameSpace(absolutePath, "file");
0959:            }
0960:
0961:            /** Does the class or one of its superclasses declare any abstract methods
0962:             * that have not been implemented here or in a superclass? (gosling_et_al_2000 <a
0963:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#34944">&sect;8.1.1</a>). */
0964:            public static boolean hasAbstractMethods(final SymbolTable tab,
0965:                    final List<File> paths, final ClassT clazz) {
0966:                return !allAbstractMethods(tab, paths, clazz).isEmpty();
0967:            }
0968:
0969:            /** Does the class depend on itself by inheritance or by nesting? (gosling_et_al_2000 <a
0970:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#262560">&sect;8.1.3</a>). */
0971:            public static boolean hasCircularDependency(final SymbolTable tab,
0972:                    final List<File> paths, final ClassOrInterfaceT type) {
0973:                final Iterator<Type> iSup = new SuperTypesIter(tab, paths,
0974:                        type, false);
0975:                while (iSup.hasNext()) {
0976:                    Type t = iSup.next();
0977:                    inner: while (true) {
0978:                        if (JavaTypeConverter.isIdentical(type, t))
0979:                            return true;
0980:                        if (!isTypeMember(t))
0981:                            break inner;
0982:                        t = declaringType(tab, t);
0983:                    }
0984:                }
0985:                return false;
0986:            }
0987:
0988:            public static boolean hasModifier(final Type t, final String m) {
0989:                final Type u = t.isAlias() ? ((AliasT) t).getType() : t;
0990:                assert isGeneralLValueT(u) || u.isMethod() || u.isClass()
0991:                        || u.isInterface();
0992:                return u.hasAttribute(nameToModifier(m), false);
0993:            }
0994:
0995:            static List<Type> imports(final SymbolTable tab,
0996:                    final PackageT packageT, final String fileName) {
0997:                final String baseScope = null == packageT ? "" : scopeName(
0998:                        packageT, fileName);
0999:                final Object o = tab.lookup(Utilities.qualify(baseScope,
1000:                        "imports(*)"));
1001:                if (null == o)
1002:                    return new ArrayList<Type>();
1003:                if (o instanceof  List)
1004:                    return typeList((List) o);
1005:                final ArrayList<Type> list = new ArrayList<Type>();
1006:                list.add((Type) o);
1007:                return list;
1008:            }
1009:
1010:            /** Is it allowed to use the entity from the current scope of the symbol table (gosling_et_al_2000 <a
1011:             * href="http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#104285">&sect;6.6</a>)? */
1012:            public static boolean isAccessible(final SymbolTable tab,
1013:                    final List<File> paths, final Type entity) {
1014:                return isAccessibleIn(tab, paths, entity, null);
1015:            }
1016:
1017:            public static boolean isAccessibleFromIn(final SymbolTable tab,
1018:                    final List<File> paths, final String scope,
1019:                    final Type entity, final Type inType) {
1020:                final String oldScope = JavaEntities.enterScopeByQualifiedName(
1021:                        tab, scope);
1022:                final boolean result = isAccessibleIn(tab, paths, entity,
1023:                        inType);
1024:                JavaEntities.enterScopeByQualifiedName(tab, oldScope);
1025:                return result;
1026:            }
1027:
1028:            public static boolean isAccessibleIn(final SymbolTable tab,
1029:                    final List<File> paths, final Type entity, final Type inType) {
1030:                if (entity.isArray())
1031:                    return true;
1032:                if (entity.isAlias())
1033:                    return isAccessible(tab, paths, ((AliasT) entity).getType());
1034:                if (entity.isPackage())
1035:                    return true;
1036:                final boolean samePackage = declaringPackage(tab, entity)
1037:                        .getName().equals(currentPackage(tab).getName());
1038:                if (isWrappedClassT(entity) || isWrappedInterfaceT(entity)) {
1039:                    if (hasModifier(entity, "public"))
1040:                        return true;
1041:                    if (isTypeTopLevel((ClassOrInterfaceT) entity))
1042:                        return samePackage;
1043:                }
1044:                if (!isTypeMember(entity))
1045:                    return true;
1046:                final Type base = null == inType ? declaringType(tab, entity)
1047:                        : inType;
1048:                assert null != base;
1049:                if (!isAccessible(tab, paths, base))
1050:                    return false;
1051:                if (hasModifier(entity, "public"))
1052:                    return true;
1053:                if (hasModifier(entity, "protected")) {
1054:                    if (samePackage)
1055:                        return true;
1056:                    if (entity.isMethod()
1057:                            && isConstructor(base, entity.toMethod())) {
1058:                        return false; //TD 36 (6.6.2) isAccessibleIn() for protected constructors in different package
1059:                    } else {
1060:                        final Type decl = declaringType(tab, entity), curr = currentType(tab);
1061:                        return (null == curr || isSuperClass(tab, paths, decl,
1062:                                curr))
1063:                                && isSuperClass(tab, paths, decl, base);
1064:                    }
1065:                }
1066:                if (hasModifier(entity, "private")) {
1067:                    final Type top;
1068:                    final String oldScope = enterScopeByQualifiedName(tab,
1069:                            typeToScopeName(base));
1070:                    while (true) {
1071:                        final ClassOrInterfaceT t = JavaEntities
1072:                                .currentType(tab);
1073:                        enterScopeByQualifiedName(tab, typeToScopeName(t));
1074:                        if (isTypeTopLevel(t)) {
1075:                            top = t;
1076:                            break;
1077:                        }
1078:                        tab.exit();
1079:                    }
1080:                    enterScopeByQualifiedName(tab, oldScope);
1081:                    return tab.current().getQualifiedName().startsWith(
1082:                            typeToScopeName(top));
1083:                }
1084:                return samePackage;
1085:            }
1086:
1087:            public static boolean isApplicableField(final SymbolTable tab,
1088:                    final List<File> paths, final VariableT field,
1089:                    final String name) {
1090:                if (name.equals(field.getName())) {
1091:                    final ClassOrInterfaceT declaringType = declaringType(tab,
1092:                            field);
1093:                    resolveIfAlias(tab, paths, typeToScopeName(declaringType),
1094:                            field.getType());
1095:                    return true;
1096:                }
1097:                return false;
1098:            }
1099:
1100:            public static boolean isApplicableMemberType(final Type memberType,
1101:                    final String name) {
1102:                final ClassOrInterfaceT raw = resolveToRawClassOrInterfaceT(memberType);
1103:                return name.equals(raw.getName());
1104:            }
1105:
1106:            public static boolean isApplicableMethod(final SymbolTable tab,
1107:                    final List<File> paths, final MethodT callee,
1108:                    final String name, final List<Type> actuals) {
1109:                if (!callee.getName().equals(name))
1110:                    return false;
1111:                final List<Type> formals = callee.getParameters();
1112:                if (formals.size() != actuals.size())
1113:                    return false;
1114:                final ClassOrInterfaceT declaringType = declaringType(tab,
1115:                        callee);
1116:                final String aScope = tab.current().getQualifiedName();
1117:                final Iterator<Type> iF = formals.iterator(), iA = actuals
1118:                        .iterator();
1119:                while (iF.hasNext()) {
1120:                    final Type formal = iF.next();
1121:                    resolveIfAlias(tab, paths, typeToScopeName(declaringType),
1122:                            dereference(formal));
1123:                    final Type aAlias = iA.next();
1124:                    final Type actual = resolveIfAlias(tab, paths, aScope,
1125:                            aAlias);
1126:                    final boolean conv = JavaTypeConverter.isParameterPassable(
1127:                            tab, paths, dereference(formal), actual);
1128:                    if (!conv)
1129:                        return false;
1130:                }
1131:                return true;
1132:            }
1133:
1134:            public static boolean isCheckedException(final SymbolTable tab,
1135:                    final List<File> paths, final Type exc) {
1136:                // gosling_et_al_2000 11.2
1137:                return isSuperClass(tab, paths, tThrowable(tab), exc)
1138:                        && !isSuperClass(tab, paths, tRuntimeException(tab),
1139:                                exc)
1140:                        && !isSuperClass(tab, paths, tError(tab), exc);
1141:            }
1142:
1143:            public static boolean isConstantT(final Type t) {
1144:                return (null != t) && t.isAnnotated() && t.hasConstant(false);
1145:            }
1146:
1147:            public static boolean isConstructor(final Type declaringType,
1148:                    final MethodT maybeConstructor) {
1149:                if (!declaringType.isClass())
1150:                    return false;
1151:                return declaringType.toClass().getName().equals(
1152:                        maybeConstructor.getName());
1153:            }
1154:
1155:            /** ExpressionT &gt; GeneralLValueT, GeneralRValueT. */
1156:            public static boolean isExpressionT(final Type t) {
1157:                return isGeneralLValueT(t) || isGeneralRValueT(t);
1158:            }
1159:
1160:            /** FieldT = Name WrappedRValueT. */
1161:            public static boolean isFieldT(final Type t) {
1162:                return t.isVariable()
1163:                        && VariableT.Kind.FIELD == t.toVariable().getKind();
1164:            }
1165:
1166:            /** GeneralLValueT &gt; LValueT, VariableT, FieldT, ParameterT. */
1167:            public static boolean isGeneralLValueT(final Type t) {
1168:                return isLValueT(t) || isLocalT(t) || isFieldT(t)
1169:                        || isParameterT(t);
1170:            }
1171:
1172:            /** GeneralRValueT &gt; NullT, WrappedRValueT. */
1173:            public static boolean isGeneralRValueT(final Type t) {
1174:                return isNullT(t) || isWrappedRValueT(t);
1175:            }
1176:
1177:            public static boolean isInLocalNameSpace(final String name) {
1178:                final String lastPart = Utilities.unqualify(name);
1179:                return SymbolTable.isInNameSpace(lastPart, "method")
1180:                        || SymbolTable.isInNameSpace(lastPart, "block")
1181:                        || SymbolTable.isInNameSpace(lastPart, "forStatement")
1182:                        || SymbolTable.isInNameSpace(lastPart,
1183:                                "labeledStatement")
1184:                        || SymbolTable.isInNameSpace(lastPart, "function") //in Jeannie, not in Java
1185:                        || SymbolTable.isInNameSpace(lastPart, "withStatement") //in Jeannie, not in Java
1186:                        || SymbolTable.isInNameSpace(lastPart, "matchClause") //in Matchete, not in Java
1187:                        || SymbolTable.isInNameSpace(lastPart, "catchClause");
1188:            }
1189:
1190:            public static boolean isInt(final Type t) {
1191:                final Type n = JavaTypeConverter.promoteUnaryNumeric(t);
1192:                if (null == n)
1193:                    return false;
1194:                final Type r = resolveToRawRValue(n);
1195:                return r.isInteger()
1196:                        && NumberT.Kind.INT == ((IntegerT) r).getKind();
1197:            }
1198:
1199:            /** LocalT = Name WrappedRValueT. */
1200:            public static boolean isLocalT(final Type t) {
1201:                return t.isVariable()
1202:                        && VariableT.Kind.LOCAL == t.toVariable().getKind();
1203:            }
1204:
1205:            /** LValueT = RValueT. */
1206:            public static boolean isLValueT(final Type t) {
1207:                return (null != t) && t.isAnnotated() && t.hasShape(false);
1208:            }
1209:
1210:            /** NotAValueT &gt; PackageT, AnnotatedT:ReturnT --- annotated with Constants.ATT_NOT_A_VALUE */
1211:            public static boolean isNotAValueT(final Type t) {
1212:                return t.isPackage() || t instanceof  AnnotatedT
1213:                        && t.hasAttribute(Constants.ATT_NOT_A_VALUE)
1214:                        && isReturnT(((AnnotatedT) t).getType());
1215:            }
1216:
1217:            /** NullT = ConstantT:VoidT. */
1218:            public static boolean isNullT(final Type t) {
1219:                return isConstantT(t) && ((AnnotatedT) t).getType().isVoid();
1220:            }
1221:
1222:            /** ParameterT = Name RValueT. */
1223:            public static boolean isParameterT(final Type t) {
1224:                return t.isVariable()
1225:                        && VariableT.Kind.PARAMETER == t.toVariable().getKind();
1226:            }
1227:
1228:            /** PrimitiveT &gt; BooleanT, NumberT. */
1229:            public static boolean isPrimitiveT(final Type t) {
1230:                return t.isBoolean() || t.isNumber();
1231:            }
1232:
1233:            /** Is t a class, interface, or array type (gosling_et_al_2000 <a
1234:             * href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#9317">&sect;4.3</a>)?  */
1235:            public static boolean isReferenceT(final Type t) {
1236:                if (isNullT(t))
1237:                    return true;
1238:                final Type u = isConstantT(t) ? ((AnnotatedT) t).getType() : t;
1239:                return u.isArray() || isWrappedClassT(u)
1240:                        || isWrappedInterfaceT(u);
1241:            }
1242:
1243:            /** ReturnT &gt; VoidT, RValueT. */
1244:            public static boolean isReturnT(final Type t) {
1245:                return t.isVoid() || isRValueT(t);
1246:            }
1247:
1248:            /** RValueT &gt; PrimitiveT, ArrayT, WrappedClassT, WrappedInterfaceT. */
1249:            public static boolean isRValueT(final Type t) {
1250:                return isPrimitiveT(t) || t.isArray() || isWrappedClassT(t)
1251:                        || isWrappedInterfaceT(t);
1252:            }
1253:
1254:            public static boolean isScopeForMember(final String scopeName) {
1255:                // gosling_et_al_2000 8.5, 9.5
1256:                return isScopeNested(scopeName)
1257:                        && !isInLocalNameSpace(scopeName);
1258:            }
1259:
1260:            public static boolean isScopeLocal(final String scopeName) {
1261:                //gosling_et_al_2000 14.3
1262:                return isInLocalNameSpace(scopeName);
1263:            }
1264:
1265:            public static boolean isScopeNested(final String scopeName) {
1266:                //gosling_et_al_2000 intro paragraph to chapters 8 and 9
1267:                if (isScopeTopLevel(scopeName))
1268:                    return false;
1269:                return 3 < Utilities.toComponents(scopeName).length;
1270:            }
1271:
1272:            public static boolean isScopeTopLevel(final String scopeName) {
1273:                //gosling_et_al_2000 7.6
1274:                if (null == scopeName)
1275:                    System.out.println("hohoho");
1276:                assert null != scopeName;
1277:                if ("".equals(scopeName) || ".".equals(scopeName))
1278:                    return true; //top-level in C file
1279:                final String[] scopeParts = Utilities.toComponents(scopeName);
1280:                if (0 < scopeParts.length)
1281:                    assert "".equals(scopeParts[0]);
1282:                if (2 < scopeParts.length
1283:                        && SymbolTable.isInNameSpace(scopeParts[1], "package")) {
1284:                    assert SymbolTable.isInNameSpace(scopeParts[2], "file");
1285:                    return 3 == scopeParts.length; //top-level in Java file
1286:                }
1287:                return false;
1288:            }
1289:
1290:            public static boolean isSuperClass(final SymbolTable tab,
1291:                    final List<File> paths, final Type sup, final Type sub) {
1292:                if (!isWrappedClassT(sub) || !isWrappedClassT(sup))
1293:                    return false;
1294:                return JavaTypeConverter.isIdentical(sup, sub)
1295:                        || JavaTypeConverter.isWiderReference(tab, paths, sup,
1296:                                sub);
1297:            }
1298:
1299:            /** Note: not symmetric! */
1300:            public static boolean isSuperMethod(final SymbolTable tab,
1301:                    final List<File> paths, final MethodT sup, final MethodT sub) {
1302:                if (!sub.getName().equals(sup.getName()))
1303:                    return false;
1304:                if (sub.getParameters().size() != sup.getParameters().size())
1305:                    return false;
1306:                if (hasModifier(sup, "private"))
1307:                    return false;
1308:                final ClassOrInterfaceT dSup = declaringType(tab, sup), dSub = declaringType(
1309:                        tab, sub);
1310:                if (!isAccessibleFromIn(tab, paths, typeToScopeName(dSub), sup,
1311:                        dSup))
1312:                    return false;
1313:                if (!JavaTypeConverter.isParameterPassable(tab, paths, dSup,
1314:                        dSub))
1315:                    return false;
1316:                final Iterator<Type> iSub = sub.getParameters().iterator();
1317:                final Iterator<Type> iSup = sup.getParameters().iterator();
1318:                while (iSub.hasNext()) {
1319:                    final VariableT tSup = iSup.next().toVariable(), tSub = iSub
1320:                            .next().toVariable();
1321:                    final Type rSup = tSup.getType(), rSub = tSub.getType();
1322:                    resolveIfAlias(tab, paths, declaringScopeName(sup), rSup);
1323:                    resolveIfAlias(tab, paths, declaringScopeName(sub), rSub);
1324:                    if (!JavaTypeConverter.isParameterPassable(tab, paths,
1325:                            rSup, rSub))
1326:                        return false;
1327:                }
1328:                if (JavaTypeConverter.isIdentical(dSup, dSub)
1329:                        && sameMethodSignature(sup, sub)) {
1330:                    //Java 1.5 introduces contravariant return types, and we must tackle them in libraries, such as StringBuffer
1331:                    final Type tSup = sup.getResult(), tSub = sub.getResult();
1332:                    resolveIfAlias(tab, paths, declaringScopeName(sup), tSup);
1333:                    resolveIfAlias(tab, paths, declaringScopeName(sub), tSub);
1334:                    if (!JavaTypeConverter.isReturnTypeSubstitutable(tab,
1335:                            paths, tSup, tSub))
1336:                        return false;
1337:                }
1338:                return true;
1339:            }
1340:
1341:            public static boolean isTypeAnonymous(final ClassOrInterfaceT t) {
1342:                return t.isClass() && null == t.toClass().getName();
1343:            }
1344:
1345:            public static boolean isTypeInner(final ClassOrInterfaceT t) {
1346:                // gosling_et_al_2000 8.1.2
1347:                return !hasModifier(t, "static") && isTypeNested(t);
1348:            }
1349:
1350:            public static boolean isTypeLocal(final ClassOrInterfaceT t) {
1351:                // gosling_et_al_2000 14.3
1352:                return isScopeLocal(declaringScopeName(t))
1353:                        && !isTypeAnonymous(t);
1354:            }
1355:
1356:            public static boolean isTypeMember(final Type t) {
1357:                return isScopeForMember(declaringScopeName(t));
1358:            }
1359:
1360:            public static boolean isTypeNamed(final ClassOrInterfaceT t) {
1361:                return !isTypeAnonymous(t);
1362:            }
1363:
1364:            public static boolean isTypeNested(final ClassOrInterfaceT t) {
1365:                final String scope = declaringScopeName(t);
1366:                assert null != scope;
1367:                return isScopeNested(scope);
1368:            }
1369:
1370:            public static boolean isTypeTopLevel(final ClassOrInterfaceT t) {
1371:                return isScopeTopLevel(declaringScopeName(t));
1372:            }
1373:
1374:            /** WrappedClassT = AliasT:Name / AliasT:ResolvedClassT / ResolvedClassT. */
1375:            public static boolean isWrappedClassT(final Type t) {
1376:                if (t.isAlias()) {
1377:                    final Type r = ((AliasT) t).getType();
1378:                    return null == r || r.isClass();
1379:                }
1380:                return t.isClass();
1381:            }
1382:
1383:            /** WrappedInterfaceT = AliasT:Name / AliasT:ResolvedInterfaceT / ResolvedInterfaceT. */
1384:            public static boolean isWrappedInterfaceT(final Type t) {
1385:                if (t.isAlias()) {
1386:                    final Type r = ((AliasT) t).getType();
1387:                    return null == r || r.isInterface();
1388:                }
1389:                return t.isInterface();
1390:            }
1391:
1392:            /** WrappedRValueT = ConstantT:RValueT / RValueT. */
1393:            public static boolean isWrappedRValueT(final Type t) {
1394:                return isConstantT(t) && isRValueT(((AnnotatedT) t).getType())
1395:                        || isRValueT(t);
1396:            }
1397:
1398:            public static String javaAstToString(final Node ast) {
1399:                final CharArrayWriter writer = new CharArrayWriter();
1400:                final JavaPrinter printer = new JavaPrinter(new Printer(writer));
1401:                printer.dispatch(ast);
1402:                return writer.toString();
1403:            }
1404:
1405:            /**
1406:             * Don't use this method gratuitously. Originally, I used this to serialize
1407:             * ASTs into strings, then concatenated the strings into more code, then
1408:             * reparsed the result to a larger AST. But that is slow and less elegant
1409:             * than using FactoryFactory.
1410:             */
1411:            private static GNode javaStringToAst(final String production,
1412:                    final String code) {
1413:                try {
1414:                    return JavaEntities.javaStringToAst(production, code, true);
1415:                } catch (final Exception e) {
1416:                    throw new Error(e);
1417:                }
1418:            }
1419:
1420:            public static GNode javaStringToAst(final String production,
1421:                    final String escaped, final boolean simple)
1422:                    throws Exception {
1423:                final Method method = JavaParser.class.getDeclaredMethod("p"
1424:                        + production, Integer.TYPE);
1425:                method.setAccessible(true);
1426:                final String string = unicodeUnescape(escaped);
1427:                final JavaParser parser = new JavaParser( //
1428:                        new StringReader(string), "<input>", string.length());
1429:                final Object[] paramValues = { new Integer(0) };
1430:                final Result parseResult = (Result) method.invoke(parser,
1431:                        paramValues);
1432:                if (!parseResult.hasValue())
1433:                    parser.signal(parseResult.parseError());
1434:                if (parseResult.index != string.length())
1435:                    throw new ParseException("input not fully consumed");
1436:                final GNode ast = (GNode) parseResult.semanticValue();
1437:                if (simple)
1438:                    return (GNode) new JavaAstSimplifier().dispatch(ast);
1439:                return ast;
1440:            }
1441:
1442:            public static Type javaStringToType(final String code) {
1443:                final SymbolTable tab = new SymbolTable();
1444:                JavaUnitTests.enterPackageFile(tab, "", "<input>");
1445:                return javaStringToType(code, tab);
1446:            }
1447:
1448:            private static Type javaStringToType(final String code,
1449:                    final SymbolTable tab) {
1450:                final GNode ast = JavaEntities.javaStringToAst("Type", code);
1451:                final JavaAnalyzer ana = new JavaAnalyzer(JavaUnitTests
1452:                        .newRuntime(), tab);
1453:                final Type result = (Type) ana.dispatch(ast);
1454:                return result;
1455:            }
1456:
1457:            public static GNode javaTypeToAst(final SymbolTable tab,
1458:                    final Type type) {
1459:                final String s = JavaEntities.javaTypeToString(tab, type);
1460:                final GNode result = JavaEntities.javaStringToAst("ResultType",
1461:                        s);
1462:                return scrubLocations(result);
1463:            }
1464:
1465:            public static String javaTypeToString(final SymbolTable tab,
1466:                    final Type type) {
1467:                if (JavaEntities.isGeneralRValueT(type)) {
1468:                    final Type r = JavaEntities.resolveToRawRValue(type);
1469:                    return JavaEntities.typeToString(tab, false, r);
1470:                }
1471:                return JavaEntities.typeToString(tab, false, type);
1472:            }
1473:
1474:            /**
1475:             * Resolve single-type import. The name is canonical (gosling_et_al_2000
1476:             * Section 7.5.1) and denotes a class or interface. The only thing that is
1477:             * uncertain is where the package ends and where the nested types start. For
1478:             * example, in a.b.c, it could be that the package is a.b and the class is c,
1479:             * or that the package is a, the outer class is b, and the inner class is c.
1480:             * There can be no ambiguity (gosling_et_al_2000 Section 6.4), because a
1481:             * package must not have a top-level type and a subpackage of the same name.
1482:             */
1483:            static ClassOrInterfaceT lookupImport(final SymbolTable tab,
1484:                    final List<File> paths, final AliasT alias) {
1485:                return canonicalAliasToType(tab, paths, alias, false);
1486:            }
1487:
1488:            public static List<Type> memberTypesApplicableAndAccessible(
1489:                    final SymbolTable tab, final List<File> paths,
1490:                    final ClassOrInterfaceT base, final boolean parents,
1491:                    final String name) {
1492:                final List<Type> memberTypes = parents ? memberTypesOwnAndInherited(
1493:                        tab, paths, base)
1494:                        : memberTypesOwn(tab, paths, base);
1495:                final List<Type> result = new ArrayList<Type>();
1496:                for (final Type memberType : memberTypes)
1497:                    if (isAccessibleIn(tab, paths, memberType, base))
1498:                        if (isApplicableMemberType(memberType, name))
1499:                            result.add(memberType);
1500:                return result;
1501:            }
1502:
1503:            public static List<Type> memberTypesInherited(
1504:                    final SymbolTable tab, final List<File> paths,
1505:                    final ClassOrInterfaceT base) {
1506:                //gosling_et_al_2000 8.5 (before subsections)
1507:                final List<Type> result = new ArrayList<Type>();
1508:                final List<Type> memberTypesOwn = memberTypesOwn(tab, paths,
1509:                        base);
1510:                final String baseScope = declaringScopeName(base);
1511:                assert null != baseScope || base.isArray();
1512:                final List<ClassOrInterfaceT> super Types = directSuperTypes(
1513:                        tab, paths, base);
1514:                for (final ClassOrInterfaceT super Type : super Types) {
1515:                    final List<Type> super MemberTypes = memberTypesOwnAndInherited(
1516:                            tab, paths, super Type);
1517:                    super MemberTypes: for (final Type t : super MemberTypes) {
1518:                        //the private and accessible checks are here for consistency with fieldsInherited, the specification doesn't explicitly mention them
1519:                        if (hasModifier(t, "private"))
1520:                            continue super MemberTypes;
1521:                        if (null != baseScope
1522:                                && !isAccessibleFromIn(tab, paths, baseScope,
1523:                                        t, super Type))
1524:                            continue super MemberTypes;
1525:                        final String tName = resolveToRawClassOrInterfaceT(t)
1526:                                .getName();
1527:                        for (final Type o : memberTypesOwn)
1528:                            if (tName.equals(resolveToRawClassOrInterfaceT(o)
1529:                                    .getName()))
1530:                                continue super MemberTypes;
1531:                        for (final Type r : result)
1532:                            if (t == r)
1533:                                continue super MemberTypes;
1534:                        result.add(t);
1535:                    }
1536:                }
1537:                return result;
1538:            }
1539:
1540:            public static List<Type> memberTypesOwn(final SymbolTable tab,
1541:                    final List<File> paths, final ClassOrInterfaceT base) {
1542:                if (base.isArray())
1543:                    return new ArrayList<Type>(0);
1544:                final Scope scope = tab.getScope(typeToScopeName(base));
1545:                final List<Type> result = new ArrayList<Type>();
1546:                for (final Iterator<String> i = scope.symbols(); i.hasNext();) {
1547:                    final String symbol = i.next();
1548:                    final Type member = (Type) scope.lookupLocally(symbol);
1549:                    if (isWrappedClassT(member) || isWrappedInterfaceT(member))
1550:                        result.add(member);
1551:                }
1552:                return result;
1553:            }
1554:
1555:            public static List<Type> memberTypesOwnAndInherited(
1556:                    final SymbolTable tab, final List<File> paths,
1557:                    final ClassOrInterfaceT base) {
1558:                final List<Type> result = new ArrayList<Type>();
1559:                result.addAll(memberTypesInherited(tab, paths, base));
1560:                result.addAll(memberTypesOwn(tab, paths, base));
1561:                return result;
1562:            }
1563:
1564:            /** All methods in the base type that are accessible, and whose formals accept the actuals
1565:             * after method invocation conversion (gosling_et_al_2000 <a
1566:             * href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#18427">&sect;15.12.2.1</a>). */
1567:            public static List<MethodT> methodsApplicableAndAccessible(
1568:                    final SymbolTable tab, final List<File> paths,
1569:                    final Type base, final boolean parents, final String name,
1570:                    final List<Type> actuals) {
1571:                final List<MethodT> methods = parents ? methodsOwnAndInherited(
1572:                        tab, paths, base) : methodsOwn(base);
1573:                final List<MethodT> result = new ArrayList<MethodT>();
1574:                for (final MethodT method : methods)
1575:                    if (isAccessibleIn(tab, paths, method, base))
1576:                        if (isApplicableMethod(tab, paths, method, name,
1577:                                actuals))
1578:                            result.add(method);
1579:                return result;
1580:            }
1581:
1582:            public static List<MethodT> methodsInherited(final SymbolTable tab,
1583:                    final List<File> paths, final Type base,
1584:                    final boolean includeOverridden) {
1585:                //gosling_et_al_2000 8.4.6
1586:                List<MethodT> result = new ArrayList<MethodT>();
1587:                final List<MethodT> methodsOwn = methodsOwn(base);
1588:                final String baseScope = typeToScopeName(base); //declaringScopeName(base);
1589:                assert null != baseScope || base.isArray();
1590:                final List<ClassOrInterfaceT> super Types = directSuperTypes(
1591:                        tab, paths, base);
1592:                for (final ClassOrInterfaceT super Type : super Types) {
1593:                    final List<MethodT> super Methods = methodsOwnAndInherited(
1594:                            tab, paths, super Type);
1595:                    super Methods: for (final MethodT m : super Methods) {
1596:                        resolveIfAliasMethod(tab, paths, m);
1597:                        if (hasModifier(m, "private"))
1598:                            continue super Methods;
1599:                        if (null != baseScope
1600:                                && !isAccessibleFromIn(tab, paths, baseScope,
1601:                                        m, super Type))
1602:                            continue super Methods;
1603:                        if (!includeOverridden)
1604:                            for (final MethodT o : methodsOwn) {
1605:                                resolveIfAliasMethod(tab, paths, o);
1606:                                if (sameMethodSignature(o, m))
1607:                                    continue super Methods;
1608:                            }
1609:                        boolean mustRemoveDuplicates = false;
1610:                        for (final MethodT r : result) {
1611:                            if (r == m)
1612:                                continue super Methods; //inherited from same interface by two different paths
1613:                            if (sameMethodSignature(m, r)) {
1614:                                assert hasModifier(m, "abstract")
1615:                                        || hasModifier(r, "abstract");
1616:                                if (hasModifier(m, "abstract")
1617:                                        && hasModifier(r, "abstract")) {
1618:                                    //TD 39 (8.4.6) report error if incompatible return types
1619:                                } else if (!hasModifier(m, "abstract")) {
1620:                                    mustRemoveDuplicates = true;
1621:                                } else if (!hasModifier(r, "abstract")) {
1622:                                    //TD 39 (8.4.6) report error if r is static
1623:                                    continue super Methods;
1624:                                }
1625:                            }
1626:                        }
1627:                        result.add(m);
1628:                        if (mustRemoveDuplicates) {
1629:                            //TD 39 (8.4.6) report error if m is static
1630:                            final List<MethodT> oldResult = result;
1631:                            result = new ArrayList<MethodT>();
1632:                            for (final MethodT r : oldResult)
1633:                                if (r == m || !sameMethodSignature(r, m))
1634:                                    result.add(r);
1635:                        }
1636:                    }
1637:                }
1638:                return result;
1639:            }
1640:
1641:            public static List<MethodT> methodsOwn(final Type base) {
1642:                final List<MethodT> result = new ArrayList<MethodT>();
1643:                if (!base.isArray()) //TD should methodsOwn() list of array type be non-empty?
1644:                    for (final Type m : resolveToRawClassOrInterfaceT(base)
1645:                            .getMethods())
1646:                        result.add(m.toMethod());
1647:                return result;
1648:            }
1649:
1650:            public static List<MethodT> methodsOwnAndInherited(
1651:                    final SymbolTable tab, final List<File> paths,
1652:                    final Type base) {
1653:                final List<MethodT> result = new ArrayList<MethodT>();
1654:                result.addAll(methodsInherited(tab, paths, base, false));
1655:                result.addAll(methodsOwn(base));
1656:                return result;
1657:            }
1658:
1659:            public static String methodSymbolFromAst(final GNode ast) {
1660:                final String name = ast.getString(3);
1661:                final String args = javaAstToString(ast.getGeneric(4));
1662:                /* In general, the arguments are unresolved, hence the scope name
1663:                 * is not canonical, hence it is useless for future lookup. That
1664:                 * is fine as long as we never look up methods or their scopes by
1665:                 * name. Instead, we should rely on the SCOPE attribute for that. */
1666:                return "method(" + name + ")" + args;
1667:            }
1668:
1669:            public static String methodSymbolFromConstructor(
1670:                    final Constructor method) {
1671:                final StringBuilder result = new StringBuilder();
1672:                result.append("method(<init>)");
1673:                methodSymbolHelper(result, method.getParameterTypes());
1674:                return result.toString();
1675:            }
1676:
1677:            public static String methodSymbolFromMethod(final Method method) {
1678:                final StringBuilder result = new StringBuilder();
1679:                result.append("method(").append(method.getName()).append(")");
1680:                methodSymbolHelper(result, method.getParameterTypes());
1681:                return result.toString();
1682:            }
1683:
1684:            private static void methodSymbolHelper(final StringBuilder b,
1685:                    final Class[] t) {
1686:                b.append('(');
1687:                for (int i = 0; i < t.length; i++) {
1688:                    if (0 < i)
1689:                        b.append(',');
1690:                    b.append(t[i].getName());
1691:                }
1692:                b.append(')');
1693:            }
1694:
1695:            public static String modifiersToString(final Type type) {
1696:                final StringBuilder result = new StringBuilder();
1697:                for (final Attribute att : type.attributes()) {
1698:                    if (0 < result.length())
1699:                        result.append(' ');
1700:                    result.append(modifierToName(att));
1701:                }
1702:                return result.toString();
1703:            }
1704:
1705:            public static String modifierToName(final Attribute modifier) {
1706:                return MODIFIER_TO_NAME.get(modifier);
1707:            }
1708:
1709:            private static List<MethodT> mostSpecificMethods(
1710:                    final SymbolTable tab, final List<File> paths,
1711:                    final List<MethodT> allMethods) {
1712:                final List<MethodT> result = new ArrayList<MethodT>();
1713:                outer: for (final MethodT mOuter : allMethods) {
1714:                    for (final MethodT mInner : allMethods)
1715:                        if (mOuter != mInner
1716:                                && isSuperMethod(tab, paths, mOuter, mInner))
1717:                            continue outer;
1718:                    result.add(mOuter);
1719:                }
1720:                return result;
1721:            }
1722:
1723:            public static Type nameToBaseType(final String name) {
1724:                return NAME_TO_BASETYPE.get(name);
1725:            }
1726:
1727:            public static Attribute nameToModifier(final String name) {
1728:                final Attribute result = NAME_TO_MODIFIER.get(name);
1729:                assert null != result;
1730:                return result;
1731:            }
1732:
1733:            public static MethodT newRawConstructor(final Type base,
1734:                    final List<Type> formals, final List<Type> exceptions) {
1735:                return new MethodT(
1736:                        constructorsReturnVoid() ? nameToBaseType("void")
1737:                                : base, typeToSimpleName(base), formals, false,
1738:                        exceptions);
1739:            }
1740:
1741:            public static Type notAValueIfClassOrInterface(final Type t) {
1742:                if (null == t)
1743:                    return t;
1744:                if (isWrappedClassT(t) || isWrappedInterfaceT(t)) {
1745:                    final Type result = new AnnotatedT(t);
1746:                    /* don't call t.attribute(), because that would pollute aliases of t */
1747:                    return result.attribute(Constants.ATT_NOT_A_VALUE);
1748:                }
1749:                return t;
1750:            }
1751:
1752:            public static PackageT packageDotPackage(final SymbolTable tab,
1753:                    final PackageT base, final String selector) {
1754:                final String tagName = SymbolTable.toTagName(selector);
1755:                final String scopeName = packageNameToScopeName(base.getName());
1756:                final String symbol = "."
1757:                        + Utilities.qualify(scopeName, tagName);
1758:                PackageT result = (PackageT) tab.lookup(symbol);
1759:                if (result == null) {
1760:                    result = new PackageT(Utilities.qualify(base.getName(),
1761:                            selector));
1762:                    SymbolTable.Scope scope = tab.lookupScope(symbol);
1763:                    if (scope == null) {
1764:                        final SymbolTable.Scope oldScope = tab.current();
1765:                        tab.setScope(tab.root());
1766:                        tab.enter(packageNameToScopeName(base.getName()));
1767:                        scope = tab.current();
1768:                        tab.setScope(oldScope);
1769:                    }
1770:                    scope.define(tagName, result);
1771:                }
1772:                return result;
1773:            }
1774:
1775:            public static Type packageDotPackageOrType(final SymbolTable tab,
1776:                    final List<File> paths, final PackageT base,
1777:                    final String selector) {
1778:                final Type t = packageDotType(tab, paths, base, selector);
1779:                return t != null ? t : packageDotPackage(tab, base, selector);
1780:            }
1781:
1782:            static ClassOrInterfaceT packageDotType(final SymbolTable tab,
1783:                    final List<File> paths, final PackageT base,
1784:                    final String selector) {
1785:                assert null != base;
1786:                final ClassOrInterfaceT t1 = packageDotType_existing(tab, base,
1787:                        selector);
1788:                if (null != t1)
1789:                    return t1;
1790:                final ClassOrInterfaceT t2 = packageDotType_external(tab,
1791:                        paths, base, selector);
1792:                if (null != t2)
1793:                    return t2;
1794:                return packageDotType_noSource(tab, base, selector);
1795:            }
1796:
1797:            private static ClassOrInterfaceT packageDotType_existing(
1798:                    final SymbolTable tab, final PackageT base,
1799:                    final String selector) {
1800:                final String tagName = SymbolTable.toTagName(selector);
1801:                final String baseScopeName = "."
1802:                        + packageNameToScopeName(base.getName());
1803:                final SymbolTable.Scope scope = tab.getScope(baseScopeName);
1804:                if (scope != null)
1805:                    for (final Iterator<String> i = scope.nested(); i.hasNext();) {
1806:                        final String symbol = baseScopeName + "." + i.next()
1807:                                + "." + tagName;
1808:                        final Type result = (Type) tab.lookup(symbol);
1809:                        if (result != null && !result.isAlias())
1810:                            return (ClassOrInterfaceT) result;
1811:                    }
1812:                return null;
1813:            }
1814:
1815:            private static ClassOrInterfaceT packageDotType_external(
1816:                    final SymbolTable tab, final List<File> paths,
1817:                    final PackageT base, final String selector) {
1818:                final String tagName = SymbolTable.toTagName(selector);
1819:                final String suffix = File.separatorChar
1820:                        + Utilities.toPath(base.getName()) + File.separatorChar
1821:                        + selector + ".java";
1822:                for (final File prefix : paths) {
1823:                    try {
1824:                        final File file = new File(prefix, suffix);
1825:                        final String path = file.getAbsolutePath();
1826:                        if (file.exists()) {
1827:                            final String scopedName = scopeName(base, path)
1828:                                    + "." + tagName;
1829:                            if (null == tab.lookupScope(scopedName)) {
1830:                                final String oldScope = enterScopeByQualifiedName(
1831:                                        tab, "");
1832:                                FileReader fileReader = null;
1833:                                try {
1834:                                    fileReader = new FileReader(file);
1835:                                    final UnicodeUnescaper unescaper = new UnicodeUnescaper(
1836:                                            fileReader);
1837:                                    final JavaParser parser = new JavaParser(
1838:                                            unescaper, path);
1839:                                    final Result parseResult = parser
1840:                                            .pCompilationUnit(0);
1841:                                    if (parseResult.hasValue()) {
1842:                                        final GNode ast = (GNode) parseResult
1843:                                                .semanticValue();
1844:                                        final GNode simple = (GNode) new JavaAstSimplifier()
1845:                                                .dispatch(ast);
1846:                                        new JavaExternalAnalyzer(new Runtime(),
1847:                                                tab).dispatch(simple);
1848:                                    }
1849:                                } finally {
1850:                                    if (null != fileReader)
1851:                                        fileReader.close();
1852:                                }
1853:                                enterScopeByQualifiedName(tab, oldScope);
1854:                            }
1855:                            final ClassOrInterfaceT result = (ClassOrInterfaceT) tab
1856:                                    .lookup(scopedName);
1857:                            if (result != null)
1858:                                return result;
1859:                        }
1860:                    } catch (final IOException e) {
1861:                        e.printStackTrace();
1862:                    }
1863:                }
1864:                return null;
1865:            }
1866:
1867:            static ClassOrInterfaceT packageDotType_noSource(
1868:                    final SymbolTable tab, final PackageT base,
1869:                    final String selector) {
1870:                final String scopedName = "."
1871:                        + packageNameToScopeName(base.getName()) + ".file()."
1872:                        + SymbolTable.toTagName(selector);
1873:                if (null == tab.lookup(scopedName)) {
1874:                    final Class clazz;
1875:                    try {
1876:                        clazz = Class.forName(base.getName() + "." + selector);
1877:                    } catch (final ClassNotFoundException e) {
1878:                        return null;
1879:                    }
1880:                    if (base.getName().equals(clazz.getPackage().getName())) {
1881:                        final String oldScope = enterScopeByQualifiedName(tab,
1882:                                "");
1883:                        tab.enter(packageNameToScopeName(base.getName()));
1884:                        tab.enter("file()");
1885:                        new JavaNoSourceAnalyzer(tab)
1886:                                .visitClassOrInterface(clazz);
1887:                        enterScopeByQualifiedName(tab, oldScope);
1888:                    }
1889:                }
1890:                return (ClassOrInterfaceT) tab.lookup(scopedName);
1891:            }
1892:
1893:            public static String packageNameToScopeName(
1894:                    final String canonicalName) {
1895:                return SymbolTable.toNameSpace(canonicalName, "package");
1896:            }
1897:
1898:            public static String qNameWithDollars(final SymbolTable tab,
1899:                    final ClassOrInterfaceT t) {
1900:                final String allDots = t.getQName();
1901:                if (null == tab)
1902:                    return allDots;
1903:                final String packageName = declaringPackage(tab, t).getName();
1904:                if (0 == packageName.length())
1905:                    return allDots;
1906:                assert allDots.startsWith(packageName);
1907:                final String afterPackage = allDots.substring(
1908:                        packageName.length() + 1).replace('.', '$');
1909:                final String result = packageName + "." + afterPackage;
1910:                return result;
1911:            }
1912:
1913:            public static List<ClassOrInterfaceT> qualifiedAliasesToTypes(
1914:                    final SymbolTable tab, final List<File> paths,
1915:                    final String scope, final List<AliasT> aliases) {
1916:                final List<ClassOrInterfaceT> result = new ArrayList<ClassOrInterfaceT>(
1917:                        aliases.size());
1918:                for (final AliasT a : aliases) {
1919:                    final ClassOrInterfaceT resolved = JavaEntities
1920:                            .qualifiedAliasToType(tab, paths, scope, a);
1921:                    if (null != resolved)
1922:                        result.add(resolved);
1923:                }
1924:                return result;
1925:            }
1926:
1927:            public static ClassOrInterfaceT qualifiedAliasToType(
1928:                    final SymbolTable tab, final List<File> paths,
1929:                    final String scope, final AliasT alias) {
1930:                if (alias.getType() == null)
1931:                    alias.setType(qualifiedNameToType(tab, paths, scope, alias
1932:                            .getName()));
1933:                return (ClassOrInterfaceT) alias.getType();
1934:            }
1935:
1936:            public static Type qualifiedNameToPackageOrType(
1937:                    final SymbolTable tab, final List<File> paths,
1938:                    final String scope, final String name) {
1939:                final Type t = qualifiedNameToType(tab, paths, scope, name);
1940:                return t != null ? t : canonicalNameToPackage(tab, name);
1941:            }
1942:
1943:            public static ClassOrInterfaceT qualifiedNameToType(
1944:                    final SymbolTable tab, final List<File> paths,
1945:                    final String scope, final String name) {
1946:                if (name.indexOf('.') == -1)
1947:                    return simpleNameToType(tab, paths, scope, name);
1948:                final String qualifier = Utilities.getQualifier(name);
1949:                final String selector = Utilities.unqualify(name);
1950:                final Type base = qualifiedNameToPackageOrType(tab, paths,
1951:                        scope, qualifier);
1952:                if (base.isPackage())
1953:                    return packageDotType(tab, paths, base.toPackage(),
1954:                            selector);
1955:                return typeDotType(tab, paths, (ClassOrInterfaceT) base, true,
1956:                        selector);
1957:            }
1958:
1959:            public static Type resolveIfAlias(final SymbolTable tab,
1960:                    final List<File> paths, final String scope,
1961:                    final Type typeThatMayBeAlias) {
1962:                assert null != scope;
1963:                if (null == typeThatMayBeAlias)
1964:                    return null;
1965:                if (isGeneralLValueT(typeThatMayBeAlias)) {
1966:                    final Type t = dereference(typeThatMayBeAlias);
1967:                    resolveIfAlias(tab, paths, scope, t);
1968:                    return typeThatMayBeAlias;
1969:                }
1970:                if (typeThatMayBeAlias.isAnnotated()) {
1971:                    final Type t = ((AnnotatedT) typeThatMayBeAlias).getType();
1972:                    resolveIfAlias(tab, paths, scope, t);
1973:                    return typeThatMayBeAlias;
1974:                }
1975:                if (typeThatMayBeAlias.isArray()) {
1976:                    final Type t = arrayElementType(typeThatMayBeAlias
1977:                            .toArray());
1978:                    resolveIfAlias(tab, paths, scope, t);
1979:                    return typeThatMayBeAlias;
1980:                }
1981:                if (typeThatMayBeAlias.isAlias())
1982:                    return qualifiedAliasToType(tab, paths, scope,
1983:                            typeThatMayBeAlias.toAlias());
1984:                return typeThatMayBeAlias;
1985:            }
1986:
1987:            public static MethodT resolveIfAliasMethod(final SymbolTable tab,
1988:                    final List<File> paths, final MethodT method) {
1989:                final String scope = declaringScopeName(method);
1990:                assert null != scope;
1991:                resolveIfAlias(tab, paths, scope, declaringType(tab, method));
1992:                resolveIfAlias(tab, paths, scope, method.getResult());
1993:                for (final Type p : method.getParameters())
1994:                    resolveIfAlias(tab, paths, scope, p);
1995:                for (final Type e : method.getExceptions())
1996:                    resolveIfAlias(tab, paths, scope, e);
1997:                return method;
1998:            }
1999:
2000:            static ClassOrInterfaceT resolveToRawClassOrInterfaceT(final Type t) {
2001:                return (ClassOrInterfaceT) resolveToRawRValue(t);
2002:            }
2003:
2004:            public static WrappedT resolveToRawLValue(final Type t) {
2005:                assert isGeneralLValueT(t);
2006:                final boolean a = t.isAnnotated();
2007:                final WrappedT r = (WrappedT) (a ? ((AnnotatedT) t).getType()
2008:                        : t);
2009:                assert isLValueT(r) || isLocalT(r) || isFieldT(r)
2010:                        || isParameterT(r);
2011:                return r;
2012:            }
2013:
2014:            public static Type resolveToRawRValue(final Type t) {
2015:                assert isGeneralRValueT(t);
2016:                Type result = t;
2017:                if (!isNullT(result))
2018:                    while (true) {
2019:                        if (result.isAlias())
2020:                            result = ((AliasT) result).getType();
2021:                        else if (result.isAnnotated())
2022:                            result = ((AnnotatedT) result).getType();
2023:                        else if (isConstantT(result))
2024:                            result = ((AnnotatedT) result).getType();
2025:                        else
2026:                            break;
2027:                    }
2028:                assert isNullT(result) || isPrimitiveT(result)
2029:                        || result.isArray() || result.isClass()
2030:                        || result.isInterface();
2031:                return result;
2032:            }
2033:
2034:            public static Type resolveToRValue(final Type t0) {
2035:                assert isGeneralRValueT(t0);
2036:                final Type t1 = isConstantT(t0) ? ((AnnotatedT) t0).getType()
2037:                        : t0;
2038:                final Type t2 = t1.isAlias() ? ((AliasT) t1).getType() : t1;
2039:                assert isPrimitiveT(t2) || t2.isArray() || t2.isClass()
2040:                        || t2.isInterface();
2041:                return t2;
2042:            }
2043:
2044:            public static Type resolveToValue(final AnnotatedT notAValue) {
2045:                assert isNotAValueT(notAValue);
2046:                Type result = notAValue.getType();
2047:                for (final Attribute a : notAValue.attributes()) {
2048:                    if (!a.equals(Constants.ATT_NOT_A_VALUE))
2049:                        result = result.attribute(a);
2050:                }
2051:                if (notAValue.hasScope(false))
2052:                    result.scope(notAValue.getScope());
2053:                return result;
2054:            }
2055:
2056:            public static boolean runtimeAssrt(final Runtime runtime,
2057:                    final Node n, final boolean cond, final String msgFormat,
2058:                    final Object... msgArgs) {
2059:                if (!cond) {
2060:                    final Formatter message = new Formatter();
2061:                    message.format(msgFormat, msgArgs);
2062:                    runtime.error(message.toString(), n);
2063:                }
2064:                return cond;
2065:            }
2066:
2067:            public static boolean sameMethodReturnType(final MethodT m1,
2068:                    final MethodT m2) {
2069:                final Type r1 = m1.getResult(), r2 = m2.getResult();
2070:                if (r1.isVoid() || r2.isVoid())
2071:                    return r1.isVoid() && r2.isVoid();
2072:                return JavaTypeConverter.isIdentical(r1, r2);
2073:            }
2074:
2075:            public static boolean sameMethodSignature(final MethodT m1,
2076:                    final MethodT m2) {
2077:                if (!m1.getName().equals(m2.getName()))
2078:                    return false;
2079:                final List<Type> params1 = m1.getParameters(), params2 = m2
2080:                        .getParameters();
2081:                if (params1.size() != params2.size())
2082:                    return false;
2083:                final Iterator<Type> i1 = params1.iterator(), i2 = params2
2084:                        .iterator();
2085:                while (i1.hasNext()) {
2086:                    final Type t1 = i1.next(), t2 = i2.next();
2087:                    assert isParameterT(t1) && isParameterT(t2);
2088:                    final Type r1 = dereference(t1), r2 = dereference(t2);
2089:                    if (!JavaTypeConverter.isIdentical(r1, r2))
2090:                        return false;
2091:                }
2092:                return true;
2093:            }
2094:
2095:            static String scopeName(final PackageT packageT,
2096:                    final String fileName) {
2097:                return "." + packageNameToScopeName(packageT.getName()) + "."
2098:                        + fileNameToScopeName(fileName);
2099:            }
2100:
2101:            public static GNode scrubLocations(final GNode result) {
2102:                new MiniVisitor_scrubLocations().dispatch(result);
2103:                return result;
2104:            }
2105:
2106:            public static Type simpleNameToExpression(final SymbolTable tab,
2107:                    final List<File> paths, final String scope,
2108:                    final String name) {
2109:                final String oldScope = enterScopeByQualifiedName(tab, scope);
2110:                final Type result = (Type) tab.lookup(name);
2111:                resolveIfAlias(tab, paths, scope, result);
2112:                final boolean found = null != result
2113:                        && isGeneralLValueT(result);
2114:                if (found) {
2115:                    final Type rValue = dereference(result);
2116:                    resolveIfAlias(tab, paths,
2117:                            typeToScopeName(currentType(tab)), rValue);
2118:                }
2119:                enterScopeByQualifiedName(tab, oldScope);
2120:                if (!found && isScopeNested(tab.current().getQualifiedName()))
2121:                    return typeDotField(tab, paths, currentType(tab), true,
2122:                            name);
2123:                return result;
2124:            }
2125:
2126:            public static PackageT simpleNameToPackage(final SymbolTable tab,
2127:                    final String name) {
2128:                final String tagName = SymbolTable.toTagName(name);
2129:                final String toplevelScopeDotSymbol = "." + tagName;
2130:                PackageT result = (PackageT) tab.lookup(toplevelScopeDotSymbol);
2131:                if (result == null) {
2132:                    result = new PackageT(name);
2133:                    tab.lookupScope(toplevelScopeDotSymbol).define(tagName,
2134:                            result);
2135:                }
2136:                return result;
2137:            }
2138:
2139:            public static Type simpleNameToPackageOrType(final SymbolTable tab,
2140:                    final List<File> paths, final String scope,
2141:                    final String name) {
2142:                final Type t = simpleNameToType(tab, paths, scope, name);
2143:                return t != null ? t : simpleNameToPackage(tab, name);
2144:            }
2145:
2146:            public static Type simpleNameToPackageOrTypeOrExpression(
2147:                    final SymbolTable tab, final List<File> paths,
2148:                    final String scope, final String name) {
2149:                final Type e = simpleNameToExpression(tab, paths, scope, name);
2150:                return e != null ? e : simpleNameToPackageOrType(tab, paths,
2151:                        scope, name);
2152:            }
2153:
2154:            public static ClassOrInterfaceT simpleNameToType(
2155:                    final SymbolTable tab, final List<File> paths,
2156:                    final String scope, final String name) {
2157:                final String oldScope = enterScopeByQualifiedName(tab, scope);
2158:                ClassOrInterfaceT result = null;
2159:                { // find as local class, member class, single-import, or top-level class
2160:                    final Type t = (Type) tab.lookup(SymbolTable
2161:                            .toTagName(name));
2162:                    if (null != t && !t.isPackage())
2163:                        result = t.isAlias() ? lookupImport(tab, paths, t
2164:                                .toAlias()) : (ClassOrInterfaceT) t;
2165:                }
2166:                if (null == result && isScopeNested(scope))
2167:                    result = typeDotType(tab, paths, currentType(tab), true,
2168:                            name);
2169:                if (null == result)
2170:                    // find in other compilation unit of current package
2171:                    result = packageDotType(tab, paths, currentPackage(tab),
2172:                            name);
2173:                if (null == result) {
2174:                    final List<Type> imports = currentImports(tab);
2175:                    if (null != imports)
2176:                        // find in import-on-demand
2177:                        for (final Type i : imports) {
2178:                            result = packageDotType(tab, paths, (PackageT) i,
2179:                                    name);
2180:                            if (null != result)
2181:                                break;
2182:                        }
2183:                }
2184:                if (null == result)
2185:                    result = packageDotType(tab, paths, canonicalNameToPackage(
2186:                            tab, "java.lang"), name);
2187:                enterScopeByQualifiedName(tab, oldScope);
2188:                if (null == result)
2189:                    return null;
2190:                return result;
2191:            }
2192:
2193:            @SuppressWarnings("unchecked")
2194:            public static Set<String> stringSet(final Object s) {
2195:                return (Set<String>) s;
2196:            }
2197:
2198:            public static ClassT tClass(final SymbolTable tab) {
2199:                return tForName(tab, "java.lang.Class").toClass();
2200:            }
2201:
2202:            public static InterfaceT tCloneable(final SymbolTable tab) {
2203:                return tForName(tab, "java.lang.Cloneable").toInterface();
2204:            }
2205:
2206:            public static ClassT tError(final SymbolTable tab) {
2207:                return tForName(tab, "java.lang.Error").toClass();
2208:            }
2209:
2210:            private static ClassOrInterfaceT tForName(final SymbolTable tab,
2211:                    final String name) {
2212:                final List<File> paths = new ArrayList<File>();
2213:                return canonicalNameToType(tab, paths, name, false);
2214:            }
2215:
2216:            public static ClassT tObject(final SymbolTable tab) {
2217:                return tForName(tab, "java.lang.Object").toClass();
2218:            }
2219:
2220:            public static AliasT tObjectAlias(final SymbolTable tab) {
2221:                return new AliasT("java.lang.Object", tObject(tab));
2222:            }
2223:
2224:            public static ClassT tRuntimeException(final SymbolTable tab) {
2225:                return tForName(tab, "java.lang.RuntimeException").toClass();
2226:            }
2227:
2228:            public static InterfaceT tSerializable(final SymbolTable tab) {
2229:                return tForName(tab, "java.io.Serializable").toInterface();
2230:            }
2231:
2232:            public static ClassT tString(final SymbolTable tab) {
2233:                return tForName(tab, "java.lang.String").toClass();
2234:            }
2235:
2236:            public static ClassT tThrowable(final SymbolTable tab) {
2237:                return tForName(tab, "java.lang.Throwable").toClass();
2238:            }
2239:
2240:            public static String typeDeclString(final SymbolTable tab,
2241:                    final Object obj) {
2242:                assert obj instanceof  Type || obj instanceof  List;
2243:                if (obj instanceof  Type)
2244:                    return typeToString(tab, true, (Type) obj);
2245:                final StringBuilder result = new StringBuilder();
2246:                for (final Type t : typeList((List) obj))
2247:                    result.append(typeToString(tab, true, t)).append(';');
2248:                return result.toString();
2249:            }
2250:
2251:            public static VariableT typeDotField(final SymbolTable tab,
2252:                    final List<File> paths, final Type base,
2253:                    final boolean parents, final String name) {
2254:                final List<VariableT> all = fieldsApplicableAndAccessible(tab,
2255:                        paths, base, parents, name);
2256:                if (1 == all.size())
2257:                    return all.get(0);
2258:                return null;
2259:            }
2260:
2261:            public static MethodT typeDotMethod(final SymbolTable tab,
2262:                    final List<File> paths, final Type baseT,
2263:                    final boolean parents, final String selector,
2264:                    final List<Type> actuals) {
2265:                final List<MethodT> all = methodsApplicableAndAccessible(tab,
2266:                        paths, baseT, parents, selector, actuals);
2267:                // chose the most specific method: see gosling_et_al_2000 Section 15.12.2.2.
2268:                final List<MethodT> specific = mostSpecificMethods(tab, paths,
2269:                        all);
2270:                final MethodT result;
2271:                if (specific.size() == 1) {
2272:                    result = specific.get(0);
2273:                } else {
2274:                    int nonAbstract = 0;
2275:                    MethodT any = null;
2276:                    for (final MethodT m : specific) {
2277:                        if (any == null)
2278:                            any = m;
2279:                        assert sameMethodSignature(m, any);
2280:                        if (!hasModifier(m, "abstract")) {
2281:                            any = m;
2282:                            nonAbstract++;
2283:                        }
2284:                    }
2285:                    assert nonAbstract <= 1;
2286:                    result = any;
2287:                }
2288:                if (null == result)
2289:                    return null;
2290:                resolveIfAlias(tab, paths, typeToScopeName(baseT), result
2291:                        .getResult());
2292:                return result;
2293:            }
2294:
2295:            public static ClassOrInterfaceT typeDotType(final SymbolTable tab,
2296:                    final List<File> paths, final ClassOrInterfaceT base,
2297:                    final boolean parents, final String selector) {
2298:                if (recursiveTypeDotType)
2299:                    return null;
2300:                recursiveTypeDotType = true;
2301:                final List<Type> all = memberTypesApplicableAndAccessible(tab,
2302:                        paths, base, parents, selector);
2303:                recursiveTypeDotType = false;
2304:                if (1 == all.size())
2305:                    return (ClassOrInterfaceT) all.get(0);
2306:                return null;
2307:            }
2308:
2309:            public static Type typeDotTypeOrField(final SymbolTable tab,
2310:                    final List<File> paths, final Type base,
2311:                    final boolean parents, final String selector) {
2312:                assert isWrappedClassT(base) || isWrappedInterfaceT(base)
2313:                        || base.isArray();
2314:                if (parents) {
2315:                    for (final Iterator<Type> i = new SuperTypesIter(tab,
2316:                            paths, base); i.hasNext();) {
2317:                        final Type member = typeDotTypeOrField(tab, paths, i
2318:                                .next(), false, selector);
2319:                        if (null != member)
2320:                            return member;
2321:                    }
2322:                    return null;
2323:                }
2324:                final VariableT field = typeDotField(tab, paths, base, false,
2325:                        selector);
2326:                if (null != field)
2327:                    return field;
2328:                return typeDotType(tab, paths, (ClassOrInterfaceT) base, false,
2329:                        selector);
2330:            }
2331:
2332:            @SuppressWarnings("unchecked")
2333:            public static List<Type> typeList(final List list) {
2334:                return list;
2335:            }
2336:
2337:            /** A descriptor is a JVM-internal string representation of a type of a field or method, see JVM
2338:             * specification <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#1169">&sect;4.3</a>. */
2339:            public static String typeToDescriptor(final SymbolTable tab,
2340:                    final Type type) {
2341:                if (isConstantT(type))
2342:                    return typeToDescriptor(tab, type.toAnnotated().getType());
2343:                if (type.isBoolean())
2344:                    return "Z";
2345:                if (type.isNumber()) {
2346:                    switch (((NumberT) type).getKind()) {
2347:                    case BYTE:
2348:                        return "B";
2349:                    case CHAR:
2350:                        return "C";
2351:                    case DOUBLE:
2352:                        return "D";
2353:                    case FLOAT:
2354:                        return "F";
2355:                    case INT:
2356:                        return "I";
2357:                    case LONG:
2358:                        return "J";
2359:                    case SHORT:
2360:                        return "S";
2361:                    }
2362:                }
2363:                if (type.isVoid())
2364:                    return "V";
2365:                if (type.isArray())
2366:                    return "["
2367:                            + typeToDescriptor(tab, arrayElementType(type
2368:                                    .toArray()));
2369:                if (isWrappedClassT(type) || isWrappedInterfaceT(type))
2370:                    return "L"
2371:                            + qNameWithDollars(tab,
2372:                                    resolveToRawClassOrInterfaceT(type))
2373:                                    .replace('.', '/') + ";";
2374:                if (type.isMethod()) {
2375:                    final StringBuilder b = new StringBuilder();
2376:                    b.append('(');
2377:                    for (final Type param : type.toMethod().getParameters())
2378:                        b.append(typeToDescriptor(tab, dereference(param)));
2379:                    b.append(')').append(
2380:                            typeToDescriptor(tab, type.toMethod().getResult()));
2381:                    return b.toString();
2382:                }
2383:                throw new Error();
2384:            }
2385:
2386:            static String typeToScopeName(final Type type) {
2387:                if (null == type || type.isArray())
2388:                    return "";
2389:                final String result = type.getScope();
2390:                assert null != result;
2391:                return result;
2392:            }
2393:
2394:            public static String typeToSimpleName(final Type type) {
2395:                if (type.isAlias())
2396:                    return Utilities.unqualify(type.toAlias().getName());
2397:                if (isWrappedClassT(type) || isWrappedInterfaceT(type))
2398:                    return resolveToRawClassOrInterfaceT(type).getName();
2399:                assert type.isMethod();
2400:                return type.toMethod().getName();
2401:            }
2402:
2403:            public static String typeToString(final SymbolTable tab,
2404:                    final boolean showDetails, final Type type) {
2405:                final CharArrayWriter writer = new CharArrayWriter();
2406:                final Printer printer = new Printer(writer);
2407:                final TypePrinter typePrinter = new JavaTypePrinter(tab,
2408:                        showDetails, printer);
2409:                typePrinter.dispatch(type);
2410:                printer.flush();
2411:                return writer.toString();
2412:            }
2413:
2414:            public static Type typeWithDimensions(final Type componentT,
2415:                    final int dim) {
2416:                if (dim == 0)
2417:                    return componentT;
2418:                final Type rec = typeWithDimensions(componentT, dim - 1);
2419:                // FIXME: plugged in faux reference with faux type.
2420:                final Type rec2 = rec.annotate().shape(
2421:                        new DynamicReference(NumberT.INT));
2422:                return new ArrayT(rec2, true);
2423:            }
2424:
2425:            public static String unicodeUnescape(final String in) {
2426:                if (!in.contains("\\u"))
2427:                    return in;
2428:                final UnicodeUnescaper uu = new UnicodeUnescaper(
2429:                        new StringReader(in));
2430:                final StringBuilder result = new StringBuilder(in.length());
2431:                try {
2432:                    while (true) {
2433:                        final int c = uu.read();
2434:                        if (-1 == c)
2435:                            break;
2436:                        result.append((char) c);
2437:                    }
2438:                } catch (final IOException e) {
2439:                    throw new Error("internal error", e);
2440:                }
2441:                return result.toString();
2442:            }
2443:
2444:            public static boolean zeroLiteral(final String s) {
2445:                for (int i = 0; i < s.length(); i++) {
2446:                    final char c = s.charAt(i);
2447:                    if ('1' <= c && c <= '9')
2448:                        return false;
2449:                    if ('d' == c || 'D' == c || 'e' == c || 'E' == c
2450:                            || 'f' == c || 'F' == c)
2451:                        return true;
2452:                }
2453:                return true;
2454:            }
2455:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.