langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java
changeset 25845 14935053bb07
parent 25699 7ca97d2d0405
equal deleted inserted replaced
25844:48eab270456c 25845:14935053bb07
    34 import java.util.stream.Stream;
    34 import java.util.stream.Stream;
    35 
    35 
    36 import static java.lang.String.format;
    36 import static java.lang.String.format;
    37 import static java.util.stream.Collectors.*;
    37 import static java.util.stream.Collectors.*;
    38 
    38 
    39 
    39 /**
       
    40  * Base class for LocalVariableTable and LocalVariableTypeTable attributes tests.
       
    41  * To add tests cases you should extend this class.
       
    42  * Then implement {@link #getVariableTables} to get LocalVariableTable or LocalVariableTypeTable attribute.
       
    43  * Then add method with local variables.
       
    44  * Finally, annotate method with information about expected variables and their types
       
    45  * by several {@link LocalVariableTestBase.ExpectedLocals} annotations.
       
    46  * To run test invoke {@link #test()} method.
       
    47  * If there are variables with the same name, set different scopes for them.
       
    48  *
       
    49  * @see #test()
       
    50  */
    40 public abstract class LocalVariableTestBase extends TestBase {
    51 public abstract class LocalVariableTestBase extends TestBase {
    41     public static final int DEFAULT_SCOPE = 0;
    52     public static final int DEFAULT_SCOPE = 0;
    42     private final ClassFile classFile;
    53     private final ClassFile classFile;
    43     private final Class<?> clazz;
    54     private final Class<?> clazz;
    44 
    55 
    45     protected abstract List<VariableTable> getVariableTables(Code_attribute codeAttribute);
    56     /**
    46 
    57      * @param clazz class to test. Must contains annotated methods with expected results.
       
    58      */
    47     public LocalVariableTestBase(Class<?> clazz) {
    59     public LocalVariableTestBase(Class<?> clazz) {
    48         this.clazz = clazz;
    60         this.clazz = clazz;
    49         try {
    61         try {
    50             this.classFile = ClassFile.read(getClassFile(clazz));
    62             this.classFile = ClassFile.read(getClassFile(clazz));
    51         } catch (IOException | ConstantPoolException e) {
    63         } catch (IOException | ConstantPoolException e) {
    52             throw new IllegalArgumentException("Can't read classfile for specified class", e);
    64             throw new IllegalArgumentException("Can't read classfile for specified class", e);
    53         }
    65         }
    54     }
    66     }
    55 
    67 
    56 
    68     protected abstract List<VariableTable> getVariableTables(Code_attribute codeAttribute);
    57     //info in the LocalVariableTable attribute is compared against expected info stored in annotations
    69 
       
    70     /**
       
    71      * Finds expected variables with their type in VariableTable.
       
    72      * Also does consistency checks, like variables from the same scope must point to different indexes.
       
    73      */
    58     public void test() throws IOException {
    74     public void test() throws IOException {
    59         List<java.lang.reflect.Method> testMethods = Stream.of(clazz.getDeclaredMethods())
    75         List<java.lang.reflect.Method> testMethods = Stream.of(clazz.getDeclaredMethods())
    60                 .filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0)
    76                 .filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0)
    61                 .collect(toList());
    77                 .collect(toList());
    62         int failed = 0;
    78         int failed = 0;
   196             ex.printStackTrace();
   212             ex.printStackTrace();
   197             throw new AssertionFailedException("Issue while reading constant pool");
   213             throw new AssertionFailedException("Issue while reading constant pool");
   198         }
   214         }
   199     }
   215     }
   200 
   216 
   201 
   217     /**
       
   218      * LocalVariableTable and LocalVariableTypeTable are similar.
       
   219      * VariableTable interface is introduced to test this attributes in the same way without code duplication.
       
   220      */
   202     interface VariableTable {
   221     interface VariableTable {
   203 
   222 
   204         int localVariableTableLength();
   223         int localVariableTableLength();
   205 
   224 
   206         List<VariableTable.Entry> entries();
   225         List<VariableTable.Entry> entries();
   229                         "%n}", name(), type(), index(), startPC(), length());
   248                         "%n}", name(), type(), index(), startPC(), length());
   230             }
   249             }
   231         }
   250         }
   232     }
   251     }
   233 
   252 
       
   253     /**
       
   254      * Used to store expected results in sources
       
   255      */
   234     @Retention(RetentionPolicy.RUNTIME)
   256     @Retention(RetentionPolicy.RUNTIME)
   235     @Repeatable(Container.class)
   257     @Repeatable(Container.class)
   236     @interface ExpectedLocals {
   258     @interface ExpectedLocals {
       
   259         /**
       
   260          * @return name of a local variable
       
   261          */
   237         String name();
   262         String name();
   238 
   263 
       
   264         /**
       
   265          * @return type of local variable in the internal format.
       
   266          */
   239         String type();
   267         String type();
   240 
   268 
   241         //variables from different scopes can share local variable table index and/or name.
   269         //variables from different scopes can share the local variable table index and/or name.
   242         int scope() default DEFAULT_SCOPE;
   270         int scope() default DEFAULT_SCOPE;
   243     }
   271     }
   244 
   272 
   245     @Retention(RetentionPolicy.RUNTIME)
   273     @Retention(RetentionPolicy.RUNTIME)
   246     @interface Container {
   274     @interface Container {