Path: blob/master/test/langtools/tools/javac/6402516/Checker.java
41152 views
/*1* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.*;24import java.util.*;25import javax.lang.model.util.*;26import javax.tools.*;27import com.sun.tools.javac.api.*;28import com.sun.source.tree.*;29import com.sun.source.util.*;30import com.sun.tools.javac.tree.JCTree;31import com.sun.tools.javac.tree.JCTree.*;32import com.sun.tools.javac.util.Position;3334/*35* Abstract class to help check the scopes in a parsed source file.36* -- parse source file37* -- scan trees looking for string literals38* -- check the scope at that point against the string, using39* boolean check(Scope s, String ref)40*/41abstract class Checker {42// parse the source file and call check(scope, string) for each string literal found43void check(String... fileNames) throws IOException {44File testSrc = new File(System.getProperty("test.src"));4546DiagnosticListener<JavaFileObject> dl = new DiagnosticListener<JavaFileObject>() {47public void report(Diagnostic d) {48System.err.println(d);49if (d.getKind() == Diagnostic.Kind.ERROR)50errors = true;51new Exception().printStackTrace();52}53};5455JavacTool tool = JavacTool.create();56try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) {57Iterable<? extends JavaFileObject> files =58fm.getJavaFileObjectsFromFiles(getFiles(testSrc, fileNames));59task = tool.getTask(null, fm, dl, null, null, files);60Iterable<? extends CompilationUnitTree> units = task.parse();6162if (errors)63throw new AssertionError("errors occurred creating trees");6465ScopeScanner s = new ScopeScanner();66for (CompilationUnitTree unit: units) {67TreePath p = new TreePath(unit);68s.scan(p, getTrees());69additionalChecks(getTrees(), unit);70}71task = null;7273if (errors)74throw new AssertionError("errors occurred checking scopes");75}76}7778// default impl: split ref at ";" and call checkLocal(scope, ref_segment) on scope and its enclosing scopes79protected boolean check(Scope s, String ref) {80// System.err.println("check scope: " + s);81// System.err.println("check ref: " + ref);82if (s == null && (ref == null || ref.trim().length() == 0))83return true;8485if (s == null) {86error(s, ref, "scope missing");87return false;88}8990if (ref == null) {91error(s, ref, "scope unexpected");92return false;93}9495String local;96String encl;97int semi = ref.indexOf(';');98if (semi == -1) {99local = ref;100encl = null;101} else {102local = ref.substring(0, semi);103encl = ref.substring(semi + 1);104}105106return checkLocal(s, local.trim())107& check(s.getEnclosingScope(), encl);108}109110// override if using default check(Scope,String)111boolean checkLocal(Scope s, String ref) {112throw new IllegalStateException();113}114115void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {116}117118void error(Scope s, String ref, String msg) {119System.err.println("Error: " + msg);120System.err.println("Scope: " + (s == null ? null : asList(s.getLocalElements())));121System.err.println("Expect: " + ref);122System.err.println("javac: " + (s == null ? null : ((JavacScope) s).getEnv()));123errors = true;124}125126protected Elements getElements() {127return task.getElements();128}129130protected Trees getTrees() {131return Trees.instance(task);132}133134boolean errors = false;135protected JavacTask task;136137// scan a parse tree, and for every string literal found, call check(scope, string) with138// the string value at the scope at that point139class ScopeScanner extends TreePathScanner<Boolean,Trees> {140public Boolean visitLiteral(LiteralTree tree, Trees trees) {141TreePath path = getCurrentPath();142CompilationUnitTree unit = path.getCompilationUnit();143Position.LineMap lineMap = ((JCCompilationUnit)unit).lineMap;144// long line = lineMap.getLineNumber(((JCTree)tree).pos/*trees.getSourcePositions().getStartPosition(tree)*/);145// System.err.println(line + ": " + abbrev(tree));146Scope s = trees.getScope(path);147if (tree.getKind() == Tree.Kind.STRING_LITERAL)148check(s, tree.getValue().toString().trim());149return null;150}151152private String abbrev(Tree tree) {153int max = 48;154String s = tree.toString().replaceAll("[ \n]+", " ");155return (s.length() < max ? s : s.substring(0, max-3) + "...");156}157}158159// prefix filenames with a directory160static Iterable<File> getFiles(File dir, String... names) {161List<File> files = new ArrayList<File>(names.length);162for (String name: names)163files.add(new File(dir, name));164return files;165}166167static private <T> List<T> asList(Iterable<T> iter) {168List<T> l = new ArrayList<T>();169for (T t: iter)170l.add(t);171return l;172}173}174175176