Mercurial > hg > jdk9-shenandoah > langtools
changeset 2441:7d67ebd3e35c jdk9-b16
Merge
author | lana |
---|---|
date | Fri, 30 May 2014 09:25:52 -0700 |
parents | 204314bf9667 (current diff) ca2bc0c46552 (diff) |
children | 00d3ef2061f0 4e6234110d3a |
files | |
diffstat | 8 files changed, 344 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java Thu May 29 22:32:18 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Fri May 30 09:25:52 2014 -0700 @@ -4696,7 +4696,7 @@ assembleClassSig(rawOuter ? types.erasure(outer) : outer); - append('.'); + append(rawOuter ? '$' : '.'); Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); append(rawOuter ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength())
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu May 29 22:32:18 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri May 30 09:25:52 2014 -0700 @@ -1221,25 +1221,102 @@ } //slow path + Symbol sym = quicklyResolveMethod(env, tree); + + if (sym == null) { + result = ArgumentExpressionKind.POLY; + return; + } + + result = analyzeCandidateMethods(sym, ArgumentExpressionKind.PRIMITIVE, + argumentKindAnalyzer); + } + //where + private boolean isSimpleReceiver(JCTree rec) { + switch (rec.getTag()) { + case IDENT: + return true; + case SELECT: + return isSimpleReceiver(((JCFieldAccess)rec).selected); + case TYPEAPPLY: + case TYPEARRAY: + return true; + case ANNOTATED_TYPE: + return isSimpleReceiver(((JCAnnotatedType)rec).underlyingType); + case APPLY: + return true; + default: + return false; + } + } + private ArgumentExpressionKind reduce(ArgumentExpressionKind kind) { + return argumentKindAnalyzer.reduce(result, kind); + } + MethodAnalyzer<ArgumentExpressionKind> argumentKindAnalyzer = + new MethodAnalyzer<ArgumentExpressionKind>() { + @Override + public ArgumentExpressionKind process(MethodSymbol ms) { + return ArgumentExpressionKind.methodKind(ms, types); + } + @Override + public ArgumentExpressionKind reduce(ArgumentExpressionKind kind1, + ArgumentExpressionKind kind2) { + switch (kind1) { + case PRIMITIVE: return kind2; + case NO_POLY: return kind2.isPoly() ? kind2 : kind1; + case POLY: return kind1; + default: + Assert.error(); + return null; + } + } + @Override + public boolean shouldStop(ArgumentExpressionKind result) { + return result.isPoly(); + } + }; + + @Override + public void visitLiteral(JCLiteral tree) { + Type litType = attr.litType(tree.typetag); + result = ArgumentExpressionKind.standaloneKind(litType, types); + } + + @Override + void skip(JCTree tree) { + result = ArgumentExpressionKind.NO_POLY; + } + + private Symbol quicklyResolveMethod(Env<AttrContext> env, final JCMethodInvocation tree) { final JCExpression rec = tree.meth.hasTag(SELECT) ? ((JCFieldAccess)tree.meth).selected : null; if (rec != null && !isSimpleReceiver(rec)) { - //give up if receiver is too complex (to cut down analysis time) - result = ArgumentExpressionKind.POLY; - return; + return null; } - Type site = rec != null ? - attribSpeculative(rec, env, attr.unknownTypeExprInfo).type : - env.enclClass.sym.type; + Type site; - while (site.hasTag(TYPEVAR)) { - site = site.getUpperBound(); + if (rec != null) { + if (rec.hasTag(APPLY)) { + Symbol recSym = quicklyResolveMethod(env, (JCMethodInvocation) rec); + if (recSym == null) + return null; + Symbol resolvedReturnType = + analyzeCandidateMethods(recSym, syms.errSymbol, returnSymbolAnalyzer); + if (resolvedReturnType == null) + return null; + site = resolvedReturnType.type; + } else { + site = attribSpeculative(rec, env, attr.unknownTypeExprInfo).type; + } + } else { + site = env.enclClass.sym.type; } List<Type> args = rs.dummyArgs(tree.args.length()); + Name name = TreeInfo.name(tree.meth); Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args, List.<Type>nil(), MethodResolutionPhase.VARARITY) { @Override @@ -1254,61 +1331,60 @@ } }; - Symbol sym = rs.lookupMethod(env, tree, site.tsym, rs.arityMethodCheck, lh); + return rs.lookupMethod(env, tree, site.tsym, rs.arityMethodCheck, lh); + } + //where: + MethodAnalyzer<Symbol> returnSymbolAnalyzer = new MethodAnalyzer<Symbol>() { + @Override + public Symbol process(MethodSymbol ms) { + ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types); + return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null; + } + @Override + public Symbol reduce(Symbol s1, Symbol s2) { + return s1 == syms.errSymbol ? s2 : s1 == s2 ? s1 : null; + } + @Override + public boolean shouldStop(Symbol result) { + return result == null; + } + }; - if (sym.kind == Kinds.AMBIGUOUS) { - Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); - result = ArgumentExpressionKind.PRIMITIVE; - for (Symbol s : err.ambiguousSyms) { - if (result.isPoly()) break; - if (s.kind == Kinds.MTH) { - result = reduce(ArgumentExpressionKind.methodKind(s, types)); + /** + * Process the result of Resolve.lookupMethod. If sym is a method symbol, the result of + * MethodAnalyzer.process is returned. If sym is an ambiguous symbol, all the candidate + * methods are inspected one by one, using MethodAnalyzer.process. The outcomes are + * reduced using MethodAnalyzer.reduce (using defaultValue as the first value over which + * the reduction runs). MethodAnalyzer.shouldStop can be used to stop the inspection early. + */ + <E> E analyzeCandidateMethods(Symbol sym, E defaultValue, MethodAnalyzer<E> analyzer) { + switch (sym.kind) { + case Kinds.MTH: + return analyzer.process((MethodSymbol) sym); + case Kinds.AMBIGUOUS: + Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); + E res = defaultValue; + for (Symbol s : err.ambiguousSyms) { + if (s.kind == Kinds.MTH) { + res = analyzer.reduce(res, analyzer.process((MethodSymbol) s)); + if (analyzer.shouldStop(res)) + return res; + } } - } - } else { - result = (sym.kind == Kinds.MTH) ? - ArgumentExpressionKind.methodKind(sym, types) : - ArgumentExpressionKind.NO_POLY; + return res; + default: + return defaultValue; } } - //where - private boolean isSimpleReceiver(JCTree rec) { - switch (rec.getTag()) { - case IDENT: - return true; - case SELECT: - return isSimpleReceiver(((JCFieldAccess)rec).selected); - case TYPEAPPLY: - case TYPEARRAY: - return true; - case ANNOTATED_TYPE: - return isSimpleReceiver(((JCAnnotatedType)rec).underlyingType); - default: - return false; - } - } - private ArgumentExpressionKind reduce(ArgumentExpressionKind kind) { - switch (result) { - case PRIMITIVE: return kind; - case NO_POLY: return kind.isPoly() ? kind : result; - case POLY: return result; - default: - Assert.error(); - return null; - } - } + } - @Override - public void visitLiteral(JCLiteral tree) { - Type litType = attr.litType(tree.typetag); - result = ArgumentExpressionKind.standaloneKind(litType, types); - } + /** Analyzer for methods - used by analyzeCandidateMethods. */ + interface MethodAnalyzer<E> { + E process(MethodSymbol ms); + E reduce(E e1, E e2); + boolean shouldStop(E result); + } - @Override - void skip(JCTree tree) { - result = ArgumentExpressionKind.NO_POLY; - } - } //where private EnumSet<JCTree.Tag> deferredCheckerTags = EnumSet.of(LAMBDA, REFERENCE, PARENS, TYPECAST,
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu May 29 22:32:18 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Fri May 30 09:25:52 2014 -0700 @@ -1925,6 +1925,13 @@ return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1); } + void removeLastRange() { + Range lastRange = lastRange(); + if (lastRange != null) { + aliveRanges.remove(lastRange); + } + } + @Override public String toString() { if (aliveRanges == null) { @@ -1955,9 +1962,7 @@ } } } else { - if (!aliveRanges.isEmpty()) { - aliveRanges.remove(aliveRanges.size() - 1); - } + removeLastRange(); } } @@ -1965,16 +1970,14 @@ if (aliveRanges.isEmpty()) { return false; } - Range range = lastRange(); - return range.length == Character.MAX_VALUE; + return lastRange().length == Character.MAX_VALUE; } public boolean isLastRangeInitialized() { if (aliveRanges.isEmpty()) { return false; } - Range range = lastRange(); - return range.start_pc != Character.MAX_VALUE; + return lastRange().start_pc != Character.MAX_VALUE; } public Range getWidestRange() { @@ -2095,7 +2098,7 @@ v.closeRange(length); putVar(v); } else { - v.lastRange().start_pc = Character.MAX_VALUE; + v.removeLastRange(); } } }
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu May 29 22:32:18 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri May 30 09:25:52 2014 -0700 @@ -1800,8 +1800,7 @@ genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); thenExit = code.branch(goto_); if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) { - code.closeAliveRanges(tree.thenpart, - thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp); + code.closeAliveRanges(tree.thenpart, code.cp); } } if (elseChain != null) {
--- a/test/tools/javac/flow/LVTHarness.java Thu May 29 22:32:18 2014 -0700 +++ b/test/tools/javac/flow/LVTHarness.java Fri May 30 09:25:52 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -23,8 +23,8 @@ /* * @test - * @bug 7047734 8027660 - * @summary The LVT is not generated correctly during some try/catch scenarios; + * @bug 7047734 8027660 8037937 + * @summary The LVT is not generated correctly during some try/catch scenarios * javac crash while creating LVT entry for a local variable defined in * an inner block * @library /tools/javac/lib @@ -120,7 +120,7 @@ for (Map.Entry<ElementKey, AliveRanges> entry : aliveRangeMap.entrySet()) { if (!seenAliveRanges.contains(entry.getKey())) { error("Redundant @AliveRanges annotation on method " + - entry.getKey().elem); + entry.getKey().elem + " with key " + entry.getKey()); } } } @@ -134,7 +134,7 @@ for (Method method : classFile.methods) { for (ElementKey elementKey: aliveRangeMap.keySet()) { String methodDesc = method.getName(constantPool) + - method.descriptor.getParameterTypes(constantPool); + method.descriptor.getParameterTypes(constantPool).replace(" ", ""); if (methodDesc.equals(elementKey.elem.toString())) { checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); seenAliveRanges.add(elementKey);
--- a/test/tools/javac/flow/tests/TestCaseIfElse.java Thu May 29 22:32:18 2014 -0700 +++ b/test/tools/javac/flow/tests/TestCaseIfElse.java Fri May 30 09:25:52 2014 -0700 @@ -33,7 +33,7 @@ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9) - void m2(String[] args) { + void m2() { Object o; int i = 5; if (i != 5) { @@ -45,4 +45,19 @@ } o = "finish"; } + + @AliveRange(varName="o", bytecodeStart=11, bytecodeLength=3) + @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=2) + Object m3(boolean cond1, boolean cond2) { + Object o; + if (cond1) { + if (cond2) { + o = "then"; + } else { + o = "else"; + return null; + } + } + return null; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8031967.java Fri May 30 09:25:52 2014 -0700 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, 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 8031967 + * @summary Ensure javac can handle very deeply nested chain of method invocations occurring as + * a parameter to other method invocations. + * @run main T8031967 + */ + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; + +public class T8031967 { + + public static void main(String... args) throws IOException { + new T8031967().run(); + } + + final int depth = 50; + + private void run() throws IOException { + runTestCase(true); + runTestCase(false); + } + + private void runTestCase(boolean withErrors) throws IOException { + StringBuilder code = new StringBuilder(); + + code.append("public class Test {\n" + + " private void test() {\n" + + " GroupLayout l = new GroupLayout();\n" + + " l.setHorizontalGroup(\n"); + + gen(code, depth); + code.append(" );\n" + + " }\n"); + if (!withErrors) { + code.append(" class GroupLayout {\n" + + " ParallelGroup createParallelGroup() {return null;}\n" + + " ParallelGroup createParallelGroup(int i) {return null;}\n" + + " ParallelGroup createParallelGroup(int i, int j) {return null;}\n" + + " void setHorizontalGroup(Group g) { }\n" + + " }\n" + + " \n" + + " class Group {\n" + + " Group addGroup(Group g) { return this; }\n" + + " Group addGroup(int i, Group g) { return this; }\n" + + " Group addGap(int i) { return this; }\n" + + " Group addGap(long l) { return this; }\n" + + " Group addGap(int i, int j) { return this; }\n" + + " Group addComponent(Object c) { return this; }\n" + + " Group addComponent(int i, Object c) { return this; }\n" + + " }\n" + + " class ParallelGroup extends Group {\n" + + " Group addGroup(Group g) { return this; }\n" + + " Group addGroup(int i, Group g) { return this; }\n" + + " Group addGap(int i) { return this; }\n" + + " Group addGap(int i, int j) { return this; }\n" + + " Group addComponent(Object c) { return this; }\n" + + " Group addComponent(int i, Object c) { return this; }\n" + + " }\n"); + } + + code.append("}\n"); + + JavaSource source = new JavaSource(code.toString()); + List<JavaSource> sourceList = Arrays.asList(source); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticListener<JavaFileObject> noErrors = (diagnostic) -> { + throw new IllegalStateException("Should not produce errors: " + diagnostic); + }; + JavacTask task = (JavacTask) compiler.getTask(null, null, withErrors ? null : noErrors, + null, null, sourceList); + + task.analyze(); + } + + private void gen(StringBuilder code, int depth) { + code.append("l.createParallelGroup()\n"); + if (depth > 0) { + code.append(".addGroup(\n"); + gen(code, depth - 1); + code.append(")"); + } + + code.append(".addGap(1)\n" + + ".addComponent(new Object())\n" + + ".addGap(1)\n" + + ".addComponent(new Object())"); + } + + class JavaSource extends SimpleJavaFileObject { + + final String code; + public JavaSource(String code) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/types/BadSigTest.java Fri May 30 09:25:52 2014 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, 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 8037934 + * @summary Javac generates invalid signatures for local types + * @run main BadSigTest + */ + +public class BadSigTest<Outer> { + void m(){ + class Local1{} + class Local2 extends Local1{} + Local2.class.getTypeParameters(); + } + public static void main(String[] args) { + new BadSigTest().m(); + } +}