Source Code Cross Referenced for JavaExternalAnalyzer.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) 


001:        /*
002:         * xtc - The eXTensible Compiler
003:         * Copyright (C) 2006-2007 IBM Corp.
004:         *
005:         * This program is free software; you can redistribute it and/or
006:         * modify it under the terms of the GNU General Public License
007:         * version 2 as published by the Free Software Foundation.
008:         *
009:         * This program is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012:         * GNU General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU General Public License
015:         * along with this program; if not, write to the Free Software
016:         * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017:         * USA.
018:         */
019:        package xtc.lang;
020:
021:        import java.util.ArrayList;
022:        import java.util.Iterator;
023:        import java.util.List;
024:
025:        import xtc.Constants;
026:        import xtc.tree.Attribute;
027:        import xtc.tree.GNode;
028:        import xtc.tree.Node;
029:        import xtc.tree.Visitor;
030:        import xtc.type.AliasT;
031:        import xtc.type.ClassOrInterfaceT;
032:        import xtc.type.ClassT;
033:        import xtc.type.InterfaceT;
034:        import xtc.type.Language;
035:        import xtc.type.MethodT;
036:        import xtc.type.PackageT;
037:        import xtc.type.Type;
038:        import xtc.type.VariableT;
039:        import xtc.util.Runtime;
040:        import xtc.util.SymbolTable;
041:        import xtc.util.Utilities;
042:
043:        /**
044:         * A visitor that constructs externally visible types and fills the symbol table
045:         * for a Java file. Does not descend into method bodies, just finds the class,
046:         * interface, method, and field signatures. Used in conjunction with
047:         * JavaAnalyzer. Let F be the file currently analyzed by the JavaAnalyzer; then
048:         * the JavaExternalAnalyzer is used on (i) classes defined in F, and (ii)
049:         * compilation units that define classes whose name gets used in F. Packages,
050:         * classes, and interfaces go into namespace "tag(..)", methods go into
051:         * namespace "method(..)", and fields go into the default namespace. The scopes
052:         * associated with packages and types do not have the namespace in their name,
053:         * only the symbols do. For example, scope "java" contains scope "lang", but
054:         * scope "java" maps symbol "tag(lang)" to an instance of PackageT. Declared
055:         * types are represented by instances of ClassT or InterfaceT, whereas names
056:         * used, for example, as method return types are represented by instances of
057:         * AliasT.
058:         * 
059:         * @author Martin Hirzel
060:         * @version $Revision: 1.71 $
061:         */
062:        public class JavaExternalAnalyzer extends Visitor {
063:            protected static List<Attribute> MODIFIERS_CLASS = new ArrayList<Attribute>();
064:
065:            protected static List<Attribute> MODIFIERS_CONSTRUCTOR = new ArrayList<Attribute>();
066:
067:            protected static List<Attribute> MODIFIERS_FIELD = new ArrayList<Attribute>();
068:
069:            protected static List<Attribute> MODIFIERS_INTERFACE = new ArrayList<Attribute>();
070:
071:            protected static List<Attribute> MODIFIERS_INTERFACE_FIELD = new ArrayList<Attribute>();
072:
073:            protected static List<Attribute> MODIFIERS_INTERFACE_MEMBERTYPE = new ArrayList<Attribute>();
074:
075:            protected static List<Attribute> MODIFIERS_INTERFACE_METHOD = new ArrayList<Attribute>();
076:
077:            protected static List<Attribute> MODIFIERS_METHOD = new ArrayList<Attribute>();
078:
079:            static {
080:                // gosling_et_al_2000 8.1.1
081:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("public"));
082:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("protected"));
083:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("private"));
084:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("abstract"));
085:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("static"));
086:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("final"));
087:                MODIFIERS_CLASS.add(JavaEntities.nameToModifier("strictfp"));
088:                // gosling_et_al_2000 8.3.1
089:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("public"));
090:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("protected"));
091:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("private"));
092:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("static"));
093:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("final"));
094:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("transient"));
095:                MODIFIERS_FIELD.add(JavaEntities.nameToModifier("volatile"));
096:                // gosling_et_al_2000 8.8
097:                MODIFIERS_CONSTRUCTOR
098:                        .add(JavaEntities.nameToModifier("public"));
099:                MODIFIERS_CONSTRUCTOR.add(JavaEntities
100:                        .nameToModifier("protected"));
101:                MODIFIERS_CONSTRUCTOR.add(JavaEntities
102:                        .nameToModifier("private"));
103:                // gosling_et_al_2000 9.1.1
104:                MODIFIERS_INTERFACE.add(JavaEntities.nameToModifier("public"));
105:                MODIFIERS_INTERFACE.add(JavaEntities
106:                        .nameToModifier("protected"));
107:                MODIFIERS_INTERFACE.add(JavaEntities.nameToModifier("private"));
108:                MODIFIERS_INTERFACE
109:                        .add(JavaEntities.nameToModifier("abstract"));
110:                MODIFIERS_INTERFACE.add(JavaEntities.nameToModifier("static"));
111:                MODIFIERS_INTERFACE
112:                        .add(JavaEntities.nameToModifier("strictfp"));
113:                // gosling_et_al_2000 9.5
114:                MODIFIERS_INTERFACE_FIELD.add(JavaEntities
115:                        .nameToModifier("public"));
116:                MODIFIERS_INTERFACE_FIELD.add(JavaEntities
117:                        .nameToModifier("static"));
118:                MODIFIERS_INTERFACE_FIELD.add(JavaEntities
119:                        .nameToModifier("final"));
120:                // gosling_et_al_2000 9.5
121:                MODIFIERS_INTERFACE_MEMBERTYPE.add(JavaEntities
122:                        .nameToModifier("static"));
123:                MODIFIERS_INTERFACE_MEMBERTYPE.add(JavaEntities
124:                        .nameToModifier("public"));
125:                // gosling_et_al_2000 9.4
126:                MODIFIERS_INTERFACE_METHOD.add(JavaEntities
127:                        .nameToModifier("public"));
128:                MODIFIERS_INTERFACE_METHOD.add(JavaEntities
129:                        .nameToModifier("abstract"));
130:                // gosling_et_al_2000 8.4.3
131:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("public"));
132:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("protected"));
133:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("private"));
134:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("abstract"));
135:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("static"));
136:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("final"));
137:                MODIFIERS_METHOD.add(JavaEntities
138:                        .nameToModifier("synchronized"));
139:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("native"));
140:                MODIFIERS_METHOD.add(JavaEntities.nameToModifier("strictfp"));
141:            }
142:
143:            protected static void addModifier(final List<Attribute> modifiers,
144:                    final String name) {
145:                if (!hasModifier(modifiers, name))
146:                    modifiers.add(JavaEntities.nameToModifier(name));
147:            }
148:
149:            protected static void addModifiers(final List<Attribute> modifiers,
150:                    final List<Attribute> toAdd) {
151:                for (final Attribute attribute : toAdd)
152:                    if (!modifiers.contains(attribute))
153:                        modifiers.add(attribute);
154:            }
155:
156:            public static int countDimensions(final GNode dimNode) {
157:                return null == dimNode ? 0 : dimNode.size();
158:            }
159:
160:            protected static boolean hasModifier(
161:                    final List<Attribute> modifiers, final String modifier) {
162:                return modifiers
163:                        .contains(JavaEntities.nameToModifier(modifier));
164:            }
165:
166:            protected final Runtime _runtime;
167:
168:            public final SymbolTable _table;
169:
170:            public JavaExternalAnalyzer(final Runtime runtime,
171:                    final SymbolTable table) {
172:                _runtime = runtime;
173:                _table = table;
174:            }
175:
176:            /** Use this for asserting that the input is typed correctly. */
177:            protected boolean assrt(final GNode n, final boolean cond,
178:                    final String msgFormat, final Object... msgArgs) {
179:                return JavaEntities.runtimeAssrt(_runtime, n, cond, msgFormat,
180:                        msgArgs);
181:            }
182:
183:            protected void assrtDiffersFromEnclosing(final GNode n,
184:                    final String canonicalName) {
185:                final String simpleName = Utilities.getName(canonicalName);
186:                final String packageName = JavaEntities.currentPackage(_table)
187:                        .getName();
188:                final String nameWithoutPackage = 0 == packageName.length() ? canonicalName
189:                        : canonicalName.substring(packageName.length() + 1);
190:                final String middleName = Utilities
191:                        .getQualifier(nameWithoutPackage);
192:                if (null != middleName) {
193:                    final String[] c = Utilities.toComponents(middleName);
194:                    for (int i = 0; i < c.length; i++)
195:                        assrt(n, !c[i].equals(simpleName),
196:                                "name must not match enclosing type");
197:                }
198:            }
199:
200:            protected void assrtLegalModifiers(final GNode n,
201:                    final List<Attribute> expected,
202:                    final List<Attribute> actual, final String context) {
203:                final boolean pri = hasModifier(actual, "private");
204:                final boolean pro = hasModifier(actual, "protected");
205:                final boolean pub = hasModifier(actual, "public");
206:                assrt(n, !(pri && pro),
207:                        "conflicting modifiers private and protected");
208:                assrt(n, !(pri && pub),
209:                        "conflicting modifiers private and public");
210:                assrt(n, !(pro && pub),
211:                        "conflicting modifiers protected and public");
212:                for (final Attribute m : actual)
213:                    assrt(n, expected.contains(m), "illegal %s modifier %s",
214:                            context, m);
215:                final boolean fin = hasModifier(actual, "final");
216:                final boolean vol = hasModifier(actual, "volatile");
217:                assrt(n, !(fin && vol),
218:                        "conflicting modifiers final and volatile");
219:            }
220:
221:            protected final String currentScopeName() {
222:                return _table.current().getQualifiedName();
223:            }
224:
225:            protected final Type declareDefaultConstructorIfNecessary() {
226:                // gosling_et_al_2000 8.8.7 default constructor
227:                final Type wrappedBase = JavaEntities.currentType(_table);
228:                final ClassOrInterfaceT base = JavaEntities
229:                        .resolveToRawClassOrInterfaceT(wrappedBase);
230:                for (final Type i : base.getMethods())
231:                    if (JavaEntities.isConstructor(base, i.toMethod()))
232:                        return null;
233:                final MethodT result = JavaEntities.newRawConstructor(base,
234:                        new ArrayList<Type>(), new ArrayList<Type>());
235:                final List<Attribute> modifiers = new ArrayList<Attribute>();
236:                if (JavaEntities.hasModifier(wrappedBase, "private"))
237:                    modifiers.add(JavaEntities.nameToModifier("private"));
238:                else if (JavaEntities.hasModifier(wrappedBase, "protected"))
239:                    modifiers.add(JavaEntities.nameToModifier("protected"));
240:                else if (JavaEntities.hasModifier(wrappedBase, "public"))
241:                    modifiers.add(JavaEntities.nameToModifier("public"));
242:                for (final Attribute mod : modifiers)
243:                    result.addAttribute(mod);
244:                final String symbol = "method(<init>)()";
245:                _table.current().define(symbol, result);
246:                _table.enter(symbol);
247:                result.scope(_table.current().getQualifiedName());
248:                _table.exit();
249:                assert JavaEntities.isConstructor(base, result);
250:                JavaEntities.currentType(_table).getMethods().add(result);
251:                return result;
252:            }
253:
254:            protected final List<Type> makeList(final GNode n) {
255:                final List<Type> result = new ArrayList<Type>(n.size());
256:                for (final Object o : n)
257:                    result.add((Type) dispatch((Node) o));
258:                return result;
259:            }
260:
261:            protected final boolean memberOfInterface() {
262:                if (!JavaEntities.isScopeForMember(currentScopeName()))
263:                    return false;
264:                final Type t = JavaEntities.currentType(_table);
265:                return null != t && JavaEntities.isWrappedInterfaceT(t);
266:            }
267:
268:            public final List<Type> processDeclarators(
269:                    final List<Attribute> modifiers, final Type type,
270:                    final GNode declarators) {
271:                assert JavaEntities.isRValueT(type);
272:                final List<Type> result = new ArrayList<Type>();
273:                final boolean isLocal = JavaEntities
274:                        .isScopeLocal(currentScopeName());
275:                for (final Object i : declarators) {
276:                    final GNode declNode = (GNode) i;
277:                    final String name = declNode.getString(0);
278:                    final Type dimType = JavaEntities.typeWithDimensions(type,
279:                            countDimensions(declNode.getGeneric(1)));
280:                    final Type entity = isLocal ? VariableT.newLocal(dimType,
281:                            name) : VariableT.newField(dimType, name);
282:                    for (final Attribute mod : modifiers)
283:                        entity.addAttribute(mod);
284:                    entity.language(Language.JAVA);
285:                    assert isLocal ? JavaEntities.isLocalT(entity)
286:                            : JavaEntities.isFieldT(entity);
287:                    if (null == _table.current().lookupLocally(name)) {
288:                        result.add(entity);
289:                        _table.current().define(name, entity);
290:                        entity.scope(_table.current().getQualifiedName());
291:                        if (!isLocal)
292:                            JavaEntities.currentType(_table).getFields().add(
293:                                    entity);
294:                    } else {
295:                        if (isLocal)
296:                            _runtime.error("duplicate variable declaration "
297:                                    + name, declNode);
298:                        else
299:                            _runtime.error("duplicate field declaration "
300:                                    + name, declNode);
301:                    }
302:                    declNode.setProperty(Constants.TYPE, entity);
303:                }
304:                return result;
305:            }
306:
307:            /** Visit a BlockDeclaration = ["static"] Block (gosling_et_al_2000 <a
308:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#246032">&sect;8.6</a>,
309:             * <a
310:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#39245">&sect;8.7</a>). */
311:            public final void visitBlockDeclaration(final GNode n) {
312:                assert 2 == n.size();
313:            }
314:
315:            /**
316:             * Visit a ClassBody = Declaration* (gosling_et_al_2000 <a
317:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#18988">&sect;8.1.5</a>,
318:             * <a
319:             * href="http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html#236431">&sect;9.1.3</a>,
320:             * <a
321:             * href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#41147">&sect;15.9</a>).
322:             */
323:            public final void visitClassBody(final GNode n) {
324:                for (final Object o : n)
325:                    dispatch((Node) o);
326:            }
327:
328:            /**
329:             * Visit a ClassDeclaration = Modifiers Identifier null [Extension]
330:             * [Implementation] ClassBody (gosling_et_al_2000 <a
331:             * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#15372">&sect;8.1</a>,
332:             * <a
333:             * href="http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#247766">&sect;14.3</a>).
334:             */
335:            public final ClassT visitClassDeclaration(final GNode n) {
336:                @SuppressWarnings("unchecked")
337:                final List<Attribute> modifiers = (List<Attribute>) dispatch(n
338:                        .getNode(0));
339:                final boolean isMember = JavaEntities
340:                        .isScopeForMember(currentScopeName());
341:                if (isMember) {
342:                    final ClassOrInterfaceT declaringType = JavaEntities
343:                            .currentType(_table);
344:                    if (JavaEntities.isWrappedInterfaceT(declaringType))
345:                        addModifiers(modifiers, MODIFIERS_INTERFACE_MEMBERTYPE);
346:                    if (JavaEntities.hasModifier(declaringType, "strictfp"))
347:                        addModifier(modifiers, "strictfp");
348:                    if (hasModifier(modifiers, "static"))
349:                        assrt(n, JavaEntities.hasModifier(declaringType,
350:                                "static")
351:                                || JavaEntities.isTypeTopLevel(declaringType),
352:                                "illegal context for static member");
353:                }
354:                assrtLegalModifiers(n.getGeneric(0), MODIFIERS_CLASS,
355:                        modifiers, "class");
356:                if (hasModifier(modifiers, "public"))
357:                    assrt(
358:                            n,
359:                            isMember
360:                                    || JavaEntities
361:                                            .isScopeTopLevel(currentScopeName()),
362:                            "public class must be member or top-level");
363:                if (hasModifier(modifiers, "protected")
364:                        || hasModifier(modifiers, "private"))
365:                    assrt(n, isMember && !memberOfInterface(),
366:                            "private or protected class must be member of class");
367:                if (hasModifier(modifiers, "static"))
368:                    assrt(n, isMember, "static class must be member");
369:                assrt(n, !hasModifier(modifiers, "final")
370:                        || !hasModifier(modifiers, "abstract"),
371:                        "can not be both abstract and final");
372:                final String simpleName = n.getString(1);
373:                final String canonicalName = JavaEntities.canonicalName(_table,
374:                        simpleName);
375:                assrtDiffersFromEnclosing(n, canonicalName);
376:                final List<Type> extension = JavaEntities
377:                        .typeList((List) dispatch(n.getNode(3)));
378:                final Type parent;
379:                if (null == extension) {
380:                    parent = JavaEntities.tObjectAlias(_table);
381:                } else {
382:                    assrt(n, 1 == extension.size(), "can only extend one class");
383:                    assrt(n, !"java.lang.Object".equals(canonicalName),
384:                            "Object can not have an extends clause");
385:                    parent = extension.get(0);
386:                }
387:                assrt(n.getGeneric(0), JavaEntities.isWrappedClassT(parent),
388:                        "class can only extend class");
389:                final List<Type> interfaces = n.get(4) == null ? new ArrayList<Type>()
390:                        : JavaEntities.typeList((List) dispatch(n.getNode(4)));
391:                if ("java.lang.Object".equals(canonicalName))
392:                    assrt(n, 0 == interfaces.size(),
393:                            "Object can not have an implements clause");
394:                for (final Type i : interfaces)
395:                    assrt(n.getGeneric(4), JavaEntities.isWrappedInterfaceT(i),
396:                            "class can only implement interface");
397:                final ClassT result = new ClassT(canonicalName, parent,
398:                        interfaces, new ArrayList<Type>(),
399:                        new ArrayList<Type>());
400:                for (final Attribute mod : modifiers)
401:                    result.addAttribute(mod);
402:                final String tagName = SymbolTable.toTagName(simpleName);
403:                assert null == _table.current().lookupLocally(tagName);
404:                _table.current().define(tagName, result);
405:                _table.enter(simpleName);
406:                result.scope(_table.current().getQualifiedName());
407:                dispatch(n.getNode(5));
408:                declareDefaultConstructorIfNecessary();
409:                _table.exit();
410:                assert result.isClass();
411:                return result;
412:            }
413:
414:            /**
415:             * Visit a CompilationUnit = [PackageDeclaration] ImportDeclaration*
416:             * Declaration* (gosling_et_al_2000 <a
417:             * href="http://java.sun.com/docs/books/jls/second_edition/html/packages.doc.html#40031">&sect;7.3</a>).
418:             */
419:            public final void visitCompilationUnit(final GNode n) {
420:                if (null == n.get(0))
421:                    visitPackageDeclaration(null);
422:                else
423:                    dispatch(n.getNode(0));
424:                _table.enter(JavaEntities
425:                        .fileNameToScopeName(n.getLocation().file));
426:                for (int i = 1; i < n.size(); i++) {
427:                    final GNode declNode = n.getGeneric(i);
428:                    assrt(n, declNode.hasName("ImportDeclaration")
429:                            || declNode.hasName("ClassDeclaration")
430:                            || declNode.hasName("InterfaceDeclaration")
431:                            || declNode.hasName("EmptyDeclaration"),
432:                            "unexpected top-level %s", declNode.getName());
433:                    dispatch(declNode);
434:                }
435:                _table.setScope(_table.root());
436:            }
437:
438:            /**
439:             * Visit a EmptyDeclaration = (no children) (gosling_et_al_2000 <a
440:             * href="http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#5970">&sect;14.6</a>).
441:             */
442:            public final void visitEmptyDeclaration(final GNode n) {
443:                assert 0 == n.size();
444:            }
445:
446:            /** Visit an Extension = Type+. */
447:            public final List<Type> visitExtension(final GNode n) {
448:                // gosling_et_al_2000 8.1.3, 9.1.2
449:                final List<Type> result = makeList(n);
450:                for (final Type t : result)
451:                    assrt(n, JavaEntities.isWrappedClassT(t)
452:                            || JavaEntities.isWrappedInterfaceT(t),
453:                            "supertype must be class or interface");
454:                return result;
455:            }
456:
457:            /**
458:             * Visit a FieldDeclaration = Modifiers Type Declarators.
459:             * Also descends into Declarators = Declarator+ and into
460:             * Declarator = Identifier [Dimensions] [VariableInitializer]
461:             * to get all the fields declared by this node.
462:             */
463:            public final List<Type> visitFieldDeclaration(final GNode n) {
464:                // gosling_et_al_2000 9.3
465:                @SuppressWarnings("unchecked")
466:                final List<Attribute> modifiers = (List<Attribute>) dispatch(n
467:                        .getNode(0));
468:                if (memberOfInterface()) {
469:                    addModifiers(modifiers, MODIFIERS_INTERFACE_FIELD);
470:                    assrtLegalModifiers(n, MODIFIERS_INTERFACE_FIELD,
471:                            modifiers, "interface field");
472:                } else {
473:                    assrtLegalModifiers(n, MODIFIERS_FIELD, modifiers, "field");
474:                }
475:                final Type type = (Type) dispatch(n.getNode(1));
476:                assrt(n.getGeneric(1), JavaEntities.isRValueT(type),
477:                        "illegal type for field");
478:                return processDeclarators(modifiers, type, n.getGeneric(2));
479:            }
480:
481:            /** Visit a FormalParameter = [Modifier] Type null Identifier [Dimensions]. */
482:            public final Type visitFormalParameter(final GNode n) {
483:                // gosling_et_al_2000 8.4.1
484:                assert null == n.get(4) : "must run JavaAstSimplifier first";
485:                final String id = n.getString(3);
486:                final Type result = VariableT.newParam((Type) dispatch(n
487:                        .getNode(1)), id);
488:                result.language(Language.JAVA);
489:                if (n.getGeneric(0).size() != 0)
490:                    result.addAttribute(JavaEntities.nameToModifier("final"));
491:                if (null == _table.current().lookupLocally(id)) {
492:                    _table.current().define(id, result);
493:                    result.scope(_table.current().getQualifiedName());
494:                } else
495:                    _runtime.error("duplicate parameter declaration " + id, n);
496:                assert JavaEntities.isParameterT(result);
497:                return result;
498:            }
499:
500:            /** Visit a FormalParameters = FormalParameter*. */
501:            public final List<Type> visitFormalParameters(final GNode n) {
502:                // gosling_et_al_2000 8.4.1
503:                return makeList(n);
504:            }
505:
506:            /** Visit an Implementation = Type+. */
507:            public final List<Type> visitImplementation(final GNode n) {
508:                // gosling_et_al_2000 8.1.4
509:                final List<Type> result = makeList(n);
510:                for (final Iterator iN = n.iterator(), iT = result.iterator(); iT
511:                        .hasNext();)
512:                    assrt((GNode) iN.next(), JavaEntities
513:                            .isWrappedInterfaceT((Type) iT.next()),
514:                            "supertype must be class or interface");
515:                return result;
516:            }
517:
518:            /** Visit an ImportDeclaration = QualifiedIdentifier ["*"]. */
519:            public final void visitImportDeclaration(final GNode n) {
520:                // gosling_et_al_2000 7.5
521:                final String canonicalName = (String) dispatch(n.getNode(1));
522:                if (n.get(2) == null) {
523:                    // defer resolution to JavaAnalyzer.visitPrimaryIdentifier()
524:                    final AliasT t = new AliasT(canonicalName);
525:                    final String simpleName = Utilities
526:                            .unqualify(canonicalName);
527:                    // TD 03 (7.5) ImportDeclaration = QualifiedIdentifier ["*"] (check whether the name clashes with some existing package)
528:                    assrt(n, JavaEntities.isWrappedClassT(t)
529:                            || JavaEntities.isWrappedInterfaceT(t),
530:                            "import must be class or interface");
531:                    _table.current().define(SymbolTable.toTagName(simpleName),
532:                            t);
533:                } else {
534:                    final PackageT t = JavaEntities.canonicalNameToPackage(
535:                            _table, canonicalName);
536:                    _table.current().addDefinition("imports(*)", t);
537:                }
538:            }
539:
540:            /** Visit a InterfaceDeclaration = Modifiers Identifier null [Extension] ClassBody. */
541:            public final InterfaceT visitInterfaceDeclaration(final GNode n) {
542:                // gosling_et_al_2000 9.1
543:                @SuppressWarnings("unchecked")
544:                final List<Attribute> modifiers = (List<Attribute>) dispatch(n
545:                        .getNode(0));
546:                addModifier(modifiers, "abstract");
547:                final boolean isMember = JavaEntities
548:                        .isScopeForMember(currentScopeName());
549:                if (isMember) {
550:                    final ClassOrInterfaceT declaringType = JavaEntities
551:                            .currentType(_table);
552:                    if (declaringType.isInterface())
553:                        addModifiers(modifiers, MODIFIERS_INTERFACE_MEMBERTYPE);
554:                    if (JavaEntities.hasModifier(declaringType, "strictfp"))
555:                        addModifier(modifiers, "strictfp");
556:                    addModifier(modifiers, "static");
557:                    assrt(n, JavaEntities.hasModifier(declaringType, "static")
558:                            || JavaEntities.isTypeTopLevel(declaringType),
559:                            "illegal context for static member");
560:                }
561:                if (hasModifier(modifiers, "protected")
562:                        || hasModifier(modifiers, "private"))
563:                    assrt(n, isMember,
564:                            "private or protected interface must be member");
565:                if (hasModifier(modifiers, "static"))
566:                    assrt(n, isMember, "static interface must be member");
567:                assrtLegalModifiers(n, MODIFIERS_INTERFACE, modifiers,
568:                        "interface");
569:                final String simpleName = n.getString(1);
570:                final String canonicalName = JavaEntities.canonicalName(_table,
571:                        simpleName);
572:                assrtDiffersFromEnclosing(n, canonicalName);
573:                final List<Type> interfaces = null == n.get(3) ? new ArrayList<Type>()
574:                        : JavaEntities.typeList((List) dispatch(n.getNode(3)));
575:                final InterfaceT result = new InterfaceT(canonicalName,
576:                        interfaces, new ArrayList<Type>(),
577:                        new ArrayList<Type>());
578:                for (final Attribute mod : modifiers)
579:                    result.addAttribute(mod);
580:                final String tagName = SymbolTable.toTagName(simpleName);
581:                if (null == _table.current().lookupLocally(tagName)) {
582:                    _table.current().define(tagName, result);
583:                    _table.enter(simpleName);
584:                    result.scope(_table.current().getQualifiedName());
585:                    final GNode bodyNode = n.getGeneric(4);
586:                    for (int i = 0; i < bodyNode.size(); i++) {
587:                        final GNode memberNode = bodyNode.getGeneric(i);
588:                        assrt(n, memberNode.hasName("EmptyDeclaration")
589:                                || memberNode.hasName("FieldDeclaration")
590:                                || memberNode.hasName("MethodDeclaration")
591:                                || memberNode.hasName("ClassDeclaration")
592:                                || memberNode.hasName("InterfaceDeclaration"),
593:                                "illegal interface member");
594:                        dispatch(memberNode);
595:                    }
596:                    _table.exit();
597:                    if (JavaEntities.isTypeNested(result))
598:                        assrt(n, !JavaEntities.isTypeInner(JavaEntities
599:                                .declaringType(_table, result)),
600:                                "inner classes may not declare member interfaces");
601:                } else {
602:                    _runtime.error("duplicate declaration " + canonicalName, n);
603:                }
604:                assert result.isInterface();
605:                return result;
606:            }
607:
608:            /**
609:             * Visit a MethodDeclaration = Modifiers null Type Identifier FormalParameters [Dimensions]
610:             * [ThrowsClause] [Block].
611:             */
612:            public final Type visitMethodDeclaration(final GNode n) {
613:                // gosling_et_al_2000 8.4, 8.8, 9.4
614:                assert null == n.get(5) : "must run JavaAstSimplifier first";
615:                @SuppressWarnings("unchecked")
616:                final List<Attribute> modifiers = (List<Attribute>) dispatch(n
617:                        .getNode(0));
618:                final String name = n.getString(3);
619:                final ClassOrInterfaceT base = JavaEntities.currentType(_table);
620:                final boolean isConstructor = JavaEntities.typeToSimpleName(
621:                        base).equals(name);
622:                final Type returnType = isConstructor ? (JavaEntities
623:                        .constructorsReturnVoid() ? JavaEntities
624:                        .nameToBaseType("void") : base) : (Type) dispatch(n
625:                        .getNode(2));
626:                if (!isConstructor) {
627:                    assrt(n, null != n.get(2), "missing return type");
628:                    if (JavaEntities.hasModifier(base, "strictfp"))
629:                        addModifier(modifiers, "strictfp");
630:                    if (JavaEntities.hasModifier(base, "final"))
631:                        addModifier(modifiers, "final");
632:                    if (hasModifier(modifiers, "private"))
633:                        addModifier(modifiers, "final");
634:                }
635:                if (memberOfInterface()) {
636:                    assrt(n, !isConstructor,
637:                            "interface can not have constructor");
638:                    addModifiers(modifiers, MODIFIERS_INTERFACE_METHOD);
639:                    assrtLegalModifiers(n, MODIFIERS_INTERFACE_METHOD,
640:                            modifiers, "interface method");
641:                } else {
642:                    if (isConstructor)
643:                        assrtLegalModifiers(n, MODIFIERS_CONSTRUCTOR,
644:                                modifiers, "constructor");
645:                    else
646:                        assrtLegalModifiers(n, MODIFIERS_METHOD, modifiers,
647:                                "method");
648:                }
649:                if (hasModifier(modifiers, "static"))
650:                    assrt(n, JavaEntities.hasModifier(base, "static")
651:                            || JavaEntities.isTypeTopLevel(base),
652:                            "illegal context for static member");
653:                final List<Type> exceptions = null == n.get(6) ? new ArrayList<Type>()
654:                        : JavaEntities.typeList((List) dispatch(n.getNode(6)));
655:                final String symbol = JavaEntities.methodSymbolFromAst(n);
656:                _table.enter(symbol);
657:                final List<Type> parameters = JavaEntities
658:                        .typeList((List) dispatch(n.getNode(4)));
659:                final Type result = new MethodT(returnType, name, parameters,
660:                        false, exceptions);
661:                for (final Attribute mod : modifiers)
662:                    result.addAttribute(mod);
663:                if (JavaEntities.hasModifier(result, "abstract"))
664:                    assrt(n, !JavaEntities.hasModifier(result, "private")
665:                            && !JavaEntities.hasModifier(result, "static")
666:                            && !JavaEntities.hasModifier(result, "final")
667:                            && !JavaEntities.hasModifier(result, "native")
668:                            && !JavaEntities.hasModifier(result, "strictfp")
669:                            && !JavaEntities
670:                                    .hasModifier(result, "synchronized"),
671:                            "conflicting modifiers");
672:                assrt(n, !JavaEntities.hasModifier(result, "strictfp")
673:                        || !JavaEntities.hasModifier(result, "native"),
674:                        "conflicting modifiers");
675:                result.scope(_table.current().getQualifiedName());
676:                _table.exit();
677:                _table.current().define(symbol, result);
678:                JavaEntities.currentType(_table).getMethods().add(result);
679:                assert result.isMethod();
680:                return result;
681:            }
682:
683:            /** Visit a Modifiers = Modifier*. */
684:            public final List<Attribute> visitModifiers(final GNode n) {
685:                final List<Attribute> result = new ArrayList<Attribute>();
686:                for (int i = 0; i < n.size(); i++) {
687:                    final String name = n.getGeneric(i).getString(0);
688:                    final Attribute modifier = JavaEntities
689:                            .nameToModifier(name);
690:                    if (null == modifier)
691:                        _runtime.error("unexpected modifier " + name, n);
692:                    else if (result.contains(modifier))
693:                        _runtime.error("duplicate modifier " + name, n);
694:                    else
695:                        result.add(modifier);
696:                }
697:                return result;
698:            }
699:
700:            /** Visit a PackageDeclaration = QualifiedIdentifier. */
701:            public final PackageT visitPackageDeclaration(final GNode n) {
702:                // gosling_et_al_2000 9.4
703:                final String canonicalName = null == n ? ""
704:                        : (String) dispatch(n.getNode(1));
705:                final PackageT result = JavaEntities.canonicalNameToPackage(
706:                        _table, canonicalName);
707:                _table.enter(JavaEntities.packageNameToScopeName(result
708:                        .getName()));
709:                return result;
710:            }
711:
712:            /** Visit a PrimitiveType = ("byte" / "short" / "char" / "int" / "long" / "float" / "double" / "boolean")
713:             * (gosling_et_al_2000 <a href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#85587">&sect;4.2</a>). */
714:            public final Type visitPrimitiveType(final GNode n) {
715:                final Type result = JavaEntities.nameToBaseType(n.getString(0));
716:                assrt(n, null != result
717:                        && (JavaEntities.isPrimitiveT(result) || result
718:                                .isVoid()), "unknown base type %s", n
719:                        .getString(0));
720:                return result;
721:            }
722:
723:            /** Visit a QualifiedIdentifier = Identifier+. */
724:            public final String visitQualifiedIdentifier(final GNode n) {
725:                // using StringBuffer instead of Utilities.qualify() to avoid O(n^2)
726:                // behavior
727:                final StringBuffer b = new StringBuffer();
728:                for (int i = 0; i < n.size(); i++) {
729:                    if (b.length() > 0)
730:                        b.append(Constants.QUALIFIER);
731:                    b.append(n.getString(i));
732:                }
733:                return b.toString();
734:            }
735:
736:            /** Visit a ThrowsClause = QualifiedIdentifier+. */
737:            public final List<Type> visitThrowsClause(final GNode n) {
738:                //gosling_et_al_2000 8.4.4, 8.8.4, 9.4
739:                final List<Type> result = new ArrayList<Type>(n.size());
740:                for (int i = 0; i < n.size(); i++) {
741:                    final String name = (String) dispatch(n.getNode(i));
742:                    result.add(new AliasT(name));
743:                }
744:                return result;
745:            }
746:
747:            /**
748:             * Visit a Type = TypeName Dimensions
749:             * (gosling_et_al_2000 <a href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#48440">&sect;4</a>,
750:             * <a href="http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html#25518">&sect;10.1</a>).
751:             * Note that TypeName is either PrimitiveType or ClassType, i.e., QualifiedIdentifier.
752:             * Make no resolution attempt in the case of a qualified identifier, just
753:             * return an alias every time. The reason is that in general, there is
754:             * too little information to resolve the type at this point. For example, the
755:             * name may refer to a type declared in another file, which may recursively
756:             * mention an entity in this file.
757:             */
758:            public final Type visitType(final GNode n) {
759:                final boolean composite = n.getGeneric(0).hasName(
760:                        "QualifiedIdentifier");
761:                final Object dispatched0 = dispatch(n.getNode(0));
762:                final Type componentT = composite ? new AliasT(
763:                        (String) dispatched0) : (Type) dispatched0;
764:                final int dimensions = countDimensions(n.getGeneric(1));
765:                final Type result = JavaEntities.typeWithDimensions(componentT,
766:                        dimensions);
767:                assrt(n, JavaEntities.isReturnT(result),
768:                        "unexpected type reference");
769:                return result;
770:            }
771:
772:            /** Visit a VoidType = (no children). */
773:            public final Type visitVoidType(final GNode n) {
774:                return JavaEntities.nameToBaseType("void");
775:            }
776:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.