TestJavacTaskScanner.java revision 2689:f839b50088bc
1/* 2 * Copyright (c) 2005, 2014, 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 24/* 25 * @test 26 * @bug 4813736 8013256 27 * @summary Additional functionality test of task and JSR 269 28 * @author Peter von der Ah\u00e9 29 * @library ./lib 30 * @build ToolTester 31 * @run main TestJavacTaskScanner TestJavacTaskScanner.java 32 */ 33 34import com.sun.tools.javac.api.JavacTaskImpl; 35import com.sun.tools.javac.parser.*; 36import com.sun.tools.javac.parser.Tokens.Token; 37import com.sun.tools.javac.util.*; 38import java.io.*; 39import java.net.*; 40import java.nio.*; 41import java.nio.charset.Charset; 42import java.util.Arrays; 43import javax.lang.model.element.Element; 44import javax.lang.model.element.TypeElement; 45import javax.lang.model.type.DeclaredType; 46import javax.lang.model.type.TypeMirror; 47import javax.lang.model.util.Elements; 48import javax.lang.model.util.Types; 49import javax.tools.*; 50 51import static javax.tools.StandardLocation.CLASS_PATH; 52import static javax.tools.StandardLocation.SOURCE_PATH; 53import static javax.tools.StandardLocation.CLASS_OUTPUT; 54 55public class TestJavacTaskScanner extends ToolTester { 56 57 final JavacTaskImpl task; 58 final Elements elements; 59 final Types types; 60 61 int numTokens; 62 int numParseTypeElements; 63 int numAllMembers; 64 65 TestJavacTaskScanner(File file) { 66 final Iterable<? extends JavaFileObject> compilationUnits = 67 fm.getJavaFileObjects(new File[] {file}); 68 StandardJavaFileManager fm = getLocalFileManager(tool, null, null); 69 task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits); 70 task.getContext().put(ScannerFactory.scannerFactoryKey, 71 new MyScanner.Factory(task.getContext(), this)); 72 elements = task.getElements(); 73 types = task.getTypes(); 74 } 75 76 public void run() { 77 Iterable<? extends TypeElement> toplevels; 78 toplevels = task.enter(task.parse()); 79 for (TypeElement clazz : toplevels) { 80 System.out.format("Testing %s:%n%n", clazz.getSimpleName()); 81 testParseType(clazz); 82 testGetAllMembers(clazz); 83 System.out.println(); 84 System.out.println(); 85 System.out.println(); 86 } 87 88 System.out.println("#tokens: " + numTokens); 89 System.out.println("#parseTypeElements: " + numParseTypeElements); 90 System.out.println("#allMembers: " + numAllMembers); 91 92 check(numTokens, "#Tokens", 1222); 93 check(numParseTypeElements, "#parseTypeElements", 158); 94 check(numAllMembers, "#allMembers", 52); 95 } 96 97 void check(int value, String name, int expected) { 98 // allow some slop in the comparison to allow for minor edits in the 99 // test and in the platform 100 if (value < expected * 9 / 10) 101 throw new Error(name + " lower than expected; expected " + expected + "; found: " + value); 102 if (value > expected * 11 / 10) 103 throw new Error(name + " higher than expected; expected " + expected + "; found: " + value); 104 } 105 106 void testParseType(TypeElement clazz) { 107 DeclaredType type = (DeclaredType)task.parseType("List<String>", clazz); 108 for (Element member : elements.getAllMembers((TypeElement)type.asElement())) { 109 TypeMirror mt = types.asMemberOf(type, member); 110 System.out.format("type#%d: %s : %s -> %s%n", 111 numParseTypeElements, member.getSimpleName(), member.asType(), mt); 112 numParseTypeElements++; 113 } 114 } 115 116 public static void main(String... args) throws IOException { 117 String srcdir = System.getProperty("test.src"); 118 try (TestJavacTaskScanner t = new TestJavacTaskScanner(new File(srcdir, args[0]))) { 119 t.run(); 120 } 121 } 122 123 private void testGetAllMembers(TypeElement clazz) { 124 for (Element member : elements.getAllMembers(clazz)) { 125 System.out.format("elem#%d: %s : %s%n", 126 numAllMembers, member.getSimpleName(), member.asType()); 127 numAllMembers++; 128 } 129 } 130 131 /* Similar to ToolTester.getFileManager, except that this version also ensures 132 * javac classes will be available on the classpath. The javac classes are assumed 133 * to be on the classpath used to run this test (this is true when using jtreg). 134 * The classes are found by obtaining the URL for a sample javac class, using 135 * getClassLoader().getResource(), and then deconstructing the URL to find the 136 * underlying directory or jar file to place on the classpath. 137 */ 138 public StandardJavaFileManager getLocalFileManager(JavaCompiler tool, 139 DiagnosticListener<JavaFileObject> dl, 140 Charset encoding) { 141 File javac_classes; 142 try { 143 final String javacMainClass = "com/sun/tools/javac/Main.class"; 144 URL url = getClass().getClassLoader().getResource(javacMainClass); 145 if (url == null) 146 throw new Error("can't locate javac classes"); 147 URI uri = url.toURI(); 148 String scheme = uri.getScheme(); 149 String ssp = uri.getSchemeSpecificPart(); 150 if (scheme.equals("jar")) { 151 javac_classes = new File(new URI(ssp.substring(0, ssp.indexOf("!/")))); 152 } else if (scheme.equals("file")) { 153 javac_classes = new File(ssp.substring(0, ssp.indexOf(javacMainClass))); 154 } else 155 throw new Error("unknown URL: " + url); 156 } catch (URISyntaxException e) { 157 throw new Error(e); 158 } 159 System.err.println("javac_classes: " + javac_classes); 160 161 StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, encoding); 162 try { 163 fm.setLocation(SOURCE_PATH, Arrays.asList(test_src)); 164 fm.setLocation(CLASS_PATH, join(test_class_path, Arrays.asList(javac_classes))); 165 fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes)); 166 } catch (IOException e) { 167 throw new AssertionError(e); 168 } 169 return fm; 170 } 171} 172 173class MyScanner extends Scanner { 174 175 public static class Factory extends ScannerFactory { 176 public Factory(Context context, TestJavacTaskScanner test) { 177 super(context); 178 this.test = test; 179 } 180 181 @Override 182 public Scanner newScanner(CharSequence input, boolean keepDocComments) { 183 if (input instanceof CharBuffer) { 184 return new MyScanner(this, (CharBuffer)input, test); 185 } else { 186 char[] array = input.toString().toCharArray(); 187 return newScanner(array, array.length, keepDocComments); 188 } 189 } 190 191 @Override 192 public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { 193 return new MyScanner(this, input, inputLength, test); 194 } 195 196 private TestJavacTaskScanner test; 197 } 198 protected MyScanner(ScannerFactory fac, CharBuffer buffer, TestJavacTaskScanner test) { 199 super(fac, buffer); 200 this.test = test; 201 } 202 protected MyScanner(ScannerFactory fac, char[] input, int inputLength, TestJavacTaskScanner test) { 203 super(fac, input, inputLength); 204 this.test = test; 205 } 206 207 public void nextToken() { 208 super.nextToken(); 209 Token tk = token(); 210 System.err.format("Saw token %s %n", tk.kind); 211 test.numTokens++; 212 } 213 214 private TestJavacTaskScanner test; 215 216} 217