1d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein/* 2d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Copyright (C) 2011 Google Inc. 3d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * 4d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License"); 5d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * you may not use this file except in compliance with the License. 6d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * You may obtain a copy of the License at 7d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * 8d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * http://www.apache.org/licenses/LICENSE-2.0 9d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * 10d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software 11d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS, 12d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * See the License for the specific language governing permissions and 14d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * limitations under the License. 15d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 16d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 17d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinpackage com.google.doclava; 18d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 196ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport com.google.doclava.parser.JavaLexer; 206ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport com.google.doclava.parser.JavaParser; 216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 22d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport org.antlr.runtime.ANTLRFileStream; 23d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport org.antlr.runtime.CommonToken; 246ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport org.antlr.runtime.CommonTokenStream; 256ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport org.antlr.runtime.RecognitionException; 266ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport org.antlr.runtime.debug.ParseTreeBuilder; 27d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport org.antlr.runtime.tree.ParseTree; 28d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport org.antlr.runtime.tree.Tree; 29d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 306ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport java.io.IOException; 316ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinimport java.util.ArrayList; 327c80d0e9086eef289d323661977cbfb771d95a2aMorad Abdelrahmanimport java.util.Collections; 33d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.HashMap; 34d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.HashSet; 35d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Iterator; 36d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 37d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein/** 38d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * InfoBuilder parses an individual file and builds Doclava 39d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * objects out of the data within the file. This data is 40d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * stored within a global cache for later use. 41d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 42d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinpublic class InfoBuilder { 43d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private PackageInfo mPackage; 44d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ArrayList<String> mImports; 45d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private HashSet<String> mClassNames; 466ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private String mFilename; // TODO - remove this eventually 476ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private ClassInfo mRootClass; 48d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 496ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public InfoBuilder(String filename) { 50d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mImports = new ArrayList<String>(); 51d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mImports.add("java.lang.*"); // should allow us to resolve this properly, eventually 52d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // alternatively, we could add everything from java.lang.* 53d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // but that would probably be too brittle 54d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mClassNames = new HashSet<String>(); 556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein mFilename = filename; 566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein @Override 596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public String toString() { 606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return mFilename; 616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 636ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public void parseFile() { 646ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein JavaLexer lex; 656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein try { 666ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein lex = new JavaLexer(new ANTLRFileStream(mFilename, "UTF8")); 676ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein CommonTokenStream tokens = new CommonTokenStream(lex); 696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 706ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // create the ParseTreeBuilder to build a parse tree 716ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // much easier to parse than ASTs 726ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ParseTreeBuilder builder = new ParseTreeBuilder("compilationUnit"); 736ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein JavaParser g = new JavaParser(tokens, builder); 746ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 756ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein g.compilationUnit(); 766ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ParseTree tree = builder.getTree(); 776ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 786ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein lex = null; 796ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein tokens = null; 806ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein builder = null; 816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein g = null; 826ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 836ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein parseFile(tree); 846ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 856ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } catch (IOException e1) { 866ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein e1.printStackTrace(); 876ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } catch (RecognitionException e) { 886ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein e.printStackTrace(); 896ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 906ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 916ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 926ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public static void resolve() { 936ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein Caches.resolve(); 94d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 95d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 96d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // All of the print functions exist for debugging alone. 97d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public void printStuff() { 98d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(mPackage.name() + "\n"); 99d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 100d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein printList(mImports); 101d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 102d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Caches.printResolutions(); 103d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 104d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 105d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void printList(ArrayList<String> list) { 106d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (String value : list) { 107d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(value); 108d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 109d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 110d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 111d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 112d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1136ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public static void printClassInfo(ClassInfo cl) { 1146ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print("Class: " + cl.toString()); 1156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeVariables(cl.type()); 1176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 1196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(cl.comment().mText); 121d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!cl.annotations().isEmpty()) { 1236ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nAnnotations:"); 1246ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printAnnotations(cl.annotations()); 1256ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 126d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.superclass() != null) { 1286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print("Superclass: " + cl.superclass().qualifiedName()); 1296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeVariables(cl.superclassType()); 130d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 1316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 132d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!cl.realInterfaces().isEmpty()) { 1346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nInterfaces Implemented:"); 1356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein Iterator<TypeInfo> it = cl.realInterfaceTypes().iterator(); 1366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (ClassInfo cls : cl.realInterfaces()) { 1376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein TypeInfo outerType = it.next(); 1386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cls == null) { 1396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(outerType.simpleTypeName()); 1406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else { 1416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(cls.qualifiedName()); 1426ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 143d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeVariables(outerType); 145d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 146d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 147d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 148d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1496ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 1506ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 151d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1526ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!cl.allSelfFields().isEmpty()) { 1536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nFields:"); 1546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (FieldInfo f : cl.allSelfFields()) { 1556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (f != cl.allSelfFields().get(0)) { 156d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 157d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(f.comment().mText); 159d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printAnnotations(f.annotations()); 1616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeName(f.type()); 162d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1636ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" " + f.name()); 164d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (f.constantValue() != null) { 1666ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(": " + f.constantValue()); 1676ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if (f.hasValue()) { 1686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(": has some value"); 1696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else { 1706ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 171d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 172d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 173d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1746ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 1756ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 176d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1776ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.enumConstants() != null && !cl.enumConstants().isEmpty()) { 1786ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nEnum Constants:"); 1796ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (FieldInfo f : cl.enumConstants()) { 1806ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (f != cl.enumConstants().get(0)) { 1816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 182d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1836ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(f.comment().mText); 1846ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printAnnotations(f.annotations()); 1856ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(f.type().simpleTypeName() + " " + f.name()); 186d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1876ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (f.constantValue() != null) { 1886ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(": " + f.constantValue()); 1896ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else { 1906ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 1916ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 192d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 193d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1946ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 1956ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 196d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1976ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!cl.allConstructors().isEmpty()) { 1986ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nConstructors:"); 1996ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (MethodInfo m : cl.allConstructors()) { 2006ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m != cl.allConstructors().get(0)) { 2016ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 2026ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 203d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2046ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(m.comment().mText); 205d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printAnnotations(m.annotations()); 2076ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m.getTypeParameters() != null) { 2086ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeVariableList(m.getTypeParameters()); 2096ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" "); 210d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 211d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2126ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(m.name() + m.flatSignature()); 213d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 214d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 2166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 217d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!cl.allSelfMethods().isEmpty()) { 2196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nMethods:"); 2206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (MethodInfo m : cl.allSelfMethods()) { 2216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m != cl.allSelfMethods().get(0)) { 2226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 2236ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 224d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2256ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(m.comment().mText); 2266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printAnnotations(m.annotations()); 2276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m.getTypeParameters() != null) { 2286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeVariableList(m.getTypeParameters()); 2296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" "); 2306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 231d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeName(m.returnType()); 233d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" " + m.name() + m.flatSignature()); 235d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m.thrownExceptions() != null && !m.thrownExceptions().isEmpty()) { 2376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" throws "); 2386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (ClassInfo c : m.thrownExceptions()) { 2396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (c != m.thrownExceptions().get(0)) { 2406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(", "); 241d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 242d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(c.name()); 2446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 245d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 246d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 247d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 248d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 249d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2506ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 2516ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 252d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!cl.annotationElements().isEmpty()) { 2546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nAnnotation Elements:"); 255d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (MethodInfo m : cl.annotationElements()) { 2576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m != cl.annotationElements().get(0)) { 2586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 2596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 260d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(m.comment().mText); 2626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printAnnotations(m.annotations()); 2636ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printTypeName(m.returnType()); 264d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" " + m.name() + m.flatSignature()); 266d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2676ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (m.defaultAnnotationElementValue() != null) { 2686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.print(" default " + 2696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein m.defaultAnnotationElementValue().valueString()); 270d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 271d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 272d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 273d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2746ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 2756ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 2766ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 2776ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 2786ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.innerClasses() != null && !cl.innerClasses().isEmpty()) { 2796ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("\nInner Classes:"); 2806ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (ClassInfo c : cl.innerClasses()) { 2816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein printClassInfo(c); 2826ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 283d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 284d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 285d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2866ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static void printTypeName(TypeInfo type) { 287d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(type.simpleTypeName()); 288d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 289d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type.extendsBounds() != null && !type.extendsBounds().isEmpty()) { 290d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(" extends "); 291d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (TypeInfo t : type.extendsBounds()) { 292d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (t != type.extendsBounds().get(0)) { 293d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(" & "); 294d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 295d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein printTypeName(t); 296d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 297d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 298d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 299d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type.superBounds() != null && !type.superBounds().isEmpty()) { 300d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(" super "); 301d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (TypeInfo t : type.superBounds()) { 302d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (t != type.superBounds().get(0)) { 303d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(" & "); 304d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 305d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein printTypeName(t); 306d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 307d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 308d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 309d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein printTypeVariables(type); 310d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 311d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type.dimension() != null) { 312d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(type.dimension()); 313d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 314d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 315d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 3166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static void printAnnotations(ArrayList<AnnotationInstanceInfo> annotations) { 317d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (AnnotationInstanceInfo i : annotations) { 318d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(i); 319d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 320d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 321d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 3226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static void printTypeVariables(TypeInfo type) { 323d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein printTypeVariableList(type.typeArguments()); 324d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 325d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 3266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static void printTypeVariableList(ArrayList<TypeInfo> typeList) { 327d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (typeList != null && !typeList.isEmpty()) { 328d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print("<"); 329d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (TypeInfo type : typeList) { 330d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type != typeList.get(0)) { 331d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(", "); 332d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 333d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein printTypeName(type); 334d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 335d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.print(">"); 336d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 337d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 338d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 339d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 340d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the file represented by the ParseTree. 341d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree A ParseTree of the file to parse. 342d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 3436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private void parseFile(ParseTree tree) { 344d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (tree.payload != null) { 345d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String payload = tree.payload.toString(); 346d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 347d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // first pass at ignore method blocks 348d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("block".equals(payload) || 3496ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein "blockStatement".equals(payload) || 3506ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein "explicitConstructorInvocation".equals(payload)) { 351d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein tree = null; 352d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 353d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 354d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 355d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse package of file 356d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("packageDeclaration".equals(payload)) { 357d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mPackage = buildPackage(tree); 358d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 359d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse imports 360d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("importDeclaration".equals(payload)) { 361d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mImports.add(buildImport(tree)); 362d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 363d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // classes 364d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("normalClassDeclaration".equals(payload)) { 3656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein buildClass(tree, null); 366d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 367d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // enums 368d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("enumDeclaration".equals(payload)) { 3696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein buildEnum(tree, null); 370d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 371d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // interfaces 372d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("normalInterfaceDeclaration".equals(payload)) { 3736ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein buildInterface(tree, null); 374d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 375d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // annotations 376d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("annotationTypeDeclaration".equals(payload)) { 3776ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein buildAnnotationDeclaration(tree, null); 378d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 379d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 380d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 381d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 382d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if we're not at the end, recurse down the tree 383d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (int i = 0; i < tree.getChildCount(); i++) { 384d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein parseFile((ParseTree) tree.getChild(i)); 385d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 386d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 387d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 388d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 389d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses a packageDeclaration in the tree. This function should only be called once per file. 390d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. packageDeclaration should be the root value. 391d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return a PackageInfo representing the package in which this file exists. 392d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 393d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private PackageInfo buildPackage(ParseTree tree) { 394d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (int i = 0; i < tree.getChildCount(); i++) { 395d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) tree.getChild(i); 396d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 397d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (child.payload != null && "qualifiedName".equals(child.payload.toString())) { 398d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String packageName = buildQualifiedName(child); 399d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 400d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // return package because we might be creating packages for other classes 401d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return Caches.obtainPackage(packageName); 402d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 403d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 404d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 405d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return null; 406d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 407d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 408d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 409d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses a qualifiedName, returning it as a String. 410d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. qualifiedName should be the root value. 411d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return 412d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 413d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static String buildQualifiedName(ParseTree tree) { 414d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder packageName = new StringBuilder(); 415d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 416d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (int j = 0; j < tree.getChildCount(); j++) { 417d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein packageName.append(tree.getChild(j).toString()); 418d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 419d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 420d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return packageName.toString(); 421d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 422d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 423d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 424d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a string representing an import declaration. 425d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. importDeclaration should be the root value. 426d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return a String version of the import. 427d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 428d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private String buildImport(ParseTree tree) { 429d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder theImport = new StringBuilder(); 4306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (int i = 1; i < tree.getChildCount(); i++) { 431d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String part = tree.getChild(i).toString(); 432d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 4336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ((i == 1 && "static".equals(part)) 4346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein || (i == tree.getChildCount()-1 && ";".equals(part))) { 4356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein continue; 436d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 4376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 4386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein theImport.append(part); 439d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 440d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 441d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return theImport.toString(); 442d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 443d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 444d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 445d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a ClassInfo for a normalClassDeclaration. 446d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. normalClassDeclaration should be the root value. 447d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass The class that contains the class that will be built. 448d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * This value should be null if this class is a root class in the file. 449d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return A ClassInfo that contains all of the information about the class. 450d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 451d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ClassInfo buildClass(ParseTree tree, ClassInfo containingClass) { 452d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = parseCommentAndPosition(tree); 453d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Modifiers modifiers = new Modifiers(this); 454d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo cls = null; 455d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 456d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 457d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 458d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 459d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 460d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse modifiers 461d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.parseModifiers(child); 462d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 463d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein it.next(); 464d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 465d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 466d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse class name 467d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls = buildClassName(child, containingClass, modifiers, 468d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getCommentText(), 469d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getPosition(), 470d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassType.ORDINARY); 471d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 472d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 473d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 474d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle generics 475d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("typeParameters".equals(child.toString())) { 476d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.type().setTypeArguments(buildTypeVariables(child)); 477d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 478d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 479d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 480d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 481d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle extends 482d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("extends".equals(child.toString())) { 483d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 484d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 485d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type = buildType(child); 486d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.setSuperclassType(type); 487d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 488d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if ClassInfo is null, we need to add a resolution 489d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type.asClassInfo() == null) { 4906ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein addFutureResolution(cls, "superclassQualifiedName", type.simpleTypeName(), this); 491d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 492d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 493d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.setSuperClass(type.asClassInfo()); 494d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 495d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 496d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 497d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 4986ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // TODO - do I have to make java.lang.Object the superclass if there is none otherwise? 4996ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 500d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle implements 501d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("implements".equals(child.toString())) { 502d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 503d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 504d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein parseInterfaces(child, cls); 505d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 506d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 507d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 508d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 509d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // finally, parse the body 510d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein buildClassBody(child, cls); 511d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 512d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return cls; 513d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 514d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 515d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 516d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the list of interfaces that the class implements. 517d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Should only be called if the implements keyword is found. 518d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. typeList should be the root element. 519d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param cls The class that implements these interfaces. 520d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 521d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void parseInterfaces(ParseTree tree, ClassInfo cls) { 522d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 523d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("type".equals(o.toString())) { 524d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type = buildType((ParseTree) o); 525d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.addInterfaceType(type); 526d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 527d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if ClassInfo is null, we need to add a resolution 528d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type.asClassInfo() == null) { 5296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein addFutureResolution(cls, "interfaceQualifiedName", type.simpleTypeName(), this); 530d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 531d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 532d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.addInterface(type.asClassInfo()); 533d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 534d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 535d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 536d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 537d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 538d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * ClassType exists solely to tell buildClassName which type of ClassInfo is being built. 539d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 540d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private enum ClassType { 541d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ENUM, INTERFACE, ANNOTATION, ORDINARY 542d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 543d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 544d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 545d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the class name from the declaration. Also initializes the class. 546d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree Position of the tree where the name of the class resides. 547d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass Class that this class is contained within. 548d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * <tt>null</tt> if this class is the root class. 549d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param modifiers Contains all the modifiers of this class. 550d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param commentText Javadoc comment of this class. 551d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param position Position of the class. 552d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param classType Type of class being instantiated. 553d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return the ClassInfo being initialized. 554d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 555d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ClassInfo buildClassName(ParseTree tree, ClassInfo containingClass, Modifiers modifiers, 556d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String commentText, SourcePositionInfo position, ClassType classType) { 557d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String qualifiedClassName = null; 558d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isOrdinaryClass = true; 559d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isException = false; 560d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isError = false; 561d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isIncluded = false; 562d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isPrimitive = false; 563d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isEnum = false; 564d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isInterface = false; 565d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isAnnotation = false; 566d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 567d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // set appropriate flags based on ClassType 568d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein switch (classType) { 569d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein case ENUM: 570d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein isEnum = true; 571d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein break; 572d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein case INTERFACE: 573d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein isInterface = true; 574d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein break; 575d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein case ANNOTATION: 576d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein isAnnotation = true; 577d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein break; 578d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 579d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 580d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String qualifiedTypeName = null; 581d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo cls = null; 582d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 583d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // changes the name based upon whether this is the root class or an inner class 584d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (containingClass == null) { 585d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedClassName = mPackage.name() + "." + tree.toString(); 586d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 587d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedClassName = containingClass.qualifiedName() + "." + tree.toString(); 588d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 589d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 590d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedTypeName = new String(qualifiedClassName); 591d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 592d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // add the name to mClassNames so that we can use it to resolve usages of this class 593d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mClassNames.add(qualifiedClassName); 594d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 595d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get the class from the cache and initialize it 596d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls = Caches.obtainClass(qualifiedClassName); 597d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.initialize(commentText, position, 5986ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isPublic(), modifiers.isProtected(), 5996ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isPackagePrivate(), modifiers.isPrivate(), 6006ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isStatic(), isInterface, modifiers.isAbstract(), 6016ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein isOrdinaryClass, isException, isError, isEnum, isAnnotation, 6026ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isFinal(), isIncluded, qualifiedTypeName, isPrimitive, 6036ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.getAnnotations()); 604d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 605d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.setContainingClass(containingClass); 6066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cls.setContainingPackage(mPackage); 6076ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 6086ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (containingClass == null) { 6096ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein mRootClass = cls; 6106ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 611d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 612d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // create an set a TypeInfo for this class 613d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type = new TypeInfo(false, null, cls.name(), qualifiedTypeName, cls); 614d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.setTypeInfo(type); 615d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 616d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return cls; 617d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 618d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 619d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 620d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the body of a class. 621d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. classBody should be the root value. 622d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param cls 623d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 624d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void buildClassBody(ParseTree tree, ClassInfo cls) { 625d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 626d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) o; 627d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 628d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // skip all of the cruft that isn't a declaration 629d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (!"classBodyDeclaration".equals(child.toString())) { 630d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 631d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 632d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 633d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get to an actual definition 634d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree member = (ParseTree) child.getChild(0).getChild(0); 635d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 6366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // ignores static initializers 6376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (member == null) { 6386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein continue; 6396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 6406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 641d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // field 642d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("fieldDeclaration".equals(member.toString())) { 6436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (FieldInfo f : buildFields(member, cls)) { 6446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cls.addField(f); 6456ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 646d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // method and constructor 647d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("methodDeclaration".equals(member.toString())) { 648d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein MethodInfo method = buildMethod(member, cls, false); 649d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 650d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (method.kind().equals("constructor")) { 651d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.addConstructor(method); 652d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 653d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls.addMethod(method); 654d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 655d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // classes and enums 656d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("classDeclaration".equals(member.toString())) { 657d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Object tmp = member.getChild(0); 658d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 659d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("normalClassDeclaration".equals(tmp.toString())) { 6606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cls.addInnerClass(buildClass((ParseTree) tmp, cls)); 661d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("enumDeclaration".equals(tmp.toString())) { 6626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cls.addInnerClass(buildEnum((ParseTree) tmp, cls)); 663d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 664d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // interfaces and annotations 665d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("interfaceDeclaration".equals(member.toString())) { 666d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Object tmp = member.getChild(0); 667d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 668d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("normalInterfaceDeclaration".equals(tmp.toString())) { 6696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cls.addInnerClass(buildInterface((ParseTree) tmp, cls)); 670d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("annotationTypeDeclaration".equals(tmp.toString())) { 6716ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cls.addInnerClass(buildAnnotationDeclaration((ParseTree) tmp, cls)); 672d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 673d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 674d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 675d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 676d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 677d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 6786ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * Builds one or more FieldInfos for the field declared in this class. 679d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. fieldDeclaration should be the root value. 680d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass The ClassInfo in which this field is contained. 6816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * @return A list of FieldInfos for this field declaration. 682d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 6836ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private ArrayList<FieldInfo> buildFields(ParseTree tree, ClassInfo containingClass) { 6846ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ArrayList<FieldInfo> fields = new ArrayList<FieldInfo>(); 685d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Modifiers modifiers = new Modifiers(this); 686d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = parseCommentAndPosition(tree); 687d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String name = null; 688d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Object constantValue = null; 689d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type = null; 690d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean hasValue = false; 691d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 692d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 693d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 694d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 695d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 696d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // modifiers 697d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.parseModifiers(child); 698d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 699d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 700d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse the type of this field 701d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type = buildType(child); 702d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 703d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 704d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 705d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse the variable declarators 7066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein boolean firstType = true; 7076ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein while (!";".equals(child.toString())) { 7086ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("variableDeclarator".equals(child.toString())) { 7096ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein TypeInfo newType; 7106ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (firstType) { 7116ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein firstType = false; 7126ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType = type; 7136ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else { 7146ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType = new TypeInfo(type.isPrimitive(), type.dimension(), 7156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein type.simpleTypeName(), type.qualifiedTypeName(), type.asClassInfo()); 7166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType.setBounds(type.superBounds(), type.extendsBounds()); 7176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType.setIsWildcard(type.isWildcard()); 7186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType.setIsTypeVariable(type.isTypeVariable()); 7196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType.setTypeArguments(type.typeArguments()); 7206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 7216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein name = child.getChild(0).toString(); 7226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7236ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // if we have a value for the field and/or dimensions 7246ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (child.getChildCount() > 1) { 7256ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein int j = 1; 7266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ParseTree tmp = (ParseTree) child.getChild(j++); 7276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // if we have dimensions in the wrong place 7296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("[".equals(tmp.toString())) { 7306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein StringBuilder builder = new StringBuilder(); 7316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein do { 7336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein builder.append(tmp.toString()); 7346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein tmp = (ParseTree) child.getChild(j++); 7356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } while (j < child.getChildCount() && !"=".equals(tmp.toString())); 7366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType.setDimension(builder.toString()); 7386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 7396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // get value if it exists 7416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (j < child.getChildCount()) { 7426ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // get to variableInitializer 7436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein do { 7446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein tmp = (ParseTree) child.getChild(j++); 7456ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } while (!"variableInitializer".equals(tmp.toString())); 7466ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7476ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // get the constantValue 7486ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein constantValue = parseExpression(tmp); 7496ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 7506ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7516ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein hasValue = true; 7526ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 7536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein FieldInfo field = new FieldInfo(name, containingClass, containingClass, 7556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isPublic(), modifiers.isProtected(), 7566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isPackagePrivate(), modifiers.isPrivate(), 7576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isFinal(), modifiers.isStatic(), modifiers.isTransient(), 7586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.isVolatile(), modifiers.isSynthetic(), 7596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein newType, commentAndPosition.getCommentText(), constantValue, 7606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein commentAndPosition.getPosition(), modifiers.getAnnotations()); 7616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein field.setHasValue(hasValue); 7626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein fields.add(field); 763d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 764d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 7656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein child = it.next(); 7666ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 767d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 7686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return fields; 769d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 770d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 771d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 772d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses an expression in the ParseTree to get a constant value. 773d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree the place in the tree to get the constant value. 774d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return the constant value. 775d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 776d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static Object parseExpression(ParseTree tree) { 777d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Object constantValue = null; 778d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder builder = new StringBuilder(); 779d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 780d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein while (!"primary".equals(tree.toString())) { 7816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (tree.getChildCount() > 1) { 7826ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("unaryExpression".equals(tree.toString()) || 7836ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein "unaryExpressionNotPlusMinus".equals(tree.toString())) { 7846ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("selector".equals(tree.getChild(1).toString())) { 7856ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return constantValue; 7866ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 7876ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 7886ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein builder.append(tree.getChild(0)); 7896ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein tree = (ParseTree) tree.getChild(1); 7906ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if ("arrayInitializer".equals(tree.toString())) { 7916ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // TODO - do we wanna parse arrays or just skip it 7926ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return constantValue; 7936ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else { 7946ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return constantValue; 7956ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 7966ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if ("castExpression".equals(tree.toString())) { 7976ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein tree = (ParseTree) tree.getChild(tree.getChildCount()-1); 798d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 799d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein tree = (ParseTree) tree.getChild(0); 800d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 801d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 802d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 803d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("literal".equals(tree.getChild(0).toString())) { 804d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein constantValue = builder.append(tree.getChild(0).getChild(0).toString()).toString(); 805d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if (tree.getChildCount() > 1) { 806d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 807d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append(o.toString()); 808d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 809d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 810d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein constantValue = builder.toString(); 811d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 812d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 813d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return constantValue; 814d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 815d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 816d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 817d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds TypeInfo. Requires that tree points to "type" in the ParseTree. 818d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. type should be the root value. 819d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return A TypeInfo for this type. 820d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 821d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private TypeInfo buildType(ParseTree tree) { 822d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isPrimitive = false; 823d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String dimension = null; 824d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String simpleTypeName = null; 825d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String qualifiedTypeName = null; 826d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo cl = null; 827d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean addResolution = false; 828d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<TypeInfo> typeArguments = null; 829d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 830d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse primitive types - very easy 831d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("primitiveType".equals(tree.getChild(0).toString())) { 832d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein isPrimitive = true; 833d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 834d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein simpleTypeName = tree.getChild(0).getChild(0).toString(); 835d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedTypeName = simpleTypeName; 836d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // any non-primitives 837d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 838d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder builder = new StringBuilder(); 839d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 840d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get the full name of the type 841d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object namePart : ((ParseTree) tree.getChild(0)).getChildren()) { 842d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if we get to typeArguments, aka generics, parse that and bale out 843d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // of building the name 844d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("typeArguments".equals(namePart.toString())) { 845d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein typeArguments = buildTypeVariables((ParseTree) namePart); 846d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein break; 847d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 848d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 849d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append(namePart.toString()); 850d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 851d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 852d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get simple and qualified name 853d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein simpleTypeName = builder.toString(); 854d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder qualifiedTypeNameBuilder = new StringBuilder(); 855d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isGeneric = resolveQualifiedName(simpleTypeName, 856d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedTypeNameBuilder, this); 857d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedTypeName = qualifiedTypeNameBuilder.toString(); 858d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 859d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if we couldn't figure out the qualified name 860d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // tell us we need to resolve this 861d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // can't add the resolution until the TypeInfo has been created 862d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("".equals(qualifiedTypeName)) { 863d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein addResolution = true; 864d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // otherwise, if the name is not a generic, get the class that this Type refers to 865d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if (!isGeneric) { 866d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cl = Caches.obtainClass(qualifiedTypeName); 867d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 868d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 869d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 870d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get the dimensions of this type 871d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein dimension = getDimensions(tree); 872d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 873d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type = new TypeInfo(isPrimitive, dimension, simpleTypeName, qualifiedTypeName, cl); 874d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type.setTypeArguments(typeArguments); 875d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 876d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (addResolution) { 8776ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein addFutureResolution(type, "class", simpleTypeName, this); 878d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 879d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 880d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return type; 881d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 882d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 883d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 884d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Processes the type variables of a class that contains generics. 885d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree Root of the type parameters. 886d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param cls Class in which these type variables are contained. 887d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 888d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ArrayList<TypeInfo> buildTypeVariables(ParseTree tree) { 889d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<TypeInfo> typeVariables = new ArrayList<TypeInfo>(); 890d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<TypeInfo> superBounds = new ArrayList<TypeInfo>(); 891d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<TypeInfo> extendsBounds = new ArrayList<TypeInfo>(); 892d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 893d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 894d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if we're not dealing with a type, skip 895d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // basically gets rid of commas and lessthan and greater than signs 896d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (!o.toString().equals("typeParameter") && 8976ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein !o.toString().equals("typeArgument")) { 898d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 899d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 900d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 901d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree typeParameter = (ParseTree) o; 902d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 903d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type; 904d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if we have a typeArgument and it is not a wildcard 905d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("typeArgument".equals(typeParameter.toString()) && 906d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein !"?".equals(typeParameter.getChild(0).toString())) { 907d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type = buildType((ParseTree) typeParameter.getChild(0)); 908d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 909d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // otherwise, we have a wildcard or parameter 910d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // which can be more vague because of generics 911d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String name = typeParameter.getChild(0).toString(); 912d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 913d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type = new TypeInfo(false, null, name, name, null); 914d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("?".equals(name)) { 915d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type.setIsWildcard(true); 916d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 917d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // add generic 918d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mClassNames.add(name); 919d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 920d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 921d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 922d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if we have an extends or super on our type variable 923d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (typeParameter.getChildCount() > 1) { 924d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree value = (ParseTree) typeParameter.getChild(1); 925d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 926d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("extends".equals(value.toString())) { 927d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein value = (ParseTree) typeParameter.getChild(2); 928d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 929d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // wildcard extends 930d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("type".equals(value.toString())) { 931d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein extendsBounds.add(buildType(value)); 932d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // all other extends 933d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 934d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // will have to handle stuff with typeBound - multiple types 935d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object obj : value.getChildren()) { 936d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("type".equals(obj.toString())) { 937d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein extendsBounds.add(buildType((ParseTree) obj)); 938d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 939d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 940d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 941d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("super".equals(value.toString())) { 942d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein superBounds.add(buildType((ParseTree) typeParameter.getChild(2))); 943d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 944d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 945d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 946d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type.setIsTypeVariable(true); 947d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein type.setBounds(superBounds, extendsBounds); 948d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein typeVariables.add(type); 949d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 950d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 951d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return typeVariables; 952d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 953d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 954d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 955d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a MethodInfo for methods, constructors and annotation elements. 956d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. methodDeclaration, interfaceMethodDeclaration 957d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * or annotationMethodDeclaration should be the root value. 958d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass the class in which this method exists. 959d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param isAnnotation true if the class is an annotation element 960d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return the MethodInfo 961d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 962d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private MethodInfo buildMethod(ParseTree tree, ClassInfo containingClass, 963d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isAnnotation) { 964d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Modifiers modifiers = new Modifiers(this); 965d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = parseCommentAndPosition(tree); 966d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 967d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String name = null; 968d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder flatSignature = new StringBuilder().append('('); 969d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<TypeInfo> typeParameters = null; 970d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ParameterInfo> parameters = new ArrayList<ParameterInfo>(); 971d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> thrownExceptions = new ArrayList<ClassInfo>(); 972d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo returnType = null; 973d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isAnnotationElement = false; 974d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isVarArg = false; 975d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String kind = "method"; // annotationElement, method, or constructor 976d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein AnnotationValueInfo elementValue = null; 977d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<Resolution> pendingResolutions = new ArrayList<Resolution>(); 978d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 979d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 980d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 981d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 982d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 983d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.parseModifiers(child); 984d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 985d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 986d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 987d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // generics stuff 988d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("typeParameters".equals(child.toString())) { 989d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein typeParameters = buildTypeVariables(child); 990d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 991d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 992d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 993d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle returnType if we're not in a constructor 994d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("type".equals(child.toString())) { 995d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein returnType = buildType(child); 996d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 997d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("void".equals(child.toString())) { 998d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein returnType = new TypeInfo(true, null, "void", "void", null); 999d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1000d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1001d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 10026ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // this is the method name 10036ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein name = child.toString(); 1004d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 10056ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (name.equals(containingClass.name())) { 10066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein kind = "constructor"; 1007d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1008d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 10096ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // probably don't need this check any longer since I unrolled the loop 10106ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// if (isConstructorOrMethodName(child)) { 10116ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// // this is the method name 10126ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// name = child.toString(); 10136ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// 10146ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// if (name.equals(containingClass.name())) { 10156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// kind = "constructor"; 10166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// } 10176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein// } 10186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1019d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1020d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1021d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // method parameters 1022d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("formalParameters".equals(child.toString())) { 1023d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein isVarArg = buildMethodParameters(child, parameters, flatSignature); 1024d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 1025d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1026d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1027d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1028d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1029d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein flatSignature.append(')'); 1030d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1031d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle exception throwing 1032d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("throws".equals(child.toString())) { 1033d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1034d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1035d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : child.getChildren()) { 1036d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (",".equals(o.toString())) { 1037d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 1038d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1039d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1040d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get the name of the exception, resolve it and add it to the list 1041d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // unless we can't, in which case, add a resolution 1042d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String exceptionName = buildQualifiedName(((ParseTree) o)); 1043d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder exceptionQualifiedName = new StringBuilder(); 1044d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isGeneric = resolveQualifiedName(exceptionName, 1045d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein exceptionQualifiedName, this); 1046d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1047d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("".equals(exceptionQualifiedName.toString())) { 10486ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein pendingResolutions.add(new Resolution("thrownException", exceptionName, null)); 1049d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if (!isGeneric) { 1050d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein thrownExceptions.add(Caches.obtainClass(exceptionQualifiedName.toString())); 1051d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1052d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1053d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle default values for annotation elements 1054d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("default".equals(child.toString())) { 1055d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1056d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1057d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein elementValue = buildElementValue(child, this); 1058d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1059d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1060d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1061d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (isAnnotation) { 1062d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein kind = "annotationElement"; 1063d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1064d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1065d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // Here we set signature, overridden method to null because 1066d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // MethodInfo figures these values out later on 1067d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein MethodInfo method = new MethodInfo(commentAndPosition.getCommentText(), typeParameters, 1068d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein name, null, containingClass, containingClass, modifiers.isPublic(), 1069d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.isProtected(), modifiers.isPackagePrivate(), 1070d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.isPrivate(), modifiers.isFinal(), 1071d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.isStatic(), modifiers.isSynthetic(), 1072d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.isAbstract(), modifiers.isSynchronized(), 10732e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller false, modifiers.isDefault(), isAnnotationElement, kind, flatSignature.toString(), 1074d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein null, returnType, parameters, thrownExceptions, 1075d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getPosition(), modifiers.getAnnotations()); 1076d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1077d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein method.setVarargs(isVarArg); 1078d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein method.init(elementValue); 1079d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1080d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Resolution r : pendingResolutions) { 10816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein addFutureResolution(method, r.getVariable(), r.getValue(), this); 1082d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1083d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1084d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return method; 1085d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1086d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1087d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1088d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Build the method parameters. 1089d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. formalParamaters should be the root value. 1090d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param parameters List to put the method ParamaterInfos into. 1091d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param flatSignature Pass in a StringBuilder with "(" in it to build the 1092d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * flatSignature of the MethodInfo 1093d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return true if the Method has a VarArgs parameter. false otherwise. 1094d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1095d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean buildMethodParameters(ParseTree tree, 1096d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ParameterInfo> parameters, 1097d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder flatSignature) { 1098d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein boolean isVarArg = false; 1099d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object obj : tree.getChildren()) { 1100d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) obj; 1101d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1102d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("formalParameterDecls".equals(child.toString())) { 1103d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object formalParam : child.getChildren()) { 1104d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree param = (ParseTree) formalParam; 1105d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo type = null; 1106d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1107d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (param.getChildCount() == 0) { 1108d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 1109d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1110d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 11116ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein @SuppressWarnings("unchecked") 11126ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) param.getChildren().iterator(); 11136ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11146ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ParseTree paramPart = it.next(); 11156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("variableModifiers".equals(paramPart.toString())) { 11176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // TODO - handle variable modifiers - final, etc 11186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 11196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein paramPart = it.next(); 1121d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 11226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein type = buildType(paramPart); 1123d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 11246ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein buildSignatureForType(flatSignature, type); 1125d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 11266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (param != child.getChildren().get(child.getChildCount()-1)) { 11276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein flatSignature.append(", "); 11286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 11296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein paramPart = it.next(); 11316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("...".equals(paramPart.toString())) { 11336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein isVarArg = true; 11346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // thank you varargs for only being the last parameter 11356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // you make life so much nicer 11366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein flatSignature.append("..."); 11376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein paramPart = it.next(); 1138d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 11396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String name = paramPart.toString(); 11416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11426ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein CommentAndPosition commentAndPosition = new CommentAndPosition(); 11436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein commentAndPosition.setPosition(paramPart); 11446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 11456ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein parameters.add(new ParameterInfo(name, type.qualifiedTypeName(), type, 11467c80d0e9086eef289d323661977cbfb771d95a2aMorad Abdelrahman isVarArg, commentAndPosition.getPosition(), 11477c80d0e9086eef289d323661977cbfb771d95a2aMorad Abdelrahman Collections.<AnnotationInstanceInfo>emptyList())); 1148d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1149d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1150d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1151d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1152d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return isVarArg; 1153d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1154d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1155d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1156d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a StringBuilder representing the Type, including type arguments. 1157d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param builder StringBuilder in which the Type will be placed. 1158d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param type the TypeInfo to turn into a String. 1159d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1160d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void buildSignatureForType(StringBuilder builder, TypeInfo type) { 1161d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // simple name 1162d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append(type.simpleTypeName()); 1163d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1164d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // generics 1165d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (type.typeArguments() != null && !type.typeArguments().isEmpty()) { 1166d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append('<'); 1167d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (TypeInfo inner : type.typeArguments()) { 1168d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (inner != type.typeArguments().get(0)) { 1169d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append(", "); 1170d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1171d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1172d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // recurse 1173d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein buildSignatureForType(builder, inner); 1174d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1175d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append('>'); 1176d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1177d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1178d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1179d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1180d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a ClassInfo for an enum. 1181d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. enumDeclaration should be the root value. 1182d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass ClassInfo that contains the enum declaration. 1183d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * null if the enum is a root class. 1184d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return the enum as a ClassInfo 1185d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1186d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ClassInfo buildEnum(ParseTree tree, ClassInfo containingClass) { 1187d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = parseCommentAndPosition(tree); 1188d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Modifiers modifiers = new Modifiers(this); 1189d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo cls = null; 1190d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1191d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 1192d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 1193d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1194d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 1195d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1196d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.parseModifiers(child); 1197d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1198d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1199d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1200d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1201d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls = buildClassName(child, containingClass, modifiers, 1202d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getCommentText(), 1203d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getPosition(), ClassType.ENUM); 1204d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 12056ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein child = it.next(); 12066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1207d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // handle implements 1208d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("implements".equals(child.toString())) { 1209d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1210d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1211d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein parseInterfaces(child, cls); 1212d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1213d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1214d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1215d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1216d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein buildEnumBody(child, cls); 1217d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1218d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return cls; 1219d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1220d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1221d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1222d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the body of an enum. 1223d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. enumBody should be the root value. 1224d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass ClassInfo to which this enum body pertains. 1225d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1226d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void buildEnumBody(ParseTree tree, ClassInfo containingClass) { 1227d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 1228d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) o; 1229d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1230d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("enumConstants".equals(child.toString())) { 1231d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o2 : child.getChildren()) { 1232d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree tmp = (ParseTree) o2; 1233d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1234d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("enumConstant".equals(tmp.toString())) { 1235d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein containingClass.addEnumConstant(buildEnumConstant(tmp, containingClass)); 1236d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1237d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1238d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("enumBodyDeclarations".equals(child.toString())) { 1239d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein buildClassBody(child, containingClass); 1240d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1241d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1242d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 1243d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1244d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1245d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1246d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds an enum constant. 1247d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. enumConstant should be the root value. 1248d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass ClassInfo to which this enum constant pertains. 1249d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return 1250d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1251d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private FieldInfo buildEnumConstant(ParseTree tree, ClassInfo containingClass) { 12526ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein @SuppressWarnings("unchecked") 12536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 12546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ParseTree child = it.next(); 12556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 12566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein Modifiers modifiers = new Modifiers(this); 12576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("annotations".equals(child.toString())) { 12586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.parseModifiers(child); 12596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein child = it.next(); 12606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 1261d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 12626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String name = child.toString(); 1263d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = new CommentAndPosition(); 12646ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein commentAndPosition.setCommentText(child); 12656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein commentAndPosition.setPosition(child); 1266d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Object constantValue = null; 1267d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 12686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // get constantValue if it exists 12696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (it.hasNext()) { 12706ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein child = it.next(); 12716ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 12726ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // if we have an expressionList 12736ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (child.getChildCount() == 3) { 12746ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein StringBuilder builder = new StringBuilder(); 12756ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein child = (ParseTree) child.getChild(1); // get the middle child 12766ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 12776ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (Object o : child.getChildren()) { 12786ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if ("expression".equals(o.toString())) { 12796ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein builder.append(parseExpression((ParseTree) o)); 12806ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 12816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (o != child.getChild(child.getChildCount()-1)) { 12826ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein builder.append(", "); 12836ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 12846ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 12856ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 12866ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 12876ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein constantValue = builder.toString(); 12886ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 12896ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 1290d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1291d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return new FieldInfo(name, containingClass, containingClass, containingClass.isPublic(), 1292d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein containingClass.isProtected(), containingClass.isPackagePrivate(), 1293d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein containingClass.isPrivate(), containingClass.isFinal(), 1294d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein containingClass.isStatic(), false, false, false, 1295d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein containingClass.type(), commentAndPosition.getCommentText(), 1296d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein constantValue, commentAndPosition.getPosition(), 12976ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein modifiers.getAnnotations()); 1298d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1299d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1300d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1301d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a ClassInfo for an interface. 1302d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. normalInterfaceDeclaration should be the root value. 1303d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass ClassInfo that contains the interface declaration. 1304d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * null if the interface is a root class. 1305d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return a ClassInfo representing the interface. 1306d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1307d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ClassInfo buildInterface(ParseTree tree, ClassInfo containingClass) { 1308d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 1309d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 1310d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 1311d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1312d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse modifiers and get comment and position 1313d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Modifiers modifiers = new Modifiers(this); 1314d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.parseModifiers(child); 1315d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = parseCommentAndPosition(tree); 1316d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1317d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein it.next(); 1318d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1319d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1320d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get class name 1321d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo iface = buildClassName(child, containingClass, modifiers, 1322d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getCommentText(), 1323d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getPosition(), ClassType.INTERFACE); 1324d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1325d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1326d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1327d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse generics if they exist 1328d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("typeParameters".equals(child.toString())) { 1329d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein iface.type().setTypeArguments(buildTypeVariables(child)); 1330d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1331d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1332d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1333d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse interfaces implemented by this interface 1334d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("extends".equals(child.toString())) { 1335d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1336d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1337d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein parseInterfaces(child, iface); 1338d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1339d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1340d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1341d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1342d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // finally, build the body of the interface 1343d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein buildInterfaceBody(child, iface); 1344d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1345d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return iface; 1346d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1347d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1348d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1349d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the body of the interface, adding it to iface. 1350d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. interfaceBody should be the root value. 1351d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param iface ClassInfo that will contain all of the interface body. 1352d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1353d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void buildInterfaceBody(ParseTree tree, ClassInfo iface) { 1354d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 1355d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (!o.toString().equals("interfaceBodyDeclaration")) { 1356d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 1357d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1358d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1359d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) ((ParseTree) o).getChild(0); 1360d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 13616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (";".equals(child.toString())) { 13626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein continue; 13636ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 13646ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1365d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // field 1366d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("interfaceFieldDeclaration".equals(child.toString())) { 13676ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (FieldInfo f : buildFields(child, iface)) { 13686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein iface.addField(f); 13696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 1370d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // method 1371d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("interfaceMethodDeclaration".equals(child.toString())) { 1372d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein iface.addMethod(buildMethod(child, iface, false)); 1373d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner class 1374d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("normalClassDeclaration".equals(child.getChild(0).toString())) { 1375d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein iface.addInnerClass(buildClass((ParseTree) child.getChild(0), iface)); 1376d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner enum 1377d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("enumDeclaration".equals(child.getChild(0).toString())) { 1378d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein iface.addInnerClass(buildEnum((ParseTree) child.getChild(0), iface)); 1379d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner interface 1380d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("normalInterfaceDeclaration".equals(child.getChild(0).toString())) { 1381d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein iface.addInnerClass(buildInterface((ParseTree) child.getChild(0), iface)); 1382d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner annotation 1383d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("annotationTypeDeclaration".equals(child.getChild(0).toString())) { 1384d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein iface.addInnerClass(buildAnnotationDeclaration( 1385d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein (ParseTree) child.getChild(0), iface)); 1386d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1387d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1388d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1389d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1390d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1391d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds a ClassInfo of an annotation declaration. 1392d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. annotationTypeDeclaration should be the root value. 1393d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param containingClass The class that contains this annotation. 1394d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * null if this is a root annotation. 1395d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return the ClassInfo of the annotation declaration. 1396d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1397d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ClassInfo buildAnnotationDeclaration(ParseTree tree, ClassInfo containingClass) { 1398d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 1399d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 1400d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 1401d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1402d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // get comment and position 1403d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition commentAndPosition = parseCommentAndPosition(tree); 1404d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1405d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // modifiers 1406d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Modifiers modifiers = new Modifiers(this); 1407d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein modifiers.parseModifiers(child); 1408d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1409d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // three calls to next to skip over @, interface and then 1410d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // make child = the name of this annotation 1411d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein it.next(); 1412d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein it.next(); 1413d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1414d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1415d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // build class name and initialize the class 1416d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo annotation = buildClassName(child, containingClass, modifiers, 1417d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getCommentText(), 1418d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein commentAndPosition.getPosition(), ClassType.INTERFACE); 1419d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1420d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = it.next(); 1421d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1422d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // build annotation body 1423d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein buildAnnotationBody(child, annotation); 1424d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1425d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return annotation; 1426d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1427d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1428d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1429d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the body of the annotation declaration. 1430d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. annotationTypeBody should be the root value. 1431d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param annotation the Classinfo in which the annotation elements should be added. 1432d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1433d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private void buildAnnotationBody(ParseTree tree, ClassInfo annotation) { 1434d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : tree.getChildren()) { 1435d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (!"annotationTypeElementDeclaration".equals(o.toString())) { 1436d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 1437d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1438d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1439d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) ((ParseTree) o).getChild(0); 1440d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1441d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // annotation fields 1442d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("interfaceFieldDeclaration".equals(child.toString())) { 14436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (FieldInfo f : buildFields(child, annotation)) { 14446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein annotation.addField(f); 14456ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 1446d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // annotation methods 1447d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("annotationMethodDeclaration".equals(child.toString())) { 1448d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein annotation.addAnnotationElement(buildMethod(child, annotation, true)); 1449d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner class 14506ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if ("normalClassDeclaration".equals(child.toString())) { 14516ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein annotation.addInnerClass(buildClass((ParseTree) child, annotation)); 1452d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // enum 14536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if ("enumDeclaration".equals(child.toString())) { 14546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein annotation.addInnerClass(buildEnum((ParseTree) child, annotation)); 1455d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner interface 14566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if ("normalInterfaceDeclaration".equals(child.toString())) { 14576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein annotation.addInnerClass(buildInterface((ParseTree) child, annotation)); 1458d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // inner annotation 14596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else if ("annotationTypeDeclaration".equals(child.toString())) { 1460d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein annotation.addInnerClass(buildAnnotationDeclaration( 14616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein (ParseTree) child, annotation)); 1462d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1463d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1464d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1465d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1466d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1467d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Build an annotation instance. 1468d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. annotation should be the root value. 1469d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param builder InfoBuilder of this file. 1470d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return The AnnotationInstanceInfo being parsed. 1471d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1472d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static AnnotationInstanceInfo buildAnnotationInstance(ParseTree tree, 1473d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein InfoBuilder builder) { 1474d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unchecked") 1475d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Iterator<ParseTree> it = (Iterator<ParseTree>) tree.getChildren().iterator(); 1476d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1477d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein AnnotationInstanceInfo annotationInstance = new AnnotationInstanceInfo(); 1478d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1479d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein it.next(); 1480d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1481d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse the name, get its full version, and then get the ClassInfo of it, if possible. 1482d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String name = InfoBuilder.buildQualifiedName(it.next()); 1483d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder qualifiedNameBuilder = new StringBuilder(); 1484d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein resolveQualifiedName(name, qualifiedNameBuilder, builder); 1485d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1486d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("".equals(qualifiedNameBuilder.toString())) { 14876ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein addFutureResolution(annotationInstance, "annotationTypeName", name, builder); 14886ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein annotationInstance.setSimpleAnnotationName(name); // TODO - remove once we've completed the parser 1489d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { // can't have generics here so we won't do a test 1490d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein annotationInstance.setClass(Caches.obtainClass(qualifiedNameBuilder.toString())); 1491d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1492d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1493d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // at this point, the annotation is either finished or we have more work to do 1494d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (!it.hasNext()) { 1495d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return annotationInstance; 1496d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1497d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1498d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein it.next(); 1499d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = it.next(); 1500d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1501d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse elementValue pairs 1502d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("elementValuePairs".equals(child.toString())) { 1503d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : child.getChildren()) { 1504d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (!"elementValuePair".equals(o.toString())) { 1505d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein continue; 1506d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1507d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1508d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree inner = (ParseTree) o; 1509d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein MethodInfo element = null; 1510d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String methodName = inner.getChild(0).toString(); 1511d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1512d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // try and look up the MethodInfo for this annotation, if possible 1513d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (annotationInstance.type() != null) { 15146ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (MethodInfo m : annotationInstance.type().annotationElements()) { 15156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (methodName.equals(m.name()) || 15166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein annotationInstance.type().annotationElements().size() == 1) { 1517d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein element = m; 1518d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein break; 1519d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1520d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1521d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1522d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1523d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // go to elementValue 1524d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein AnnotationValueInfo info = buildElementValue( 1525d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein (ParseTree) inner.getChild(2), builder); 1526d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1527d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (element == null) { 15286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein addFutureResolution(info, "element", methodName, builder); 15296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein info.setAnnotationInstanceName(name); 1530d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else { 1531d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein info.setElement(element); 1532d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1533d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1534d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein annotationInstance.addElementValue(info); 1535d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1536d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse element value 1537d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("elementValue".equals(child.toString())) { 1538d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein annotationInstance.addElementValue(buildElementValue(child, builder)); 1539d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1540d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1541d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return annotationInstance; 1542d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1543d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1544d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1545d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Builds the value of the annotation element. 1546d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. elementValue should be the root value. 1547d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param builder InfoBuilder of this file. 1548d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return AnnotationValueInfo representing the elementValue. 1549d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1550d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static AnnotationValueInfo buildElementValue(ParseTree tree, InfoBuilder builder) { 1551d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein AnnotationValueInfo elementValue = new AnnotationValueInfo(); 1552d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Object value = null; 1553d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1554d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // parse some stuff 1555d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String str = tree.getChild(0).toString(); 1556d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("conditionalExpression".equals(str)) { 1557d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein value = parseExpression((ParseTree) tree.getChild(0)); 1558d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("annotation".equals(str)) { 1559d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein value = InfoBuilder.buildAnnotationInstance((ParseTree) tree.getChild(0), builder); 1560d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("elementValueArrayInitializer".equals(str)) { 1561d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ParseTree child = (ParseTree) tree.getChild(0); 1562d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<AnnotationValueInfo> values = new ArrayList<AnnotationValueInfo>(); 1563d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object o : child.getChildren()) { 1564d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("elementValue".equals(o.toString())) { 1565d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein values.add(buildElementValue((ParseTree) o, builder)); 1566d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1567d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1568d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1569d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein value = values; 1570d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1571d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1572d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein elementValue.init(value); 1573d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1574d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return elementValue; 1575d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1576d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1577d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1578d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Get the dimensions of the type, as a String. 1579d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. type should be the root value. 1580d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return A String of the dimensions of the type. 1581d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1582d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private String getDimensions(ParseTree tree) { 1583d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // we only have dimensions if the count is not 1 1584d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (tree.getChildCount() == 1) { 1585d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return null; 1586d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1587d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1588d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder builder = new StringBuilder(); 1589d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1590d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (int i = 1; i < tree.getChildCount(); i++) { 1591d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein builder.append(((ParseTree) tree.getChild(i)).toString()); 1592d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1593d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1594d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return builder.toString(); 1595d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1596d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1597d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1598d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * When we have data that we can't yet parse, save it for later. 1599d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param resolvable Resolvable to which the data refers. 1600d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param variable Variable in the document to which the data refers; 1601d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param value Value for the variable 16026ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * @param builder The InfoBuilder of this file 1603d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 16046ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static void addFutureResolution(Resolvable resolvable, String variable, 16056ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String value, InfoBuilder builder) { 16066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein resolvable.addResolution(new Resolution(variable, value, builder)); 1607d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1608d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Caches.addResolvableToCache(resolvable); 1609d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1610d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1611d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1612d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Turns a short name of a class into the qualified name of a class. 1613d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * StringBuilder will contain an empty string if not found. 1614d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param name the abbreviated name of the class 1615d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param qualifiedClassName the qualified name that will be set if found. 1616d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Unchanged if not found. 1617d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param builder InfoBuilder with all of the file specific information necessary 1618d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * to properly resolve the name. 1619d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return a boolean is returned that will be true if the type is a generic. false otherwise. 1620d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 16216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public static boolean resolveQualifiedName(String name, 1622d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein StringBuilder qualifiedClassName, 1623d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein InfoBuilder builder) { 1624d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // steps to figure out a class's real name 1625d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // check class(es) in this file 16266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 16276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // trying something out. let's see how this works 16286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (name.indexOf('.') != -1) { 16296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein qualifiedClassName.append(name); 16306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return false; 16316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 16326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1633d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // TODO - search since we're now a HashSet 1634d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (String className : builder.getClassNames()) { 1635d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int beginIndex = className.lastIndexOf(".") + 1; 1636d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1637d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (className.substring(beginIndex).equals(name)) { 1638d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedClassName.append(className); 1639d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return qualifiedClassName.toString().equals(name); 1640d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1641d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1642d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1643d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // check package 1644d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo potentialClass = builder.getPackage().getClass(name); 1645d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1646d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (potentialClass != null) { 1647d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedClassName.append(potentialClass.qualifiedName()); 1648d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return qualifiedClassName.toString().equals(name); 1649d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1650d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1651d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein potentialClass = null; 1652d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 16536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String potentialName = null; 16546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // check superclass and interfaces for type 16556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (builder.getRootClass() != null) { 16566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein potentialName = resolveQualifiedNameInInheritedClass(name, builder.getRootClass(), 16576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein builder.getRootClass().containingPackage().name()); 16586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 16596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 16606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (potentialName != null) { 16616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein qualifiedClassName.append(potentialName); 16626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return false; 16636ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 16646ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 16656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1666d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // check class imports - ie, java.lang.String; 1667d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<String> packagesToCheck = new ArrayList<String>(); 1668d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (String imp : builder.getImports()) { 1669d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // +1 to get rid of off by 1 error 1670d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String endOfName = imp.substring(imp.lastIndexOf('.') + 1); 1671d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (endOfName.equals(name) || (name.indexOf('.') != -1 && 1672d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein endOfName.equals( 1673d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein name.substring(0, name.lastIndexOf('.'))))) { 1674d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein qualifiedClassName.append(imp); 1675d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return qualifiedClassName.toString().equals(name); 1676d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if (endOfName.equals("*")) { 1677d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // add package to check 1678d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein packagesToCheck.add(imp.substring(0, imp.lastIndexOf('.'))); 16796ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } else { 16806ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // check inner classes 16816ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ClassInfo cl = Caches.obtainClass(imp); 16826ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String possibleName = resolveQualifiedInnerName(cl.qualifiedName() + "." + name, 16836ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein cl); 16846ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (possibleName != null) { 16856ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein qualifiedClassName.append(possibleName); 16866ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return false; 16876ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 1688d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1689d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1690d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1691d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // check package imports - ie, java.lang.*; 1692d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (String packageName : packagesToCheck) { 1693d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein PackageInfo pkg = Caches.obtainPackage(packageName); 1694d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1695d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo cls = pkg.getClass(name); 1696d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 16976ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cls != null && name.equals(cls.name())) { 16986ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein qualifiedClassName.append(cls.qualifiedName()); 1699d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return qualifiedClassName.toString().equals(name); 1700d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1701d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1702d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // including import's inner classes... 1703d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // check package of imports... 1704d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1705d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // TODO - remove 1706d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // FROM THE JAVADOC VERSION OF THIS FUNCTION 1707d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // Find the specified class or interface within the context of this class doc. 1708d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // Search order: 1) qualified name, 2) nested in this class or interface, 1709d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // 3) in this package, 4) in the class imports, 5) in the package imports. 1710d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // Return the ClassDoc if found, null if not found. 1711d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1712d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return false; 1713d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1714d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 17156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static String resolveQualifiedNameInInheritedClass(String name, ClassInfo cl, 17166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String originalPackage) { 17176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ArrayList<ClassInfo> classesToCheck = new ArrayList<ClassInfo>(); 17186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl != null) { 17196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // if we're in a new package only, check it 17206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.containingPackage() != null && 17216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein !originalPackage.equals(cl.containingPackage().name())) { 17226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // check for new class 17236ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein ClassInfo cls = cl.containingPackage().getClass(name); 17246ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17256ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cls != null && name.equals(cls.name())) { 17266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return cls.name(); 17276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.realSuperclass() != null) { 17316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein classesToCheck.add(cl.realSuperclass()); 17326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.realInterfaces() != null) { 17356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (ClassInfo iface : cl.realInterfaces()) { 17366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein classesToCheck.add(iface); 17376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (ClassInfo cls : classesToCheck) { 17416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String potential = resolveQualifiedNameInInheritedClass(name, cls, originalPackage); 17426ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (potential != null) { 17446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return potential; 17456ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17466ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17476ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17486ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return null; 17496ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17506ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17516ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein private static String resolveQualifiedInnerName(String possibleQualifiedName, ClassInfo cl) { 17526ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (cl.innerClasses() == null) { 17536ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return null; 17546ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (ClassInfo inner : cl.innerClasses()) { 17576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (possibleQualifiedName.equals(inner.qualifiedName())) { 17586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return possibleQualifiedName; 17596ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17606ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17616ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein String name = resolveQualifiedInnerName(possibleQualifiedName + "." + inner.name(), 17626ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein inner); 17636ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17646ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (name != null) { 17656ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return name; 17666ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17676ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17686ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 17696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return null; 17706ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 17716ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 1772d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1773d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the tree, looking for the comment and position. 1774d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. 1775d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @return a CommentAndPosition object containing the comment and position of the element. 1776d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1777d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private CommentAndPosition parseCommentAndPosition(ParseTree tree) { 1778d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Tree child = tree.getChild(0).getChild(0); 1779d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1780d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // three options (modifiers with annotations, modifiers w/o annotations, no modifiers) 1781d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // if there are no modifiers, use tree.getChild(1) 1782d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein // otherwise, dive as deep as possible into modifiers to get to the comment and position. 1783d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = ("<epsilon>".equals(child.toString())) ? tree.getChild(1) : child; 1784d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1785d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein while (child.getChildCount() > 0) { 1786d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein child = child.getChild(0); 1787d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1788d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1789d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommentAndPosition cAndP = new CommentAndPosition(); 1790d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cAndP.setCommentText((ParseTree) child); 1791d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cAndP.setPosition((ParseTree) child); 1792d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return cAndP; 1793d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1794d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1795d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1796d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Private class to facilitate passing the comment and position out of a function. 1797d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1798d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private class CommentAndPosition { 1799d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public String getCommentText() { 1800d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mCommentText; 1801d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1802d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1803d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1804d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the tree to get the commentText and set that value. 1805d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. Should be pointing to the node containing the comment. 1806d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1807d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public void setCommentText(ParseTree tree) { 1808d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (tree.hiddenTokens != null && !tree.hiddenTokens.isEmpty()) { 1809d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mCommentText = ((CommonToken) tree.hiddenTokens.get(0)).getText(); 1810d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1811d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (mCommentText != null) { 1812d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return; 1813d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1814d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1815d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1816d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mCommentText = ""; 1817d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1818d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1819d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public SourcePositionInfo getPosition() { 1820d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mPosition; 1821d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1822d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1823d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1824d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses the tree to get the SourcePositionInfo of the node. 1825d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree The tree to parse. Should be pointing to the node containing the position. 1826d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1827d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public void setPosition(ParseTree tree) { 1828d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein CommonToken token = (CommonToken) tree.payload; 1829d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1830d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int line = token.getLine(); 1831d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int column = token.getCharPositionInLine(); 1832d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String fileName = ((ANTLRFileStream) token.getInputStream()).getSourceName(); 1833d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1834d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mPosition = new SourcePositionInfo(fileName, line, column); 1835d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1836d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1837d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private String mCommentText; 1838d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private SourcePositionInfo mPosition; 1839d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1840d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1841d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1842d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Private class to handle all the possible modifiers to a class/interface/field/anything else. 1843d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1844d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private class Modifiers { 1845d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsPublic = false; 1846d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsProtected = false; 1847d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsPackagePrivate = true; 1848d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsPrivate = false; 1849d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsStatic = false; 1850d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsAbstract = false; 1851d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsFinal = false; 1852d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsTransient = false; 1853d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsVolatile = false; 1854d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsSynthetic = false; 1855d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsSynchronized = false; 1856d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private boolean mIsStrictfp = false; 18572e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller private boolean mIsDefault = false; 1858d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private InfoBuilder mBuilder; 1859d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private ArrayList<AnnotationInstanceInfo> mAnnotations; 1860d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1861d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public Modifiers(InfoBuilder builder) { 1862d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mAnnotations = new ArrayList<AnnotationInstanceInfo>(); 1863d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mBuilder = builder; 1864d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1865d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1866d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1867d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Parses all of the modifiers of any declaration, including annotations. 1868d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * @param tree 1869d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 1870d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public void parseModifiers(ParseTree tree) { 1871d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Object child : tree.getChildren()) { 1872d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein String modifier = child.toString(); 1873d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1874d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ("public".equals(modifier)) { 1875d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsPublic = true; 1876d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsPackagePrivate = false; 1877d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("protected".equals(modifier)) { 1878d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsProtected = true; 1879d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsPackagePrivate = false; 1880d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("private".equals(modifier)) { 1881d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsPrivate = true; 1882d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsPackagePrivate = false; 1883d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("static".equals(modifier)) { 1884d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsStatic = true; 1885d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("abstract".equals(modifier)) { 1886d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsAbstract = true; 1887d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("final".equals(modifier)) { 1888d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsFinal = true; 1889d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("transient".equals(modifier)) { 1890d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsTransient = true; 1891d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("volatile".equals(modifier)) { 1892d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsVolatile = true; 1893d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("synthetic".equals(modifier)) { 1894d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsSynthetic = true; 1895d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("synchronized".equals(modifier)) { 1896d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsSynchronized = true; 1897d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("strictfp".equals(modifier)) { 1898d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mIsStrictfp = true; 18992e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller } else if ("default".equals(modifier)) { 19002e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller mIsDefault = true; 1901d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } else if ("annotation".equals(modifier)) { 1902d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mAnnotations.add(buildAnnotationInstance((ParseTree) child, mBuilder)); 1903d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1904d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1905d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1906d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1907d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isPublic() { 1908d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsPublic; 1909d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1910d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1911d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isProtected() { 1912d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsProtected; 1913d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1914d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1915d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isPackagePrivate() { 1916d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsPackagePrivate; 1917d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1918d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1919d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isPrivate() { 1920d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsPrivate; 1921d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1922d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1923d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isStatic() { 1924d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsStatic; 1925d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1926d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1927d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isAbstract() { 1928d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsAbstract; 1929d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1930d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1931d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isFinal() { 1932d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsFinal; 1933d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1934d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1935d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isTransient() { 1936d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsTransient; 1937d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1938d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1939d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isVolatile() { 1940d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsVolatile; 1941d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1942d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1943d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isSynthetic() { 1944d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsSynthetic; 1945d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1946d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1947d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isSynchronized() { 1948d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsSynchronized; 1949d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1950d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1951d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein @SuppressWarnings("unused") 1952d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public boolean isStrictfp() { 1953d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mIsStrictfp; 1954d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1955d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 19562e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller public boolean isDefault() { 19572e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller return mIsDefault; 19582e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller } 19592e954bda0291245d3dc56ea51ec49ef4ff3e610eNeil Fuller 1960d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public ArrayList<AnnotationInstanceInfo> getAnnotations() { 1961d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mAnnotations; 1962d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1963d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein }; 1964d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1965d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1966d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein /** 1967d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein * Singleton class to store all of the global data amongst every InfoBuilder. 1968d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein */ 19696ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public static class Caches { 1970d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static HashMap<String, PackageInfo> mPackages 1971d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein = new HashMap<String, PackageInfo>(); 1972d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static HashMap<String, ClassInfo> mClasses 1973d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein = new HashMap<String, ClassInfo>(); 1974d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static HashSet<Resolvable> mInfosToResolve 1975d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein = new HashSet<Resolvable>(); 1976d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1977d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public static PackageInfo obtainPackage(String packageName) { 1978d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein PackageInfo pkg = mPackages.get(packageName); 1979d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1980d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (pkg == null) { 1981d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein pkg = new PackageInfo(packageName); 1982d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mPackages.put(packageName, pkg); 1983d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1984d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1985d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return pkg; 1986d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 1987d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 19886ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein /** 19896ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * Gets the ClassInfo from the master list or creates a new one if it does not exist. 19906ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * @param qualifiedClassName Qualified name of the ClassInfo to obtain. 19916ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * @return the ClassInfo 19926ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein */ 1993d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public static ClassInfo obtainClass(String qualifiedClassName) { 1994d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ClassInfo cls = mClasses.get(qualifiedClassName); 1995d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 1996d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (cls == null) { 1997d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cls = new ClassInfo(qualifiedClassName); 1998d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mClasses.put(cls.qualifiedName(), cls); 1999d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2000d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2001d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return cls; 2002d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2003d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 20046ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein /** 20056ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * Gets the ClassInfo from the master list or returns null if it does not exist. 20066ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * @param qualifiedClassName Qualified name of the ClassInfo to obtain. 20076ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein * @return the ClassInfo or null, if the ClassInfo does not exist. 20086ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein */ 20096ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public static ClassInfo getClass(String qualifiedClassName) { 20106ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return mClasses.get(qualifiedClassName); 20116ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 20126ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 2013d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public static void addResolvableToCache(Resolvable resolvable) { 2014d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein mInfosToResolve.add(resolvable); 2015d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2016d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2017d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public static void printResolutions() { 20186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (mInfosToResolve.isEmpty()) { 20196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println("We've resolved everything."); 20206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return; 20216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 20226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 2023d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (Resolvable r : mInfosToResolve) { 2024d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein r.printResolutions(); 2025d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein System.out.println(); 2026d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2027d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 20286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 20296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public static void resolve() { 20306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein HashSet<Resolvable> resolveList = mInfosToResolve; 20316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein mInfosToResolve = new HashSet<Resolvable>(); 20326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 20336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein for (Resolvable r : resolveList) { 20346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein // if we could not resolve everything in this class 20356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein if (!r.resolveResolutions()) { 20366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein mInfosToResolve.add(r); 20376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 20386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 20396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein System.out.println(); 20406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 20416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 2042d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2043d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2044d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public PackageInfo getPackage() { 2045d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mPackage; 2046d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2047d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2048d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public ArrayList<String> getImports() { 2049d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mImports; 2050d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 2051d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 2052d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein public HashSet<String> getClassNames() { 2053d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein return mClassNames; 2054d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein } 20556ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein 20566ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein public ClassInfo getRootClass() { 20576ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein return mRootClass; 20586ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein } 2059d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein} 2060