# HG changeset patch # User jlahoda # Date 1379687615 -7200 # Node ID 41599b57d26277d2376ed4ee9647fcaff9f32af5 # Parent 9a75bdb249a2351a46ee7e846718b56b3cb46827 8023835: TreeMaker.QualIdent() too leafy Reviewed-by: jjg diff -r 9a75bdb249a2 -r 41599b57d262 src/share/classes/com/sun/tools/javac/tree/TreeMaker.java --- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Sep 19 19:18:37 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Sep 20 16:33:35 2013 +0200 @@ -946,6 +946,7 @@ boolean isUnqualifiable(Symbol sym) { if (sym.name == names.empty || sym.owner == null || + sym.owner == syms.rootPackage || sym.owner.kind == MTH || sym.owner.kind == VAR) { return true; } else if (sym.kind == TYP && toplevel != null) { diff -r 9a75bdb249a2 -r 41599b57d262 test/tools/javac/tree/MakeQualIdent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/tree/MakeQualIdent.java Fri Sep 20 16:33:35 2013 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, 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 8023835 + * @summary Verify that TreeMaker.QualIdent(Symbol) field access cascade ends with + * the top-level package (when no toplevel is set in TreeMaker) + * @run main MakeQualIdent + */ + +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import java.util.ArrayList; + +public class MakeQualIdent { + public static void main(String... args) throws Exception { + JavacTool tool = JavacTool.create(); + JavacTask task = tool.getTask(null, null, null, new ArrayList(), null, null); + Context ctx = ((JavacTaskImpl)task).getContext(); + TreeMaker treeMaker = TreeMaker.instance(ctx); + Symtab syms = Symtab.instance(ctx); + + String stringTree = printTree(treeMaker.QualIdent(syms.stringType.tsym)); + + if (!"java.lang.String".equals(stringTree)) { + throw new IllegalStateException(stringTree); + } + } + + private static String printTree(Tree tree) { + final StringBuilder result = new StringBuilder(); + + new TreeScanner() { + @Override public Void visitIdentifier(IdentifierTree node, Void p) { + result.append(node.getName()); + return super.visitIdentifier(node, p); + } + @Override public Void visitMemberSelect(MemberSelectTree node, Void p) { + scan(node.getExpression(), null); + result.append("."); + result.append(node.getIdentifier()); + return null; + } + }.scan(tree, null); + + return result.toString(); + } +} diff -r 9a75bdb249a2 -r 41599b57d262 test/tools/javac/tree/ScopeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/tree/ScopeTest.java Fri Sep 20 16:33:35 2013 +0200 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, 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 8023835 + * @summary Verify that implicit type of lambda parameter is correctly attributed + * in Scope + * @run main ScopeTest + */ + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Scope; +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 com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.model.JavacTypes; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import javax.lang.model.element.Element; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; + +public class ScopeTest { + + private static final String SOURCE_CODE = + "public class Test {\n" + + " private static void test() {\n" + + " InvokeOn f = null;\n" + + " f.run(x -> { x.correct(); });\n" + + " }\n" + + " public static final class FooBar {\n" + + " public void dontRun() { }\n" + + " }\n" + + "}\n" + + "class InvokeOn {\n" + + " public void run(I i) { }\n" + + "}\n" + + "class FooBar {\n" + + " public void correct() { }\n" + + "}\n" + + "interface I {\n" + + " public void run(FooBar f);\n" + + "}"; + + public static void main(String... args) throws Exception { + verifyLambdaScopeCorrect(""); + verifyLambdaScopeCorrect("package test;"); + } + + private static void verifyLambdaScopeCorrect(final String packageClause) throws Exception { + JavacTool tool = JavacTool.create(); + JavaFileObject source = new SimpleJavaFileObject(URI.create("mem://Test.java"), Kind.SOURCE) { + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return packageClause + SOURCE_CODE; + } + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return true; + } + }; + Iterable fos = Collections.singletonList(source); + JavacTask task = tool.getTask(null, null, null, new ArrayList(), null, fos); + final Types types = JavacTypes.instance(((JavacTaskImpl) task).getContext()); + final Trees trees = Trees.instance(task); + CompilationUnitTree cu = task.parse().iterator().next(); + + task.analyze(); + + new TreePathScanner() { + @Override public Void visitMemberSelect(MemberSelectTree node, Void p) { + if (node.getIdentifier().contentEquals("correct")) { + TypeMirror xType = trees.getTypeMirror(new TreePath(getCurrentPath(), node.getExpression())); + Scope scope = trees.getScope(getCurrentPath()); + for (Element l : scope.getLocalElements()) { + if (!l.getSimpleName().contentEquals("x")) continue; + if (!types.isSameType(xType, l.asType())) { + throw new IllegalStateException("Incorrect variable type in scope: " + l.asType() + "; should be: " + xType); + } + } + } + return super.visitMemberSelect(node, p); + } + }.scan(cu, null); + } +}