NPE in UnusedImportsRemover when processing files without definitions.
NPE when a source files contains a package line and at least one
import line but not class nor interface definitions (i.e. empty).
Bug: issue 8566.
(cherry picked from commit 04bc38b5070accc4c86504fc390484c21ded2c33)
Change-Id: Id917eb98e44c28a93fd2da69e3a1d9a23993975b
diff --git a/dev/core/src/com/google/gwt/dev/javac/UnusedImportsRemover.java b/dev/core/src/com/google/gwt/dev/javac/UnusedImportsRemover.java
index 13c9f9b..c269964 100644
--- a/dev/core/src/com/google/gwt/dev/javac/UnusedImportsRemover.java
+++ b/dev/core/src/com/google/gwt/dev/javac/UnusedImportsRemover.java
@@ -1,12 +1,12 @@
/*
* Copyright 2013 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
@@ -174,8 +174,11 @@
}
AccumulateNamesVisitor astVisitor = new AccumulateNamesVisitor();
- for (TypeDeclaration typeDecl : cud.types) {
- typeDecl.traverse(astVisitor, cud.scope);
+
+ if (cud.types != null) {
+ for (TypeDeclaration typeDecl : cud.types) {
+ typeDecl.traverse(astVisitor, cud.scope);
+ }
}
// for some reason JDT does not traverse package annotations even if the traversal started at
diff --git a/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java b/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java
index 3215031..9f6285f 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -15,7 +15,9 @@
*/
package com.google.gwt.dev.javac;
+import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
+import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import java.util.Collection;
import java.util.List;
@@ -42,4 +44,89 @@
units = compile(builders);
assertUnitsCompiled(units);
}
+
+ public void testCompileEmptyFile() throws Exception {
+ assertUnitCompilesWithNoErrors("com.example.Empty",
+ "package com.example;");
+ }
+
+ /**
+ * Test for issue 8566
+ */
+ public void testCompileEmptyFileWithImports() throws Exception {
+ assertUnitCompilesWithNoErrors("com.example.EmptyWithImports",
+ "package com.example;",
+ "import java.util.Collections;");
+ }
+
+ public void testRemoveUnusedImports() throws Exception {
+ // java.util.BlahBlahBlah is imported but does not exist, so it should generate a
+ // compile error if not removed.
+ JdtCompiler.setRemoveUnusedImports(false);
+ assertUnitHasErrors("com.example.UnusedImports",
+ "package com.example;",
+ "import java.util.BlahBlahBlah;",
+ "public class UnusedImports {",
+ "}");
+ JdtCompiler.setRemoveUnusedImports(true);
+ assertUnitCompilesWithNoErrors("com.example.UnusedImports",
+ "package com.example;",
+ "import java.util.BlahBlahBlah;",
+ "public class UnusedImports {",
+ "}");
+ }
+
+ public void testRemoveUnusedStaticImports() throws Exception {
+ // java.util.BlahBlahBlah.Blah is imported but does not exist, so it should generate a
+ // compile error if not removed.
+ JdtCompiler.setRemoveUnusedImports(false);
+ assertUnitHasErrors("com.example.UnusedStaticImports",
+ "package com.example;",
+ "import static java.util.BlahBlahBlah.Blah;",
+ "public class UnusedStaticImports {",
+ "}");
+ // If the imported static exists the it should compile even if unused imports are not removed
+ assertUnitCompilesWithNoErrors("com.example.UnusedStaticImports",
+ "package com.example;",
+ "import static java.lang.Float.valueOf;",
+ "public class UnusedStaticImports {",
+ "}");
+ JdtCompiler.setRemoveUnusedImports(true);
+ assertUnitCompilesWithNoErrors("com.example.UnusedStaticImports",
+ "package com.example;",
+ "import static java.util.BlahBlahBlah.Blah;",
+ "public class UnusedStaticImports {",
+ "}");
+ }
+
+ private void assertUnitCompilesWithNoErrors(String sourceName, String... sourceLines)
+ throws UnableToCompleteException {
+ CompilationUnit unit = compileUnit(sourceName, sourceLines);
+ assertNotNull(unit);
+ assertFalse(unit.isError());
+ }
+
+ private void assertUnitHasErrors(String sourceName, String... sourceLines)
+ throws UnableToCompleteException {
+ CompilationUnit unit = compileUnit(sourceName, sourceLines);
+ assertNotNull(unit);
+ assertTrue(unit.isError());
+ }
+
+ private CompilationUnit compileUnit(String sourceName, String[] sourceLines)
+ throws UnableToCompleteException {
+ MockJavaResource emptySourceFile =
+ JavaResourceBase.createMockJavaResource(sourceName, sourceLines);
+ List<CompilationUnit> units = compile(emptySourceFile);
+ return findUnitBySourceName(sourceName, units);
+ }
+
+ private CompilationUnit findUnitBySourceName(String sourceName, List<CompilationUnit> units) {
+ for (CompilationUnit unit : units) {
+ if (unit.getTypeName().equals(sourceName)) {
+ return unit;
+ }
+ }
+ return null;
+ }
}