8050979: Provide javadoc for "framework" classes in langtools tests

Reviewed-by: jjg
This commit is contained in:
Andrey Nazarov 2014-07-24 15:12:48 -07:00
parent 5ef8c4ff63
commit 0f64892089
3 changed files with 104 additions and 21 deletions

View file

@ -36,14 +36,26 @@ import java.util.stream.Stream;
import static java.lang.String.format; import static java.lang.String.format;
import static java.util.stream.Collectors.*; import static java.util.stream.Collectors.*;
/**
* Base class for LocalVariableTable and LocalVariableTypeTable attributes tests.
* To add tests cases you should extend this class.
* Then implement {@link #getVariableTables} to get LocalVariableTable or LocalVariableTypeTable attribute.
* Then add method with local variables.
* Finally, annotate method with information about expected variables and their types
* by several {@link LocalVariableTestBase.ExpectedLocals} annotations.
* To run test invoke {@link #test()} method.
* If there are variables with the same name, set different scopes for them.
*
* @see #test()
*/
public abstract class LocalVariableTestBase extends TestBase { public abstract class LocalVariableTestBase extends TestBase {
public static final int DEFAULT_SCOPE = 0; public static final int DEFAULT_SCOPE = 0;
private final ClassFile classFile; private final ClassFile classFile;
private final Class<?> clazz; private final Class<?> clazz;
protected abstract List<VariableTable> getVariableTables(Code_attribute codeAttribute); /**
* @param clazz class to test. Must contains annotated methods with expected results.
*/
public LocalVariableTestBase(Class<?> clazz) { public LocalVariableTestBase(Class<?> clazz) {
this.clazz = clazz; this.clazz = clazz;
try { try {
@ -53,8 +65,12 @@ public abstract class LocalVariableTestBase extends TestBase {
} }
} }
protected abstract List<VariableTable> getVariableTables(Code_attribute codeAttribute);
//info in the LocalVariableTable attribute is compared against expected info stored in annotations /**
* Finds expected variables with their type in VariableTable.
* Also does consistency checks, like variables from the same scope must point to different indexes.
*/
public void test() throws IOException { public void test() throws IOException {
List<java.lang.reflect.Method> testMethods = Stream.of(clazz.getDeclaredMethods()) List<java.lang.reflect.Method> testMethods = Stream.of(clazz.getDeclaredMethods())
.filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0) .filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0)
@ -198,7 +214,10 @@ public abstract class LocalVariableTestBase extends TestBase {
} }
} }
/**
* LocalVariableTable and LocalVariableTypeTable are similar.
* VariableTable interface is introduced to test this attributes in the same way without code duplication.
*/
interface VariableTable { interface VariableTable {
int localVariableTableLength(); int localVariableTableLength();
@ -231,14 +250,23 @@ public abstract class LocalVariableTestBase extends TestBase {
} }
} }
/**
* Used to store expected results in sources
*/
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Repeatable(Container.class) @Repeatable(Container.class)
@interface ExpectedLocals { @interface ExpectedLocals {
/**
* @return name of a local variable
*/
String name(); String name();
/**
* @return type of local variable in the internal format.
*/
String type(); String type();
//variables from different scopes can share local variable table index and/or name. //variables from different scopes can share the local variable table index and/or name.
int scope() default DEFAULT_SCOPE; int scope() default DEFAULT_SCOPE;
} }

View file

