diff --git a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index 7face094f161823c744e9b1550834d84c40302ef..9241a32ad0ba567b0f560ea8eebdc53ee0fc9a57 100644 --- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -274,6 +274,9 @@ public class JavacTaskImpl extends JavacTask { public Iterable enter(Iterable trees) throws IOException { + if (trees == null && notYetEntered != null && notYetEntered.isEmpty()) + return List.nil(); + prepareCompiler(); ListBuffer roots = null; diff --git a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index b684d29ce64e329321480b05a73040c0ff1bc4a2..7bd384bb5ac38203ca70cd78c9279ffe9cb0fc78 100644 --- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -65,6 +65,7 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeCopier; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.List; @@ -263,9 +264,10 @@ public class JavacTrees extends Trees { if (!(path.getLeaf() instanceof JCTree)) // implicit null-check throw new IllegalArgumentException(); - // if we're being invoked via from a JSR199 client, we need to make sure - // all the classes have been entered; if we're being invoked from JSR269, - // then the classes will already have been entered. + // if we're being invoked from a Tree API client via parse/enter/analyze, + // we need to make sure all the classes have been entered; + // if we're being invoked from JSR 199 or JSR 269, then the classes + // will already have been entered. if (javacTaskImpl != null) { try { javacTaskImpl.enter(null); @@ -313,10 +315,19 @@ public class JavacTrees extends Trees { break; case BLOCK: { // System.err.println("BLOCK: "); - if (method != null) - env = memberEnter.getMethodEnv(method, env); - JCTree body = copier.copy((JCTree)tree, (JCTree) path.getLeaf()); - env = attribStatToTree(body, env, copier.leafCopy); + if (method != null) { + try { + Assert.check(method.body == tree); + method.body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf()); + env = memberEnter.getMethodEnv(method, env); + env = attribStatToTree(method.body, env, copier.leafCopy); + } finally { + method.body = (JCBlock) tree; + } + } else { + JCBlock body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf()); + env = attribStatToTree(body, env, copier.leafCopy); + } return env; } default: @@ -329,7 +340,7 @@ public class JavacTrees extends Trees { } } } - return field != null ? memberEnter.getInitEnv(field, env) : env; + return (field != null) ? memberEnter.getInitEnv(field, env) : env; } private Env attribStatToTree(JCTree stat, Envenv, JCTree tree) { diff --git a/test/tools/javac/api/TestGetScope.java b/test/tools/javac/api/TestGetScope.java new file mode 100644 index 0000000000000000000000000000000000000000..40cf8c9cd3f3e33738a6f2a1aee34fb9e50f3d85 --- /dev/null +++ b/test/tools/javac/api/TestGetScope.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7090249 + * @summary IllegalStateException from Trees.getScope when called from JSR 199 + */ + +import com.sun.source.tree.IdentifierTree; +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.SourceVersion; + +@SupportedAnnotationTypes("*") +public class TestGetScope extends AbstractProcessor { + public static void main(String... args) { + new TestGetScope().run(); + } + + public void run() { + File srcDir = new File(System.getProperty("test.src")); + File thisFile = new File(srcDir, getClass().getName() + ".java"); + + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + + List opts = Arrays.asList("-proc:only", "-doe"); + Iterable files = fm.getJavaFileObjects(thisFile); + JavacTask t = (JavacTask) c.getTask(null, fm, null, opts, null, files); + t.setProcessors(Collections.singleton(this)); + boolean ok = t.call(); + if (!ok) + throw new Error("compilation failed"); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + Trees trees = Trees.instance(processingEnv); + if (round++ == 0) { + for (Element e: roundEnv.getRootElements()) { + TreePath p = trees.getPath(e); + new Scanner().scan(p, trees); + } + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + int round; + + static class Scanner extends TreePathScanner { + @Override + public Void visitIdentifier(IdentifierTree t, Trees trees) { + System.err.println("visitIdentifier: " + t); + trees.getScope(getCurrentPath()); + return null; + } + } +}