Revision: 5927 Author: [email protected] Date: Mon Aug 10 08:49:04 2009 Log: Exclude anonymous and local classes from TypeOracle (and changes to tests and callers of CompiledClass.getRealClassType), handle cases where we can't get the source while extracting real parameter names, don't treat annotations and their parameters as referenced types so binary-only annotations can work properly.
http://code.google.com/p/google-web-toolkit/source/detail?r=5927 Modified: /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnit.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/impl/SourceFileCompilationUnit.java /changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java /changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java /changes/jat/ihm/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnit.java Fri Jul 31 16:17:57 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnit.java Mon Aug 10 08:49:04 2009 @@ -16,6 +16,7 @@ package com.google.gwt.dev.javac; import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.core.ext.typeinfo.JRealClassType; import com.google.gwt.dev.asm.ClassReader; import com.google.gwt.dev.asm.Opcodes; import com.google.gwt.dev.asm.commons.EmptyVisitor; @@ -186,10 +187,19 @@ */ enum State { /** - * All internal state is cleared; the unit's source has not yet been - * compiled by JDT. + * A BINARIES unit has not been compiled but has up to date binary files. */ - FRESH, + BINARIES, + /** + * In this final state, the unit has been compiled and is error free. + * Additionally, all other units this unit depends on (transitively) are + * also error free. The unit contains a set of checked CompiledClasses. The + * unit and each contained CompiledClass releases all references to the JDT + * AST. Each class contains a reference to a valid JRealClassType, which has + * been added to the module's TypeOracle, as well as byte code, JSNI + * methods, and all other final state. + */ + CHECKED, /** * In this intermediate state, the unit's source has been compiled by JDT. * The unit will contain a set of CompiledClasses. @@ -202,15 +212,10 @@ */ ERROR, /** - * In this final state, the unit has been compiled and is error free. - * Additionally, all other units this unit depends on (transitively) are - * also error free. The unit contains a set of checked CompiledClasses. The - * unit and each contained CompiledClass releases all references to the JDT - * AST. Each class contains a reference to a valid JRealClassType, which has - * been added to the module's TypeOracle, as well as byte code, JSNI - * methods, and all other final state. + * All internal state is cleared; the unit's source has not yet been + * compiled by JDT. */ - CHECKED, + FRESH, /** * A CHECKED generated unit enters this state at the start of a refresh. If * a generator generates the same unit with identical source, the unit is @@ -218,10 +223,6 @@ * validation, and TypeOracle building. */ GRAVEYARD, - /** - * A BINARIES unit has not been compiled but has up to date binary files. - */ - BINARIES, } private class FindTypesInCud extends ASTVisitor { Map<SourceTypeBinding, CompiledClass> map = new IdentityHashMap<SourceTypeBinding, CompiledClass>(); @@ -297,12 +298,12 @@ */ private Map<String, String> anonymousClassMap = null; + private Set<String> cachedProvidedTypes; + private Set<String> cachedReferencedTypes; private CompilationUnitDeclaration cud; private List<CategorizedProblem> errors; private List<JsniMethod> jsniMethods = null; private State state = State.FRESH; - private Set<String> cachedReferencedTypes; - private Set<String> cachedProvidedTypes; /** * Check if any available binaries are usable. @@ -511,7 +512,8 @@ * <code>null</code>. */ Set<CompiledClass> getCompiledClasses() { - // TODO(jat): push down into subclasses, add binary support + // TODO(jat): push down into subclasses, add binary support here rather + // than in checkBinaries if (!isCompiled()) { return null; } @@ -528,7 +530,7 @@ return errors == null ? null : errors.toArray( new CategorizedProblem[errors.size()]); } - + /** * If compiled, returns the JDT compilation unit declaration; otherwise * <code>null</code>. @@ -536,7 +538,7 @@ CompilationUnitDeclaration getJdtCud() { return cud; } - + /** * @return the set of fully qualified internal class names referenced by this * compilation unit. @@ -658,7 +660,11 @@ } private boolean isAnonymousClass(CompiledClass cc) { - if (!cc.getRealClassType().isLocalType()) { + JRealClassType classType = cc.getRealClassType(); + if (classType == null) { + return true; + } + if (!classType.isLocalType()) { return false; } return isClassnameGenerated(cc.getInternalName()); ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java Wed Jul 8 15:56:20 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java Mon Aug 10 08:49:04 2009 @@ -126,6 +126,13 @@ return nameEnvironmentAnswer; } + /** + * Get the TypeOracle JRealClassType instance associated with this compiled + * class. May be null if the type hasn't been created yet or if no type will + * be created, such as for an anonymous or local class. + * + * @return JRealClassType instance or null if none + */ final JRealClassType getRealClassType() { return realClassType; } ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java Tue Jul 28 21:24:29 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java Mon Aug 10 08:49:04 2009 @@ -468,6 +468,10 @@ List<CategorizedProblem> problems = new ArrayList<CategorizedProblem>(); for (CompiledClass compiledClass : unit.getCompiledClasses()) { JRealClassType type = compiledClass.getRealClassType(); + if (type == null) { + // class not in TypeOracle, such as an anonymous class + continue; + } String typeName = type.getQualifiedSourceName(); // The ASM class visitor we will use, depends on if it is a JSO or not. ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java Fri Jul 31 10:13:46 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java Mon Aug 10 08:49:04 2009 @@ -250,7 +250,15 @@ return null; } TypeDeclaration jdtType = findType(cud, type.getQualifiedBinaryName()); + if (jdtType == null) { + // TODO(jat): any thing else to do here? + return null; + } AbstractMethodDeclaration jdtMethod = findMethod(jdtType, method); + if (jdtMethod == null) { + // TODO(jat): any thing else to do here? + return null; + } int n = jdtMethod.arguments.length; String[] argNames = new String[n]; for (int i = 0; i < n; ++i) { ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java Fri Jul 31 10:13:46 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java Mon Aug 10 08:49:04 2009 @@ -356,8 +356,9 @@ if (unit.getState() == CompilationUnit.State.GRAVEYARD) { for (CompiledClass compiledClass : unit.getCompiledClasses()) { JRealClassType type = compiledClass.getRealClassType(); - assert (type != null); - type.resurrect(); + if (type != null) { + type.resurrect(); + } } continue; } else if (!unit.isCompiled()) { @@ -366,8 +367,9 @@ Set<CompiledClass> compiledClasses = unit.getCompiledClasses(); for (CompiledClass compiledClass : compiledClasses) { CollectClassData cv = processClass(compiledClass); - // TODO(jat): skip anonymous classes - if (true || !cv.isAnonymous()) { + // skip any classes that can't be referenced by name outside of + // their local scope, such as anonymous classes and method-local classes + if (!cv.hasNoExternalName()) { classMap.put(compiledClass.getInternalName(), cv); } } @@ -385,15 +387,17 @@ String internalName = compiledClass.getInternalName(); CollectClassData cv = classMap.get(internalName); if (cv == null) { - // Ignore any we skipped in the first phase + // ignore classes that were skipped earlier continue; } JRealClassType type = compiledClass.getRealClassType(); if (type == null) { type = createType(compiledClass, unresolvedTypes); } - binaryMapper.put(internalName, type); - classMapType.put(type, cv); + if (type != null) { + binaryMapper.put(internalName, type); + classMapType.put(type, cv); + } } } @@ -572,7 +576,14 @@ if (realClassType == null) { CollectClassData classData = classMap.get(compiledClass.getInternalName()); String outerClassName = classData.getOuterClass(); - CollectClassData enclosingClassData = classMap.get(outerClassName); + CollectClassData enclosingClassData = null; + if (outerClassName != null) { + enclosingClassData = classMap.get(outerClassName); + if (enclosingClassData == null) { + // if our enclosing class was skipped, skip this one too + return null; + } + } realClassType = createType(compiledClass, classData, enclosingClassData); unresolvedTypes.add(realClassType); compiledClass.setRealClassType(realClassType); ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java Mon Jul 27 09:35:29 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java Mon Aug 10 08:49:04 2009 @@ -261,6 +261,10 @@ public String getSuperName() { return superName; } + + public boolean hasNoExternalName() { + return classType == ClassType.Anonymous || classType == ClassType.Local; + } public boolean isAnonymous() { return classType == ClassType.Anonymous; ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java Wed Jul 8 15:56:20 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java Mon Aug 10 08:49:04 2009 @@ -127,9 +127,10 @@ @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - addTypeIfClass(desc); - // we don't use visitEnd, so we can just use ourselves for nested visitors - return this; + // don't mark this annotation as a reference or its arguments, so we can + // handle binary-only annotations. + // TODO(jat): consider implications of updating the annotation class + return null; } @Override ======================================= --- /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/impl/SourceFileCompilationUnit.java Fri Jul 31 10:13:46 2009 +++ /changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/impl/SourceFileCompilationUnit.java Mon Aug 10 08:49:04 2009 @@ -207,6 +207,9 @@ @Override public void checkBinaries(TreeLogger logger) { + if (exposedCompiledClasses != null) { + return; + } if (binary != null) { Set<Resource> classFiles = binary.getClassFiles(); Resource[] ordered = classFiles.toArray(new Resource[classFiles.size()]); ======================================= --- /changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java Wed Apr 1 13:03:34 2009 +++ /changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java Mon Aug 10 08:49:04 2009 @@ -377,6 +377,7 @@ } } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -406,6 +407,7 @@ assertNotNull(type.isGenericType()); } + @Override public String getSource() { StringBuilder sb = new StringBuilder(); sb.append("package test.refresh;\n"); @@ -418,10 +420,12 @@ protected CheckedMockCompilationUnit CU_HasSyntaxErrors = new CheckedMockCompilationUnit( "test", "HasSyntaxErrors", "NoSyntaxErrors") { + @Override public void check(JClassType classInfo) { fail("This class should have been removed"); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -433,10 +437,12 @@ protected CheckedMockCompilationUnit CU_HasUnresolvedSymbols = new CheckedMockCompilationUnit( "test", "Invalid", "Valid") { + @Override public void check(JClassType classInfo) { fail("Both classes should have been removed"); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -449,31 +455,22 @@ protected CheckedMockCompilationUnit CU_LocalClass = new CheckedMockCompilationUnit( "test", "Enclosing", "Enclosing.1") { + @Override public void check(JClassType type) { final String name = type.getSimpleSourceName(); - if ("Enclosing".equals(name)) { - checkEnclosing(type); - } else { - checkLocal(type); - } + assertEquals("Enclosing", name); + checkEnclosing(type); } public void checkEnclosing(JClassType type) { assertEquals("Enclosing", type.getSimpleSourceName()); assertEquals("test.Enclosing", type.getQualifiedSourceName()); + // verify the anonymous class doesn't show up JClassType[] nested = type.getNestedTypes(); - assertEquals(1, nested.length); - JClassType inner = nested[0]; - assertEquals("test.Enclosing.1", inner.getQualifiedSourceName()); + assertEquals(0, nested.length); } - public void checkLocal(JClassType type) { - assertEquals("1", type.getSimpleSourceName()); - assertEquals("test.Enclosing.1", type.getQualifiedSourceName()); - assertEquals("test.Enclosing", - type.getEnclosingType().getQualifiedSourceName()); - } - + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -489,6 +486,7 @@ protected CheckedMockCompilationUnit CU_MethodsAndParams = new CheckedMockCompilationUnit( "test", "Methods") { + @Override public void check(JClassType type) throws NotFoundException { TypeOracle tio = type.getOracle(); JMethod[] methods = type.getMethods(); @@ -544,6 +542,7 @@ assertEquals(0, thrownTypes.length); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -561,11 +560,13 @@ protected CheckedMockCompilationUnit CU_Object = new CheckedMockCompilationUnit( "java.lang", "Object") { + @Override public void check(JClassType type) { assertEquals("Object", type.getSimpleSourceName()); assertEquals("java.lang.Object", type.getQualifiedSourceName()); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package java.lang;"); @@ -577,6 +578,7 @@ protected CheckedMockCompilationUnit CU_OuterInner = new CheckedMockCompilationUnit( "test", "Outer", "Outer.Inner") { + @Override public void check(JClassType type) { final String name = type.getSimpleSourceName(); if ("Outer".equals(name)) { @@ -602,6 +604,7 @@ assertEquals("test.Outer.Inner", inner.getQualifiedSourceName()); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -620,6 +623,7 @@ type.getQualifiedSourceName()); } + @Override public String getSource() { StringBuilder sb = new StringBuilder(); sb.append("package test.refresh;\n"); @@ -639,6 +643,7 @@ assertNotNull(intfs[0].isParameterized()); } + @Override public String getSource() { StringBuilder sb = new StringBuilder(); sb.append("package parameterized.type.build.dependency;\n"); @@ -650,10 +655,12 @@ protected CheckedMockCompilationUnit CU_RefsInfectedCompilationUnit = new CheckedMockCompilationUnit( "test", "RefsInfectedCompilationUnit") { + @Override public void check(JClassType classInfo) { fail("This class should should have been removed because it refers to a class in another compilation unit that had problems"); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package test;\n"); @@ -664,11 +671,13 @@ protected CheckedMockCompilationUnit CU_Throwable = new CheckedMockCompilationUnit( "java.lang", "Throwable") { + @Override public void check(JClassType type) { assertEquals("Throwable", type.getSimpleSourceName()); assertEquals("java.lang.Throwable", type.getQualifiedSourceName()); } + @Override public String getSource() { StringBuffer sb = new StringBuffer(); sb.append("package java.lang;"); @@ -813,12 +822,13 @@ assertEquals(3, types.length); } + // Check that anonymous classes are not reflected in TypeOracle public void testLocal() throws TypeOracleException { units.add(CU_Object); units.add(CU_LocalClass); compileAndRefresh(); JClassType[] types = typeOracle.getTypes(); - assertEquals(3, types.length); + assertEquals(2, types.length); } public void testMethodsAndParams() throws TypeOracleException { ======================================= --- /changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java Wed Jul 8 15:56:20 2009 +++ /changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java Mon Aug 10 08:49:04 2009 @@ -64,7 +64,7 @@ CollectReferencesVisitor rv = collect(Full.class); Set<String> referencedTypes = rv.getReferencedTypes(); assertDoesNotContainNull(referencedTypes); - assertEquals(9, referencedTypes.size()); + assertEquals(7, referencedTypes.size()); assertContainsInternalName(Object.class, referencedTypes); assertContainsInternalName(CollectReferencesVisitorTest.class, referencedTypes); @@ -73,8 +73,11 @@ assertContainsInternalName(Integer.class, referencedTypes); assertContainsInternalName(String.class, referencedTypes); assertContainsInternalName(Boolean.class, referencedTypes); - assertContainsInternalName(Double.class, referencedTypes); - assertContainsInternalName(TestAnnotation.class, referencedTypes); + // We no longer collect references from annotations to allow for + // binary-only annotations and nontranslatable things like File mentioned + // in the annotation + // assertContainsInternalName(Double.class, referencedTypes); + // assertContainsInternalName(TestAnnotation.class, referencedTypes); } // ASM passes null for Object's superclass, so we make sure we don't ======================================= --- /changes/jat/ihm/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java Fri Apr 17 14:15:58 2009 +++ /changes/jat/ihm/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java Mon Aug 10 08:49:04 2009 @@ -697,16 +697,6 @@ code.append("}\n"); units.add(createMockCompilationUnit("NotSerializable", code)); } - - { - StringBuilder code = new StringBuilder(); - code.append("import java.io.Serializable;\n"); - code.append("public class AutoSerializable {\n"); - code.append(" interface IFoo extends Serializable {};\n"); - code.append(" IFoo createFoo() { return new IFoo(){};}\n"); - code.append("}\n"); - units.add(createMockCompilationUnit("AutoSerializable", code)); - } { StringBuilder code = new StringBuilder(); @@ -807,12 +797,6 @@ assertFalse(sob.shouldConsiderFieldsForSerialization(notSerializable, problems)); - // Local types should not qualify for serialization - JClassType iFoo = to.getType("AutoSerializable.IFoo"); - problems = new ProblemReport(); - assertFalse(sob.shouldConsiderFieldsForSerialization( - iFoo.getSubtypes()[0], problems)); - // Static nested types qualify for serialization JClassType staticNested = to.getType("OuterClass.StaticNested"); problems = new ProblemReport(); @@ -862,10 +846,8 @@ problems = new ProblemReport(); assertTrue(sob.shouldConsiderFieldsForSerialization( enumWithSubclasses, problems)); - - problems = new ProblemReport(); - assertFalse(sob.shouldConsiderFieldsForSerialization( - enumWithSubclasses.getSubtypes()[0], problems)); + // There are no longer any enum subclasses in TypeOracle + assertEquals(0, enumWithSubclasses.getSubtypes().length); // Enum that are not default instantiable should qualify JClassType enumWithNonDefaultCtors = to.getType("EnumWithNonDefaultCtors"); --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
