1 /*
2  * Copyright (c) 2006, 2019, 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 6402516 8031569
27  * @summary need Trees.getScope(TreePath)
28  * @modules jdk.compiler/com.sun.tools.javac.api
29  *          jdk.compiler/com.sun.tools.javac.comp
30  *          jdk.compiler/com.sun.tools.javac.file
31  *          jdk.compiler/com.sun.tools.javac.tree
32  *          jdk.compiler/com.sun.tools.javac.util
33  * @build Checker CheckLocalElements
34  * @run main CheckLocalElements
35  */
36 
37 import java.io.IOException;
38 import java.util.*;
39 import java.util.regex.*;
40 
41 import javax.lang.model.element.*;
42 import javax.lang.model.util.*;
43 
44 import com.sun.source.tree.*;
45 import com.sun.source.util.*;
46 
47 /*
48  * Check the local elements of a scope against the contents of string literals and top-level comment.
49  */
50 public class CheckLocalElements extends Checker {
main(String... args)51     public static void main(String... args) throws Exception {
52         Checker chk = new CheckLocalElements();
53         chk.check("TestLocalElements.java");
54     }
55 
56     @Override
checkLocal(Scope s, String ref)57     protected boolean checkLocal(Scope s, String ref) {
58         Iterator<? extends Element> elemIter = s.getLocalElements().iterator();
59         ref = ref.trim();
60         String[] refs = ref.length() == 0 ? new String[0] : ref.split("[ ]*,[ ]*", -1);
61         Iterator<String> refIter = Arrays.asList(refs).iterator();
62         String r = null;
63 
64         nextElem:
65         while (elemIter.hasNext()) {
66             Element e = elemIter.next();
67             try {
68                 if (r == null)
69                     r = refIter.next();
70 
71                 while (r.endsWith(".*")) {
72                     String encl = getEnclosingName(e);
73                     String rBase = r.substring(0, r.length() - 2);
74                     if (encl.equals(rBase) || encl.startsWith(rBase + "."))
75                         continue nextElem;
76                     r = refIter.next();
77                 }
78 
79                 if (r.equals("-") && (e.getSimpleName().length() == 0)
80                     || e.getSimpleName().toString().equals(r)) {
81                     r = null;
82                     continue nextElem;
83                 }
84 
85                 error(s, ref, "mismatch: " + e.getSimpleName() + " " + r);
86                 return false;
87 
88             } catch (NoSuchElementException ex) { // from refIter.next()
89                 error(s, null, "scope has unexpected entry: " + e.getSimpleName());
90                 return false;
91             }
92 
93         }
94 
95         if (refIter.hasNext()) {
96             error(s, ref, "scope is missing entry: " + refIter.next());
97             return false;
98         }
99 
100         return true;
101     }
102 
103     @Override
additionalChecks(Trees trees, CompilationUnitTree topLevel)104     void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {
105         Matcher m = TOPLEVEL_SCOPE_DEF.matcher(topLevel.getSourceFile().getCharContent(false));
106         if (!m.find())
107             throw new AssertionError("Should have top-level scope def!");
108         check(trees.getScope(new TreePath(topLevel)), m.group(1));
109     }
110     //where:
111         Pattern TOPLEVEL_SCOPE_DEF = Pattern.compile("TOPLEVEL_SCOPE:(.*)");
112 
getEnclosingName(Element e)113     private String getEnclosingName(Element e) {
114         Element encl = e.getEnclosingElement();
115         return encl == null ? "" : encl.accept(qualNameVisitor, null);
116     }
117 
118     private ElementVisitor<String,Void> qualNameVisitor = new SimpleElementVisitor14<String,Void>() {
119         protected String defaultAction(Element e, Void ignore) {
120             return "";
121         }
122 
123         public String visitPackage(PackageElement e, Void ignore) {
124             return e.getQualifiedName().toString();
125         }
126 
127         public String visitType(TypeElement e, Void ignore) {
128             return e.getQualifiedName().toString();
129         }
130     };
131 }
132