blob: 4d762c8234aac4278463cb56ef6b6324715eae5b [file] [log] [blame]
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());
}
}