@ -30,18 +30,41 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
/**
* Base class for Source file attribute tests. Checks expected file name for specified classes in the SourceFile attribute.
* To add new tests you should extend the SourceFileTestBase class and invoke {@link #test} for static sources
* or {@link #compileAndTest} for generated sources. For more information see corresponding methods.
*
* @see #test
* @see #compileAndTest
*/
public class SourceFileTestBase extends TestBase { public class SourceFileTestBase extends TestBase {
/**
* Checks expected fileName for the specified class in the SourceFile attribute.
*
* @param classToTest class to check its SourceFile attribute
* @param fileName expected name of the file from which the test file is compiled.
*/
protected void test(Class<?> classToTest, String fileName) throws Exception { protected void test(Class<?> classToTest, String fileName) throws Exception {
assertAttributePresent(ClassFile.read(getClassFile(classToTest)), fileName); assertAttributePresent(ClassFile.read(getClassFile(classToTest)), fileName);
} }
/**
* Checks expected fileName for the specified class in the SourceFile attribute.
*
* @param classToTest class name to check its SourceFile attribute
* @param fileName expected name of the file from which the test file is compiled.
*/
protected void test(String classToTest, String fileName) throws Exception { protected void test(String classToTest, String fileName) throws Exception {
assertAttributePresent(ClassFile.read(getClassFile(classToTest + ".class")), fileName); assertAttributePresent(ClassFile.read(getClassFile(classToTest + ".class")), fileName);
} }
/** /**
* Compile sourceCode and for all "classesToTest" checks SourceFile attribute. * Compiles sourceCode and for each specified class name checks the SourceFile attribute.
* The file name is extracted from source code.
*
* @param sourceCode source code to compile
* @param classesToTest class names to check their SourceFile attribute.
*/ */
protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception { protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception {

View file

@ -23,11 +23,14 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.util.List;
import java.util.*; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.tools.*; import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import static java.lang.String.format; import static java.lang.String.format;
import static java.lang.System.lineSeparator; import static java.lang.System.lineSeparator;
@ -36,6 +39,11 @@ import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
/**
* Base class for class file attribute tests.
* Contains methods for compiling generated sources in memory,
* for reading files from disk and a lot of assert* methods.
*/
public class TestBase { public class TestBase {
public static final String LINE_SEPARATOR = lineSeparator(); public static final String LINE_SEPARATOR = lineSeparator();
@ -66,33 +74,46 @@ public class TestBase {
} }
} }
/**
* Compiles sources in memory.
*
* @param sources to compile.
* @return memory file manager which contains class files and class loader.
*/
public InMemoryFileManager compile(String... sources) public InMemoryFileManager compile(String... sources)
throws IOException, CompilationException { throws IOException, CompilationException {
return compile(emptyList(), sources); return compile(emptyList(), sources);
} }
/** /**
* @param options - compiler options * Compiles sources in memory.
* @param sources *
* @param options compiler options.
* @param sources sources to compile.
* @return map where key is className, value is corresponding ClassFile. * @return map where key is className, value is corresponding ClassFile.
* @throws IOException
*/ */
public InMemoryFileManager compile(List<String> options, String... sources) public InMemoryFileManager compile(List<String> options, String... sources)
throws IOException, CompilationException { throws IOException, CompilationException {
return compile(options, ToolBox.JavaSource::new, asList(sources)); return compile(options, ToolBox.JavaSource::new, asList(sources));
} }
/**
* Compiles sources in memory.
*
* @param sources sources[i][0] - name of file, sources[i][1] - sources.
* @return map where key is className, value is corresponding ClassFile.
*/
public InMemoryFileManager compile(String[]... sources) throws IOException, public InMemoryFileManager compile(String[]... sources) throws IOException,
CompilationException { CompilationException {
return compile(emptyList(), sources); return compile(emptyList(), sources);
} }
/** /**
* @param options - compiler options * Compiles sources in memory.
* @param sources - sources[i][0] - name of file, sources[i][1] - sources *
* @param options compiler options
* @param sources sources[i][0] - name of file, sources[i][1] - sources.
* @return map where key is className, value is corresponding ClassFile. * @return map where key is className, value is corresponding ClassFile.
* @throws IOException
* @throws CompilationException
*/ */
public InMemoryFileManager compile(List<String> options, String[]... sources) public InMemoryFileManager compile(List<String> options, String[]... sources)
throws IOException, CompilationException { throws IOException, CompilationException {
@ -142,10 +163,21 @@ public class TestBase {
return getClassFile(clazz.getName().replace(".", "/") + ".class"); return getClassFile(clazz.getName().replace(".", "/") + ".class");
} }
/**
* Prints message to standard error. New lines are converted to system dependent NL.
*
* @param message string to print.
*/
public void echo(String message) { public void echo(String message) {
System.err.println(message.replace("\n", LINE_SEPARATOR)); System.err.println(message.replace("\n", LINE_SEPARATOR));
} }
/**
* Substitutes args in template and prints result to standard error. New lines are converted to system dependent NL.
*
* @param template template in standard String.format(...) format.
* @param args arguments to substitute in template.
*/
public void printf(String template, Object... args) { public void printf(String template, Object... args) {
System.err.printf(template, Stream.of(args) System.err.printf(template, Stream.of(args)
.map(Objects::toString) .map(Objects::toString)