JavacTreeScannerTest.java revision 3170:dc017a37aac5
1156952Sume/*
2156952Sume * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
3156952Sume * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4156952Sume *
5156952Sume * This code is free software; you can redistribute it and/or modify it
6156952Sume * under the terms of the GNU General Public License version 2 only, as
7156952Sume * published by the Free Software Foundation.
8156952Sume *
9156952Sume * This code is distributed in the hope that it will be useful, but WITHOUT
10156952Sume * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11156952Sume * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12156952Sume * version 2 for more details (a copy is included in the LICENSE file that
13156952Sume * accompanied this code).
14156952Sume *
15156952Sume * You should have received a copy of the GNU General Public License version
16156952Sume * 2 along with this work; if not, write to the Free Software Foundation,
17156952Sume * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18156952Sume *
19156952Sume * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20156952Sume * or visit www.oracle.com if you need additional information or have any
21156952Sume * questions.
22156952Sume */
23270838Sume
24156952Sume/**
25156956Sume * Utility and test program to check javac's internal TreeScanner class.
26156956Sume * The program can be run standalone, or as a jtreg test.  For info on
27156952Sume * command line args, run program with no args.
28156952Sume *
29156956Sume * <p>
30156952Sume * jtreg: Note that by using the -r switch in the test description below, this test
31156956Sume * will process all java files in the langtools/test directory, thus implicitly
32156952Sume * covering any new language features that may be tested in this test suite.
33156952Sume */
34156952Sume
35156952Sume/*
36156952Sume * @test
37156952Sume * @bug 6923080
38156952Sume * @summary TreeScanner.visitNewClass should scan tree.typeargs
39156956Sume * @modules jdk.compiler/com.sun.tools.javac.api
40156952Sume *          jdk.compiler/com.sun.tools.javac.file
41156956Sume *          jdk.compiler/com.sun.tools.javac.tree
42156952Sume *          jdk.compiler/com.sun.tools.javac.util
43156952Sume * @build AbstractTreeScannerTest JavacTreeScannerTest
44156952Sume * @run main JavacTreeScannerTest -q -r .
45156952Sume */
46156956Sume
47156952Sumeimport java.io.*;
48156952Sumeimport java.lang.reflect.*;
49156952Sumeimport java.util.*;
50156952Sumeimport javax.tools.*;
51156952Sume
52156956Sumeimport com.sun.tools.javac.tree.JCTree;
53156952Sumeimport com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
54156952Sumeimport com.sun.tools.javac.tree.TreeScanner;
55156952Sumeimport com.sun.tools.javac.util.List;
56156952Sume
57156952Sumepublic class JavacTreeScannerTest extends AbstractTreeScannerTest {
58156952Sume    /**
59156952Sume     * Main entry point.
60156952Sume     * If test.src is set, program runs in jtreg mode, and will throw an Error
61156952Sume     * if any errors arise, otherwise System.exit will be used. In jtreg mode,
62156952Sume     * the default base directory for file args is the value of ${test.src}.
63156952Sume     * In jtreg mode, the -r option can be given to change the default base
64156956Sume     * directory to the root test directory.
65156952Sume     */
66156952Sume    public static void main(String... args) {
67156952Sume        String testSrc = System.getProperty("test.src");
68156952Sume        File baseDir = (testSrc == null) ? null : new File(testSrc);
69156952Sume        boolean ok = new JavacTreeScannerTest().run(baseDir, args);
70156952Sume        if (!ok) {
71156952Sume            if (testSrc != null)  // jtreg mode
72156952Sume                throw new Error("failed");
73156952Sume            else
74156952Sume                System.exit(1);
75156952Sume        }
76156952Sume    }
77156952Sume
78156952Sume    int test(JCCompilationUnit tree) {
79156952Sume        return new ScanTester().test(tree);
80156952Sume    }
81156952Sume
82156952Sume    /**
83156952Sume     * Main class for testing operation of tree scanner.
84156952Sume     * The set of nodes found by the scanner are compared
85156952Sume     * against the set of nodes found by reflection.
86156952Sume     */
87156952Sume    private class ScanTester extends TreeScanner {
88156952Sume        /** Main entry method for the class. */
89156952Sume        int test(JCCompilationUnit tree) {
90156952Sume            sourcefile = tree.sourcefile;
91156952Sume            found = new HashSet<JCTree>();
92156952Sume            scan(tree);
93156952Sume            expect = new HashSet<JCTree>();
94156952Sume            reflectiveScan(tree);
95156952Sume
96156952Sume            if (found.equals(expect)) {
97156952Sume                //System.err.println(sourcefile.getName() + ": trees compared OK");
98156952Sume                return found.size();
99156952Sume            }
100156952Sume
101156952Sume            error(sourcefile, "differences found");
102156952Sume
103156952Sume            if (found.size() != expect.size())
104156952Sume                error("Size mismatch; found: " + found.size() + ", expected: " + expect.size());
105156952Sume
106156952Sume            Set<JCTree> missing = new HashSet<JCTree>();
107156952Sume            missing.addAll(expect);
108156952Sume            missing.removeAll(found);
109156952Sume            for (JCTree t: missing)
110156952Sume                error(sourcefile, t, "missing");
111156952Sume
112156952Sume            Set<JCTree> excess = new HashSet<JCTree>();
113156952Sume            excess.addAll(found);
114156952Sume            excess.removeAll(expect);
115156952Sume            for (JCTree t: excess)
116156952Sume                error(sourcefile, t, "unexpected");
117156952Sume
118156952Sume            return 0;
119156952Sume        }
120156952Sume
121156952Sume        /** Record all tree nodes found by scanner. */
122156952Sume        @Override
123156952Sume        public void scan(JCTree tree) {
124156952Sume            if (tree == null)
125156952Sume                return;
126156952Sume            //System.err.println("FOUND: " + tree.getTag() + " " + trim(tree, 64));
127156952Sume            found.add(tree);
128156952Sume            super.scan(tree);
129156952Sume        }
130156952Sume
131156952Sume        /** record all tree nodes found by reflection. */
132156952Sume        public void reflectiveScan(Object o) {
133156952Sume            if (o == null)
134156952Sume                return;
135156952Sume            if (o instanceof JCTree) {
136156952Sume                JCTree tree = (JCTree) o;
137156952Sume                //System.err.println("EXPECT: " + tree.getTag() + " " + trim(tree, 64));
138156952Sume                expect.add(tree);
139156952Sume                for (Field f: getFields(tree)) {
140156952Sume                    try {
141156952Sume                        //System.err.println("FIELD: " + f.getName());
142156952Sume                        reflectiveScan(f.get(tree));
143156952Sume                    } catch (IllegalAccessException e) {
144156952Sume                        error(e.toString());
145156952Sume                    }
146156952Sume                }
147156952Sume            } else if (o instanceof List) {
148156952Sume                List<?> list = (List<?>) o;
149156952Sume                for (Object item: list)
150156952Sume                    reflectiveScan(item);
151156952Sume            } else
152156952Sume                error("unexpected item: " + o);
153156952Sume        }
154156952Sume
155156952Sume        JavaFileObject sourcefile;
156156952Sume        Set<JCTree> found;
157156952Sume        Set<JCTree> expect;
158156952Sume    }
159156952Sume}
160156952Sume