| |
| package com.google.gwt.dev.javac; |
| |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.core.ext.typeinfo.TypeOracle; |
| import com.google.gwt.core.ext.typeinfo.TypeOracleException; |
| import java.io.IOException; |
| |
| public class TypeOracleMediatorFromSourceTest extends |
| TypeOracleMediatorTestBase { |
| |
| protected CheckedJavaResource CU_HasSyntaxErrors = new CheckedJavaResource( |
| "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"); |
| sb.append("class NoSyntaxErrors { }\n"); |
| sb.append("public class HasSyntaxErrors { a syntax error }\n"); |
| return sb.toString(); |
| } |
| }; |
| |
| protected CheckedJavaResource CU_HasUnresolvedSymbols = new CheckedJavaResource( |
| "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 " + getPackageName() + ";\n"); |
| sb.append("public class Invalid extends NoSuchClass { }\n"); |
| sb.append("class Valid extends Object { }\n"); |
| return sb.toString(); |
| } |
| }; |
| |
| protected CheckedJavaResource CU_RefsInfectedCompilationUnit = new CheckedJavaResource( |
| "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"); |
| sb.append("public class RefsInfectedCompilationUnit extends Valid { }\n"); |
| return sb.toString(); |
| } |
| }; |
| |
| /** |
| * Tests that refreshing with a unit that has errors does not cause new units |
| * that reference unchanged units to be removed. The strategy is to add some |
| * good units that reference each other and build a {@link TypeOracle}. Then |
| * we add some new units that have errors as well as some units that reference |
| * old units which did not have errors. This ensures that the correct units |
| * are pruned from the type oracle in the case where we encounter units with |
| * errors. |
| * |
| * @throws UnableToCompleteException |
| * @throws IOException |
| */ |
| public void testRefreshWithErrors() throws TypeOracleException { |
| // Add Object |
| StringBuffer sb = new StringBuffer(); |
| sb.append("package java.lang;"); |
| sb.append("public class Object { }"); |
| addResource("java.lang.Object", sb); |
| |
| // Add UnmodifiedClass that will never change. |
| sb = new StringBuffer(); |
| sb.append("package test.refresh.with.errors;"); |
| sb.append("public class UnmodifiedClass { }"); |
| addResource("test.refresh.with.errors.UnmodifiedClass", sb); |
| |
| // Add GoodClass that references a class that will go bad. |
| sb = new StringBuffer(); |
| sb.append("package test.refresh.with.errors;\n"); |
| sb.append("public class GoodClass {\n"); |
| sb.append(" ClassThatWillGoBad ctwgb;\n"); |
| sb.append("}\n"); |
| addResource("test.refresh.with.errors.GoodClass", sb); |
| |
| // Add ClassThatWillGoBad that goes bad on the next refresh. |
| MutableJavaResource unitThatWillGoBad = new MutableJavaResource( |
| "test.refresh.with.errors", |
| "test.refresh.with.errors.ClassThatWillGoBad") { |
| |
| private String source = "package test.refresh.with.errors;\n" |
| + "public class ClassThatWillGoBad { }\n"; |
| |
| @Override |
| public String getSource() { |
| return source; |
| } |
| |
| @Override |
| public void touch() { |
| super.touch(); |
| source = "This will cause a syntax error."; |
| } |
| }; |
| |
| resources.add(unitThatWillGoBad); |
| |
| buildTypeOracle(); |
| |
| assertNotNull(typeOracle.findType("test.refresh.with.errors.UnmodifiedClass")); |
| assertNotNull(typeOracle.findType("test.refresh.with.errors.GoodClass")); |
| assertNotNull(typeOracle.findType("test.refresh.with.errors.ClassThatWillGoBad")); |
| |
| // Add AnotherGoodClass that references a |
| // class that was not recompiled. |
| sb = new StringBuffer(); |
| sb.append("package test.refresh.with.errors;\n"); |
| sb.append("public class AnotherGoodClass {\n"); |
| sb.append(" UnmodifiedClass uc; // This will cause the runaway pruning.\n"); |
| sb.append("}\n"); |
| addResource("test.refresh.with.errors.AnotherGoodClass", sb); |
| |
| // Add BadClass that has errors and originally |
| // forced issue 2238. |
| sb = new StringBuffer(); |
| sb.append("package test.refresh.with.errors;\n"); |
| sb.append("public class BadClass {\n"); |
| sb.append(" This will trigger a syntax error.\n"); |
| sb.append("}\n"); |
| addResource("test.refresh.with.errors.BadClass", sb); |
| |
| // Now this cup should cause errors. |
| unitThatWillGoBad.touch(); |
| |
| buildTypeOracle(); |
| |
| assertNotNull(typeOracle.findType("test.refresh.with.errors.UnmodifiedClass")); |
| assertNotNull(typeOracle.findType("test.refresh.with.errors.AnotherGoodClass")); |
| assertNull(typeOracle.findType("test.refresh.with.errors.BadClass")); |
| assertNull(typeOracle.findType("test.refresh.with.errors.ClassThatWillGoBad")); |
| assertNull(typeOracle.findType("test.refresh.with.errors.GoodClass")); |
| } |
| |
| public void testSyntaxErrors() throws TypeOracleException { |
| resources.add(CU_Object); |
| resources.add(CU_HasSyntaxErrors); |
| buildTypeOracle(); |
| JClassType[] types = typeOracle.getTypes(); |
| // Only java.lang.Object should remain. |
| // |
| assertEquals(1, types.length); |
| assertEquals("java.lang.Object", types[0].getQualifiedSourceName()); |
| } |
| |
| public void testUnresolvedSymbols() throws TypeOracleException { |
| resources.add(CU_Object); |
| resources.add(CU_HasUnresolvedSymbols); |
| resources.add(CU_RefsInfectedCompilationUnit); |
| buildTypeOracle(); |
| JClassType[] types = typeOracle.getTypes(); |
| // Only java.lang.Object should remain. |
| // |
| assertEquals(1, types.length); |
| assertEquals("java.lang.Object", types[0].getQualifiedSourceName()); |
| } |
| |
| @Override |
| protected void buildTypeOracle() throws TypeOracleException { |
| typeOracle = TypeOracleTestingUtils.buildTypeOracle(createTreeLogger(), |
| resources); |
| checkTypes(typeOracle.getTypes()); |
| } |
| } |