1/* 2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import com.sun.tools.classfile.Attribute; 25import com.sun.tools.classfile.ClassFile; 26import com.sun.tools.classfile.SourceFile_attribute; 27 28import java.nio.file.Path; 29import java.util.ArrayList; 30import java.util.List; 31import java.util.Map; 32import javax.tools.JavaFileObject; 33 34import toolbox.ToolBox; 35 36/** 37 * Base class for Source file attribute tests. Checks expected file name for specified classes in the SourceFile attribute. 38 * To add new tests you should extend the SourceFileTestBase class and invoke {@link #test} for static sources 39 * or {@link #compileAndTest} for generated sources. For more information see corresponding methods. 40 * 41 * @see #test 42 * @see #compileAndTest 43 */ 44public class SourceFileTestBase extends TestBase { 45 /** 46 * Checks expected fileName for the specified class in the SourceFile attribute. 47 * 48 * @param classToTest class to check its SourceFile attribute 49 * @param fileName expected name of the file from which the test file is compiled. 50 */ 51 protected void test(Class<?> classToTest, String fileName) throws Exception { 52 assertAttributePresent(ClassFile.read(getClassFile(classToTest)), fileName); 53 } 54 55 /** 56 * Checks expected fileName for the specified class in the SourceFile attribute. 57 * 58 * @param classToTest class name to check its SourceFile attribute 59 * @param fileName expected name of the file from which the test file is compiled. 60 */ 61 protected void test(String classToTest, String fileName) throws Exception { 62 assertAttributePresent(ClassFile.read(getClassFile(classToTest + ".class")), fileName); 63 } 64 65 /** 66 * Checks expected fileName for the specified class in the SourceFile attribute. 67 * 68 * @param classToTest path of class to check its SourceFile attribute 69 * @param fileName expected name of the file from which the test file is compiled. 70 */ 71 protected void test(Path classToTest, String fileName) throws Exception { 72 assertAttributePresent(ClassFile.read(classToTest), fileName); 73 } 74 75 /** 76 * Compiles sourceCode and for each specified class name checks the SourceFile attribute. 77 * The file name is extracted from source code. 78 * 79 * @param sourceCode source code to compile 80 * @param classesToTest class names to check their SourceFile attribute. 81 */ 82 protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception { 83 84 Map<String, ? extends JavaFileObject> classes = compile(sourceCode).getClasses(); 85 String fileName = ToolBox.getJavaFileNameFromSource(sourceCode); 86 for (String className : classesToTest) { 87 assertAttributePresent(ClassFile.read(classes.get(className).openInputStream()), fileName); 88 } 89 } 90 91 private void assertAttributePresent(ClassFile classFile, String fileName) throws Exception { 92 93 //We need to count attributes with the same names because there is no appropriate API in the ClassFile. 94 95 List<SourceFile_attribute> sourceFileAttributes = new ArrayList<>(); 96 for (Attribute a : classFile.attributes.attrs) { 97 if (Attribute.SourceFile.equals(a.getName(classFile.constant_pool))) { 98 sourceFileAttributes.add((SourceFile_attribute) a); 99 } 100 } 101 102 assertEquals(sourceFileAttributes.size(), 1, "Should be the only SourceFile attribute"); 103 104 SourceFile_attribute attribute = sourceFileAttributes.get(0); 105 106 assertEquals(classFile.constant_pool.getUTF8Info(attribute.attribute_name_index).value, 107 Attribute.SourceFile, "Incorrect attribute name"); 108 assertEquals(classFile.constant_pool.getUTF8Info(attribute.sourcefile_index).value, fileName, 109 "Incorrect source file name"); 110 assertEquals(attribute.attribute_length, 2, "Incorrect attribute length"); 111 } 112} 113