1) Util.maybeDumpSource() has structured error output now (which makes testing easier) and insists on a typeName. 2) TypeOracleBuilder fixed to provide that typeName. 3) TypeOracleTestingUtils factored out of JSORestrictionsTest to make generic utility methods. 4) JSORestrictionsTest now uses UnitTestTreeLogger rather than handrolled logger. Patch by: spoon, scottb (pair prog) git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2216 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java b/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java index 77592a6..48b2ac4 100644 --- a/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java +++ b/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
@@ -420,7 +420,8 @@ String fileName = CharOperation.charToString(cud.getFileName()); char[] source = cud.compilationResult.compilationUnit.getContents(); - Util.maybeDumpSource(logger, fileName, source, null); + Util.maybeDumpSource(logger, fileName, source, + String.valueOf(cud.getMainTypeName())); logger.log(TreeLogger.TRACE, "Removing problematic compilation unit '" + fileName + "'", null); }
diff --git a/dev/core/src/com/google/gwt/dev/util/Util.java b/dev/core/src/com/google/gwt/dev/util/Util.java index 42d2baa..42bfaf4 100644 --- a/dev/core/src/com/google/gwt/dev/util/Util.java +++ b/dev/core/src/com/google/gwt/dev/util/Util.java
@@ -541,37 +541,35 @@ /** * Give the developer a chance to see the in-memory source that failed. */ - public static String maybeDumpSource(TreeLogger logger, String location, - char[] source, String optionalTypeName) { + public static void maybeDumpSource(TreeLogger logger, String location, + char[] source, String typeName) { if (isCompilationUnitOnDisk(location)) { // Don't write another copy. - // - return null; + return; + } + + TreeLogger branch = logger.branch(TreeLogger.ERROR, + "Compilation problem due to '" + location + "'", null); + if (!branch.isLoggable(TreeLogger.INFO)) { + // Don't bother dumping source if they can't see the related message. + return; } File tmpSrc; Throwable caught = null; try { - String prefix = "gen"; - if (optionalTypeName != null) { - prefix = optionalTypeName; - } - tmpSrc = File.createTempFile(prefix, ".java"); + tmpSrc = File.createTempFile(typeName, ".java"); writeCharsAsFile(logger, tmpSrc, source); String dumpPath = tmpSrc.getAbsolutePath(); - logger.log(TreeLogger.ERROR, "Compilation problem due to '" + location - + "'; see snapshot " + dumpPath, null); - return dumpPath; + branch.log(TreeLogger.INFO, "See snapshot: " + dumpPath, null); + return; } catch (IOException e) { caught = e; } catch (UnableToCompleteException e) { caught = e; } - logger.log(TreeLogger.ERROR, - "Compilation problem due to in-memory source '" + location - + "', but unable to dump to disk", caught); - return null; + branch.log(TreeLogger.INFO, "Unable to dump source to disk", caught); } public static byte[] readFileAsBytes(File file) {
diff --git a/dev/core/test/com/google/gwt/dev/jdt/JSORestrictionsTest.java b/dev/core/test/com/google/gwt/dev/jdt/JSORestrictionsTest.java index 24da3e1..b4c8cde 100644 --- a/dev/core/test/com/google/gwt/dev/jdt/JSORestrictionsTest.java +++ b/dev/core/test/com/google/gwt/dev/jdt/JSORestrictionsTest.java
@@ -17,8 +17,7 @@ import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.dev.jdt.StaticCompilationUnitProvider; -import com.google.gwt.dev.jdt.TypeOracleBuilder; +import com.google.gwt.dev.util.UnitTestTreeLogger; import junit.framework.TestCase; @@ -148,50 +147,6 @@ + JSORestrictionsChecker.ERR_OVERRIDDEN_METHOD); } - private void addStandardCups(TypeOracleBuilder builder) - throws UnableToCompleteException { - StringBuffer code = new StringBuffer(); - code.append("package java.lang;\n"); - code.append("public class Object {\n"); - code.append(" public String toString() { return \"Object\"; }\n"); - code.append(" public Object clone() { return this; } "); - code.append("}\n"); - - StaticCompilationUnitProvider objectCup = new StaticCompilationUnitProvider( - "java.lang", "Object", code.toString().toCharArray()); - - code.setLength(0); - code.append("package java.lang;\n"); - code.append("public final class String {\n"); - code.append(" public int length() { return 0; }\n"); - code.append("}\n"); - - StaticCompilationUnitProvider stringCup = new StaticCompilationUnitProvider( - "java.lang", "String", code.toString().toCharArray()); - - code.setLength(0); - code.append("package java.lang;\n"); - code.append("public interface Serializable { }\n"); - - StaticCompilationUnitProvider serializableCup = new StaticCompilationUnitProvider( - "java.lang", "Serializable", code.toString().toCharArray()); - - code.setLength(0); - code.append("package com.google.gwt.core.client;\n"); - code.append("public class JavaScriptObject {\n"); - code.append(" protected JavaScriptObject() { }\n"); - code.append("}\n"); - - StaticCompilationUnitProvider jsoCup = new StaticCompilationUnitProvider( - "com.google.gwt.core.client", "JavaScriptObject", - code.toString().toCharArray()); - - builder.addCompilationUnit(objectCup); - builder.addCompilationUnit(stringCup); - builder.addCompilationUnit(serializableCup); - builder.addCompilationUnit(jsoCup); - } - /** * Test that when compiling buggyCode, the TypeOracleBuilder emits * expectedError somewhere in its output. The code should define a class named @@ -199,35 +154,14 @@ */ private void shouldGenerateError(CharSequence buggyCode, final String expectedError) throws UnableToCompleteException { - TypeOracleBuilder builder = new TypeOracleBuilder(); - addStandardCups(builder); - - StaticCompilationUnitProvider buggyCup = new StaticCompilationUnitProvider( - "", "Buggy", buggyCode.toString().toCharArray()); - builder.addCompilationUnit(buggyCup); - - final boolean[] gotExpectedError = new boolean[1]; - - TreeLogger testLogger = new TreeLogger() { - public TreeLogger branch(Type type, String msg, Throwable caught) { - return this; - } - - public boolean isLoggable(Type type) { - return type == ERROR; - } - - public void log(Type type, String msg, Throwable caught) { - if (type == ERROR && msg.startsWith("Line ")) { - assertEquals(null, caught); - assertEquals(expectedError, msg); - gotExpectedError[0] = true; - } - } - }; - - builder.build(testLogger); - assertTrue("Failed to get expected error: '" + expectedError + "'", - gotExpectedError[0]); + UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder(); + builder.setLowestLogLevel(TreeLogger.ERROR); + builder.expectError("Errors in \'transient source for Buggy\'", null); + builder.expectError(expectedError, null); + builder.expectError( + "Compilation problem due to \'transient source for Buggy\'", null); + UnitTestTreeLogger logger = builder.createLogger(); + TypeOracleTestingUtils.buildTypeOracleForCode("Buggy", buggyCode, logger); + logger.assertCorrectLogEntries(); } }
diff --git a/dev/core/test/com/google/gwt/dev/jdt/TypeOracleTestingUtils.java b/dev/core/test/com/google/gwt/dev/jdt/TypeOracleTestingUtils.java new file mode 100644 index 0000000..a3263b0 --- /dev/null +++ b/dev/core/test/com/google/gwt/dev/jdt/TypeOracleTestingUtils.java
@@ -0,0 +1,104 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.dev.jdt; + +import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.core.ext.UnableToCompleteException; + +/** + * Utilities for tests that build a type oracle and watch for errors. + * + */ +public class TypeOracleTestingUtils { + + public static void addCup(TypeOracleBuilder builder, String typeName, + CharSequence code) throws UnableToCompleteException { + String packageName; + String className; + int pos = typeName.lastIndexOf('.'); + if (pos >= 0) { + packageName = typeName.substring(0, pos); + className = typeName.substring(pos + 1); + } else { + packageName = ""; + className = typeName; + } + StaticCompilationUnitProvider cup = new StaticCompilationUnitProvider( + packageName, className, code.toString().toCharArray()); + builder.addCompilationUnit(cup); + } + + /** + * Add compilation units for basic classes like Object and String. + */ + public static void addStandardCups(TypeOracleBuilder builder) + throws UnableToCompleteException { + { + StringBuffer code = new StringBuffer(); + code.append("package java.lang;\n"); + code.append("public class Object {\n"); + code.append(" public String toString() { return \"Object\"; }\n"); + code.append(" public Object clone() { return this; } "); + code.append("}\n"); + addCup(builder, "java.lang.Object", code); + } + { + StringBuffer code = new StringBuffer(); + code.append("package java.lang;\n"); + code.append("public final class String {\n"); + code.append(" public int length() { return 0; }\n"); + code.append("}\n"); + addCup(builder, "java.lang.String", code); + } + { + StringBuffer code = new StringBuffer(); + code.append("package java.lang;\n"); + code.append("public interface Serializable { }\n"); + addCup(builder, "java.lang.Serializable", code); + } + { + StringBuffer code = new StringBuffer(); + code.append("package java.lang;\n"); + code.append("public @interface SuppressWarnings {\n"); + code.append(" String[] value();\n"); + code.append("}\n"); + addCup(builder, "java.lang.SuppressWarnings", code); + } + { + StringBuffer code = new StringBuffer(); + code.append("package java.lang.annotation;\n"); + code.append("public interface Annotation {\n"); + code.append("}\n"); + addCup(builder, "java.lang.annotation.Annotation", code); + } + { + StringBuffer code = new StringBuffer(); + code.append("package com.google.gwt.core.client;\n"); + code.append("public class JavaScriptObject {\n"); + code.append(" protected JavaScriptObject() { }\n"); + code.append("}\n"); + addCup(builder, "com.google.gwt.core.client.JavaScriptObject", code); + } + } + + public static void buildTypeOracleForCode(String typeName, CharSequence code, + TreeLogger testLogger) throws UnableToCompleteException { + TypeOracleBuilder builder = new TypeOracleBuilder(); + addStandardCups(builder); + addCup(builder, typeName, code); + builder.build(testLogger); + } +}