SourceTreeScannerTest.java revision 3949:693a87020034
1261601Sglebius/* 2261601Sglebius * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. 3261601Sglebius * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4261601Sglebius * 5261601Sglebius * This code is free software; you can redistribute it and/or modify it 6261601Sglebius * under the terms of the GNU General Public License version 2 only, as 7261601Sglebius * published by the Free Software Foundation. 8261601Sglebius * 9261601Sglebius * This code is distributed in the hope that it will be useful, but WITHOUT 10261601Sglebius * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11261601Sglebius * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12261601Sglebius * version 2 for more details (a copy is included in the LICENSE file that 13261601Sglebius * accompanied this code). 14261601Sglebius * 15261601Sglebius * You should have received a copy of the GNU General Public License version 16261601Sglebius * 2 along with this work; if not, write to the Free Software Foundation, 17261601Sglebius * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18261601Sglebius * 19261601Sglebius * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20261601Sglebius * or visit www.oracle.com if you need additional information or have any 21261601Sglebius * questions. 22261601Sglebius */ 23261601Sglebius 24261601Sglebius/** 25261601Sglebius * Utility and test program to check javac's internal TreeScanner class. 26261601Sglebius * The program can be run standalone, or as a jtreg test. For info on 27261601Sglebius * command line args, run program with no args. 28261601Sglebius * 29261601Sglebius * <p> 30261601Sglebius * jtreg: Note that by using the -r switch in the test description below, this test 31261601Sglebius * will process all java files in the langtools/test directory, thus implicitly 32261601Sglebius * covering any new language features that may be tested in this test suite. 33261601Sglebius */ 34261601Sglebius 35261601Sglebius/* 36261601Sglebius * @test 37261601Sglebius * @bug 6923080 38261601Sglebius * @summary TreeScanner.visitNewClass should scan tree.typeargs 39261601Sglebius * @modules jdk.compiler/com.sun.tools.javac.api 40261601Sglebius * jdk.compiler/com.sun.tools.javac.file 41261601Sglebius * jdk.compiler/com.sun.tools.javac.tree 42261601Sglebius * jdk.compiler/com.sun.tools.javac.util 43261601Sglebius * @build AbstractTreeScannerTest SourceTreeScannerTest 44261601Sglebius * @run main SourceTreeScannerTest -q -r . 45261601Sglebius */ 46261601Sglebius 47261601Sglebiusimport java.io.*; 48261601Sglebiusimport java.lang.reflect.*; 49261601Sglebiusimport java.util.*; 50261601Sglebiusimport javax.tools.*; 51261601Sglebius 52261601Sglebiusimport com.sun.source.tree.Tree; 53261601Sglebiusimport com.sun.source.util.TreeScanner; 54261601Sglebiusimport com.sun.tools.javac.tree.JCTree; 55262743Sglebiusimport com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 56261601Sglebiusimport com.sun.tools.javac.tree.JCTree.JCModuleDecl; 57261601Sglebiusimport com.sun.tools.javac.tree.JCTree.TypeBoundKind; 58261601Sglebiusimport com.sun.tools.javac.util.List; 59262743Sglebius 60262743Sglebiuspublic class SourceTreeScannerTest extends AbstractTreeScannerTest { 61261601Sglebius /** 62261601Sglebius * Main entry point. 63261601Sglebius * If test.src is set, program runs in jtreg mode, and will throw an Error 64261601Sglebius * if any errors arise, otherwise System.exit will be used. In jtreg mode, 65261601Sglebius * the default base directory for file args is the value of ${test.src}. 66261601Sglebius * In jtreg mode, the -r option can be given to change the default base 67261601Sglebius * directory to the root test directory. 68261601Sglebius */ 69261601Sglebius public static void main(String... args) { 70261601Sglebius String testSrc = System.getProperty("test.src"); 71261601Sglebius File baseDir = (testSrc == null) ? null : new File(testSrc); 72261601Sglebius boolean ok = new SourceTreeScannerTest().run(baseDir, args); 73261601Sglebius if (!ok) { 74261601Sglebius if (testSrc != null) // jtreg mode 75261601Sglebius throw new Error("failed"); 76261601Sglebius else 77261601Sglebius System.exit(1); 78261601Sglebius } 79261601Sglebius } 80261601Sglebius 81261601Sglebius int test(JCCompilationUnit tree) { 82261601Sglebius return new ScanTester().test(tree); 83261601Sglebius } 84261601Sglebius 85 /** 86 * Main class for testing operation of tree scanner. 87 * The set of nodes found by the scanner are compared 88 * against the set of nodes found by reflection. 89 */ 90 private class ScanTester extends TreeScanner<Void,Void> { 91 /** Main entry method for the class. */ 92 int test(JCCompilationUnit tree) { 93 sourcefile = tree.sourcefile; 94 found = new HashSet<Tree>(); 95 scan(tree, null); 96 expect = new HashSet<Tree>(); 97 reflectiveScan(tree); 98 99 if (found.equals(expect)) { 100 //System.err.println(sourcefile.getName() + ": trees compared OK"); 101 return found.size(); 102 } 103 104 error(sourcefile.getName() + ": differences found"); 105 106 if (found.size() != expect.size()) 107 error("Size mismatch; found: " + found.size() + ", expected: " + expect.size()); 108 109 Set<Tree> missing = new HashSet<Tree>(); 110 missing.addAll(expect); 111 missing.removeAll(found); 112 for (Tree t: missing) 113 error(sourcefile, t, "missing"); 114 115 Set<Tree> excess = new HashSet<Tree>(); 116 excess.addAll(found); 117 excess.removeAll(expect); 118 for (Tree t: excess) 119 error(sourcefile, t, "unexpected"); 120 121 return 0; 122 } 123 124 /** Record all tree nodes found by scanner. */ 125 @Override 126 public Void scan(Tree tree, Void ignore) { 127 if (tree == null) 128 return null; 129 //System.err.println("FOUND: " + tree.getKind() + " " + trim(tree, 64)); 130 found.add(tree); 131 return super.scan(tree, ignore); 132 } 133 134 /** record all tree nodes found by reflection. */ 135 public void reflectiveScan(Object o) { 136 if (o == null) 137 return; 138 if (o instanceof JCTree) { 139 JCTree tree = (JCTree) o; 140 //System.err.println("EXPECT: " + tree.getKind() + " " + trim(tree, 64)); 141 expect.add(tree); 142 for (Field f: getFields(tree)) { 143 if (TypeBoundKind.class.isAssignableFrom(f.getType())) { 144 // not part of public API 145 continue; 146 } 147 try { 148 //System.err.println("FIELD: " + f.getName()); 149 if (tree instanceof JCModuleDecl && f.getName().equals("mods")) { 150 // The modifiers will not found by TreeScanner, 151 // but the embedded annotations will be. 152 reflectiveScan(((JCModuleDecl) tree).mods.annotations); 153 } else { 154 reflectiveScan(f.get(tree)); 155 } 156 } catch (IllegalAccessException e) { 157 error(e.toString()); 158 } 159 } 160 } else if (o instanceof List) { 161 List<?> list = (List<?>) o; 162 for (Object item: list) 163 reflectiveScan(item); 164 } else 165 error("unexpected item: " + o); 166 } 167 168 JavaFileObject sourcefile; 169 Set<Tree> found; 170 Set<Tree> expect; 171 } 172} 173