Skip to content

Commit

Permalink
Fix bug where testing a package-info.java file with parsesAs() th…
Browse files Browse the repository at this point in the history
…rew an NPE.

Fixes #85.

RELNOTES=Fixed bug where testing `package-info.java` with `parsesAs()` threw an NPE.
PiperOrigin-RevId: 375541051
  • Loading branch information
netdpb authored and Compile-Testing Team committed May 24, 2021
1 parent b6b54cd commit c46b1b6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 16 deletions.
4 changes: 1 addition & 3 deletions src/main/java/com/google/testing/compile/TypeEnumerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;

import java.util.Set;

/**
Expand Down Expand Up @@ -100,7 +98,7 @@ public Set<String> visitCompilationUnit(CompilationUnitTree reference, Void v) {
"package identifier. Found " + packageSet);
}
final String packageName = packageSet.isEmpty() ? "" : packageSet.iterator().next();
Set<String> typeDeclSet = scan(reference.getTypeDecls(), v);
Set<String> typeDeclSet = firstNonNull(scan(reference.getTypeDecls(), v), ImmutableSet.of());
return FluentIterable.from(typeDeclSet)
.transform(new Function<String, String>() {
@Override public String apply(String typeName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,16 @@ public void generatedSourceFile() {
GeneratingProcessor.GENERATED_CLASS_NAME, GeneratingProcessor.GENERATED_SOURCE));
}

@Test
public void generatedSourceFile_packageInfo() {
GeneratingProcessor generatingProcessor = new GeneratingProcessor("test");
assertThat(javac().withProcessors(generatingProcessor).compile(HELLO_WORLD_RESOURCE))
.generatedSourceFile("test.package-info")
.hasSourceEquivalentTo(
JavaFileObjects.forSourceString(
"test.package-info", generatingProcessor.generatedPackageInfoSource()));
}

@Test
public void generatedSourceFile_fail() {
expectFailure
Expand Down
36 changes: 23 additions & 13 deletions src/test/java/com/google/testing/compile/GeneratingProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
Expand All @@ -29,6 +30,7 @@
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;

final class GeneratingProcessor extends AbstractProcessor {
static final String GENERATED_CLASS_NAME = "Blah";
Expand All @@ -50,31 +52,33 @@ final class GeneratingProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
Filer filer = processingEnv.getFiler();
try (Writer writer = filer.createSourceFile(generatedClassName()).openWriter()) {
writer.write(GENERATED_SOURCE);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
write(filer.createSourceFile(generatedClassName()), GENERATED_SOURCE);
write(
filer.createResource(
CLASS_OUTPUT, getClass().getPackage().getName(), GENERATED_RESOURCE_NAME),
GENERATED_RESOURCE);

try (Writer writer =
filer
.createResource(
CLASS_OUTPUT, getClass().getPackage().getName(), GENERATED_RESOURCE_NAME)
.openWriter()) {
writer.write(GENERATED_RESOURCE);
if (!packageName.isEmpty()) {
write(filer.createSourceFile(packageName + ".package-info"), generatedPackageInfoSource());
}
} catch (IOException e) {
throw new RuntimeException(e);
throw new UncheckedIOException(e);
}
}

String packageName() {
return packageName;
}

String generatedClassName() {
return packageName.isEmpty() ? GENERATED_CLASS_NAME : packageName + "." + GENERATED_CLASS_NAME;
}

String generatedPackageInfoSource() {
return "package " + packageName + ";\n";
}

@CanIgnoreReturnValue
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Expand All @@ -90,4 +94,10 @@ public Set<String> getSupportedAnnotationTypes() {
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}

private static void write(FileObject file, String contents) throws IOException {
try (Writer writer = file.openWriter()) {
writer.write(contents);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,19 @@ public void generatesSources() {
GeneratingProcessor.GENERATED_CLASS_NAME, GeneratingProcessor.GENERATED_SOURCE));
}

@Test
public void generatesSources_packageInfo() {
GeneratingProcessor generatingProcessor = new GeneratingProcessor("test.generated");
assertAbout(javaSource())
.that(HELLO_WORLD_RESOURCE)
.processedWith(generatingProcessor)
.compilesWithoutError()
.and()
.generatesSources(
JavaFileObjects.forSourceString(
"test.generated.package-info", generatingProcessor.generatedPackageInfoSource()));
}

@Test
public void generatesSources_failOnUnexpected() {
String failingExpectationSource = "abstract class Blah {}";
Expand Down

0 comments on commit c46b1b6

Please sign in to comment.