Mercurial > hg > openjdk > jdk6 > langtools
changeset 98:7d51140c7453
Merge
author | jjg |
---|---|
date | Fri, 18 Jun 2010 11:13:26 -0700 |
parents | 8b5712fa8c97 (current diff) 05bf914950a9 (diff) |
children | 0e4ccb5a0d40 e8cf1a74be06 c28b5920263c |
files | |
diffstat | 13 files changed, 443 insertions(+), 110 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Wed Jun 16 17:15:44 2010 -0700 +++ b/.hgtags Fri Jun 18 11:13:26 2010 -0700 @@ -18,3 +18,4 @@ 78efde88dc5a5a0c1affe42c0e22299d78d7a614 jdk6-b17 536fbf4fba1f607cbc300ced4c41b71ac75829a1 jdk6-b18 7306e2127357bcbe9d6b86e2c956aca016d403cd jdk6-b19 +51b6d8d173cd652ac8956879c91782eb36f44741 jdk6-b20
--- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Wed Jun 16 17:15:44 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Jun 18 11:13:26 2010 -0700 @@ -381,8 +381,8 @@ return results; } // where - private void handleFlowResults(List<Env<AttrContext>> list, ListBuffer<Element> elems) { - for (Env<AttrContext> env: list) { + private void handleFlowResults(Queue<Env<AttrContext>> queue, ListBuffer<Element> elems) { + for (Env<AttrContext> env: queue) { switch (env.tree.getTag()) { case JCTree.CLASSDEF: JCClassDecl cdef = (JCClassDecl) env.tree; @@ -396,7 +396,7 @@ break; } } - genList.appendList(list); + genList.addAll(queue); } @@ -424,13 +424,13 @@ analyze(null); // ensure all classes have been parsed, entered, and analyzed if (classes == null) { - compiler.generate(compiler.desugar(genList.toList()), results); + compiler.generate(compiler.desugar(genList), results); genList.clear(); } else { Filter f = new Filter() { public void process(Env<AttrContext> env) { - compiler.generate(compiler.desugar(List.of(env)), results); + compiler.generate(compiler.desugar(ListBuffer.of(env)), results); } }; f.run(genList, classes);
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Jun 16 17:15:44 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Jun 18 11:13:26 2010 -0700 @@ -262,8 +262,11 @@ */ <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) { ListBuffer<Type> ts = new ListBuffer<Type>(); - for (List<T> l = trees; l.nonEmpty(); l = l.tail) - ts.append(classEnter(l.head, env)); + for (List<T> l = trees; l.nonEmpty(); l = l.tail) { + Type t = classEnter(l.head, env); + if (t != null) + ts.append(t); + } return ts.toList(); }
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jun 16 17:15:44 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Jun 18 11:13:26 2010 -0700 @@ -27,6 +27,7 @@ import java.io.*; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.MissingResourceException; @@ -62,6 +63,8 @@ // TEMP, until we have a more efficient way to save doc comment info import com.sun.tools.javac.parser.DocCommentScanner; +import java.util.HashMap; +import java.util.Queue; import javax.lang.model.SourceVersion; /** This class could be the main entry point for GJC when GJC is used as a @@ -437,7 +440,25 @@ */ public Todo todo; - private Set<Env<AttrContext>> deferredSugar = new HashSet<Env<AttrContext>>(); + protected enum CompileState { + TODO(0), + ATTR(1), + FLOW(2); + CompileState(int value) { + this.value = value; + } + boolean isDone(CompileState other) { + return value >= other.value; + } + private int value; + }; + protected class CompileStates extends HashMap<Env<AttrContext>,CompileState> { + boolean isDone(Env<AttrContext> env, CompileState cs) { + CompileState ecs = get(env); + return ecs != null && ecs.isDone(cs); + } + } + private CompileStates compileStates = new CompileStates(); /** The set of currently compiled inputfiles, needed to ensure * we don't accidentally overwrite an input file when -s is set. @@ -454,11 +475,11 @@ return log.nerrors; } - protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) { + protected final <T> Queue<T> stopIfError(Queue<T> queue) { if (errorCount() == 0) - return listBuffer.toList(); + return queue; else - return List.nil(); + return ListBuffer.lb(); } protected final <T> List<T> stopIfError(List<T> list) { @@ -764,8 +785,8 @@ break; case BY_FILE: - for (List<Env<AttrContext>> list : groupByFile(flow(attribute(todo))).values()) - generate(desugar(list)); + for (Queue<Env<AttrContext>> queue : groupByFile(flow(attribute(todo))).values()) + generate(desugar(queue)); break; case BY_TODO: @@ -782,7 +803,7 @@ } if (verbose) { - elapsed_msec = elapsed(start_msec);; + elapsed_msec = elapsed(start_msec); printVerbose("total", Long.toString(elapsed_msec)); } @@ -1020,11 +1041,11 @@ * Attribution of the entries in the list does not stop if any errors occur. * @returns a list of environments for attributd classes. */ - public List<Env<AttrContext>> attribute(ListBuffer<Env<AttrContext>> envs) { + public Queue<Env<AttrContext>> attribute(Queue<Env<AttrContext>> envs) { ListBuffer<Env<AttrContext>> results = lb(); - while (envs.nonEmpty()) - results.append(attribute(envs.next())); - return results.toList(); + while (!envs.isEmpty()) + results.append(attribute(envs.remove())); + return results; } /** @@ -1032,6 +1053,9 @@ * @returns the attributed parse tree */ public Env<AttrContext> attribute(Env<AttrContext> env) { + if (compileStates.isDone(env, CompileState.ATTR)) + return env; + if (verboseCompilePolicy) log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]"); if (verbose) @@ -1048,6 +1072,7 @@ env.toplevel.sourcefile); try { attr.attribClass(env.tree.pos(), env.enclClass.sym); + compileStates.put(env, CompileState.ATTR); } finally { log.useSource(prev); @@ -1062,10 +1087,10 @@ * If any errors occur, an empty list will be returned. * @returns the list of attributed parse trees */ - public List<Env<AttrContext>> flow(List<Env<AttrContext>> envs) { + public Queue<Env<AttrContext>> flow(Queue<Env<AttrContext>> envs) { ListBuffer<Env<AttrContext>> results = lb(); - for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) { - flow(l.head, results); + for (Env<AttrContext> env: envs) { + flow(env, results); } return stopIfError(results); } @@ -1073,7 +1098,7 @@ /** * Perform dataflow checks on an attributed parse tree. */ - public List<Env<AttrContext>> flow(Env<AttrContext> env) { + public Queue<Env<AttrContext>> flow(Env<AttrContext> env) { ListBuffer<Env<AttrContext>> results = lb(); flow(env, results); return stopIfError(results); @@ -1087,7 +1112,7 @@ if (errorCount() > 0) return; - if (relax || deferredSugar.contains(env)) { + if (relax || compileStates.isDone(env, CompileState.FLOW)) { results.append(env); return; } @@ -1102,6 +1127,7 @@ make.at(Position.FIRSTPOS); TreeMaker localMake = make.forToplevel(env.toplevel); flow.analyzeTree(env.tree, localMake); + compileStates.put(env, CompileState.FLOW); if (errorCount() > 0) return; @@ -1126,10 +1152,10 @@ * If any errors occur, an empty list will be returned. * @returns a list containing the classes to be generated */ - public List<Pair<Env<AttrContext>, JCClassDecl>> desugar(List<Env<AttrContext>> envs) { + public Queue<Pair<Env<AttrContext>, JCClassDecl>> desugar(Queue<Env<AttrContext>> envs) { ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb(); - for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) - desugar(l.head, results); + for (Env<AttrContext> env: envs) + desugar(env, results); return stopIfError(results); } @@ -1139,7 +1165,7 @@ * the current implicitSourcePolicy is taken into account. * The preparation stops as soon as an error is found. */ - protected void desugar(Env<AttrContext> env, ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results) { + protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) { if (errorCount() > 0) return; @@ -1148,13 +1174,37 @@ return; } - if (desugarLater(env)) { - if (verboseCompilePolicy) - log.printLines(log.noticeWriter, "[defer " + env.enclClass.sym + "]"); - todo.append(env); + /** + * As erasure (TransTypes) destroys information needed in flow analysis, + * including information in supertypes, we need to ensure that supertypes + * are processed through attribute and flow before subtypes are translated. + */ + class ScanNested extends TreeScanner { + Set<Env<AttrContext>> dependencies = new LinkedHashSet<Env<AttrContext>>(); + public void visitClassDef(JCClassDecl node) { + Type st = types.supertype(node.sym.type); + if (st.tag == TypeTags.CLASS) { + ClassSymbol c = st.tsym.outermostClass(); + Env<AttrContext> stEnv = enter.getEnv(c); + if (stEnv != null && env != stEnv) { + if (dependencies.add(stEnv)) + scan(stEnv.tree); + } + } + super.visitClassDef(node); + } + } + ScanNested scanner = new ScanNested(); + scanner.scan(env.tree); + for (Env<AttrContext> dep: scanner.dependencies) { + if (!compileStates.isDone(dep, CompileState.FLOW)) + flow(attribute(dep)); + } + + //We need to check for error another time as more classes might + //have been attributed and analyzed at this stage + if (errorCount() > 0) return; - } - deferredSugar.remove(env); if (verboseCompilePolicy) log.printLines(log.noticeWriter, "[desugar " + env.enclClass.sym + "]"); @@ -1174,7 +1224,7 @@ List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake); if (pdef.head != null) { assert pdef.tail.isEmpty(); - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head)); + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head)); } } return; @@ -1188,7 +1238,7 @@ rootClasses.contains((JCClassDecl)untranslated) && ((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 || cdef.sym.packge().getQualifiedName() == names.java_lang)) { - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef))); + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef))); } return; } @@ -1204,7 +1254,7 @@ JCClassDecl cdef = (JCClassDecl)env.tree; if (untranslated instanceof JCClassDecl && rootClasses.contains((JCClassDecl)untranslated)) { - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); } return; } @@ -1218,7 +1268,7 @@ //generate code for each class for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) { JCClassDecl cdef = (JCClassDecl)l.head; - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); } } finally { @@ -1227,57 +1277,19 @@ } - /** - * Determine if a class needs to be desugared later. As erasure - * (TransTypes) destroys information needed in flow analysis, we - * need to ensure that supertypes are translated before derived - * types are translated. - */ - public boolean desugarLater(final Env<AttrContext> env) { - if (compilePolicy == CompilePolicy.BY_FILE) - return false; - if (!devVerbose && deferredSugar.contains(env)) - // guarantee that compiler terminates - return false; - class ScanNested extends TreeScanner { - Set<Symbol> externalSupers = new HashSet<Symbol>(); - public void visitClassDef(JCClassDecl node) { - Type st = types.supertype(node.sym.type); - if (st.tag == TypeTags.CLASS) { - ClassSymbol c = st.tsym.outermostClass(); - Env<AttrContext> stEnv = enter.getEnv(c); - if (stEnv != null && env != stEnv) - externalSupers.add(st.tsym); - } - super.visitClassDef(node); - } - } - ScanNested scanner = new ScanNested(); - scanner.scan(env.tree); - if (scanner.externalSupers.isEmpty()) - return false; - if (!deferredSugar.add(env) && devVerbose) { - throw new AssertionError(env.enclClass.sym + " was deferred, " + - "second time has these external super types " + - scanner.externalSupers); - } - return true; - } - /** Generates the source or class file for a list of classes. * The decision to generate a source file or a class file is * based upon the compiler's options. * Generation stops if an error occurs while writing files. */ - public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list) { - generate(list, null); + public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) { + generate(queue, null); } - public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list, ListBuffer<JavaFileObject> results) { + public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, ListBuffer<JavaFileObject> results) { boolean usePrintSource = (stubOutput || sourceOutput || printFlat); - for (List<Pair<Env<AttrContext>, JCClassDecl>> l = list; l.nonEmpty(); l = l.tail) { - Pair<Env<AttrContext>, JCClassDecl> x = l.head; + for (Pair<Env<AttrContext>, JCClassDecl> x: queue) { Env<AttrContext> env = x.fst; JCClassDecl cdef = x.snd; @@ -1319,26 +1331,17 @@ } // where - Map<JCCompilationUnit, List<Env<AttrContext>>> groupByFile(List<Env<AttrContext>> list) { + Map<JCCompilationUnit, Queue<Env<AttrContext>>> groupByFile(Queue<Env<AttrContext>> envs) { // use a LinkedHashMap to preserve the order of the original list as much as possible - Map<JCCompilationUnit, List<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, List<Env<AttrContext>>>(); - Set<JCCompilationUnit> fixupSet = new HashSet<JCTree.JCCompilationUnit>(); - for (List<Env<AttrContext>> l = list; l.nonEmpty(); l = l.tail) { - Env<AttrContext> env = l.head; - List<Env<AttrContext>> sublist = map.get(env.toplevel); - if (sublist == null) - sublist = List.of(env); - else { - // this builds the list for the file in reverse order, so make a note - // to reverse the list before returning. - sublist = sublist.prepend(env); - fixupSet.add(env.toplevel); + Map<JCCompilationUnit, Queue<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, Queue<Env<AttrContext>>>(); + for (Env<AttrContext> env: envs) { + Queue<Env<AttrContext>> sublist = map.get(env.toplevel); + if (sublist == null) { + sublist = new ListBuffer<Env<AttrContext>>(); + map.put(env.toplevel, sublist); } - map.put(env.toplevel, sublist); + sublist.add(env); } - // fixup any lists that need reversing back to the correct order - for (JCTree.JCCompilationUnit tree: fixupSet) - map.put(tree, map.get(tree).reverse()); return map; }
--- a/src/share/classes/com/sun/tools/javac/util/ListBuffer.java Wed Jun 16 17:15:44 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/ListBuffer.java Fri Jun 18 11:13:26 2010 -0700 @@ -25,6 +25,7 @@ package com.sun.tools.javac.util; +import java.util.AbstractQueue; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; @@ -37,12 +38,18 @@ * This code and its internal interfaces are subject to change or * deletion without notice.</b> */ -public class ListBuffer<A> implements Collection<A> { +public class ListBuffer<A> extends AbstractQueue<A> { public static <T> ListBuffer<T> lb() { return new ListBuffer<T>(); } + public static <T> ListBuffer<T> of(T x) { + ListBuffer<T> lb = new ListBuffer<T>(); + lb.add(x); + return lb; + } + /** The list of elements of this buffer. */ public List<A> elems; @@ -119,6 +126,7 @@ /** Append an element to buffer. */ public ListBuffer<A> append(A x) { + x.getClass(); // null check if (shared) copy(); last.head = x; last.setTail(new List<A>(null,null)); @@ -180,20 +188,14 @@ return elems.head; } - /** Remove the first element in this buffer. + /** Return first element in this buffer and remove */ - public void remove() { + public A next() { + A x = elems.head; if (elems != last) { elems = elems.tail; count--; } - } - - /** Return first element in this buffer and remove - */ - public A next() { - A x = elems.head; - remove(); return x; } @@ -219,21 +221,46 @@ } public boolean add(A a) { - throw new UnsupportedOperationException(); + append(a); + return true; } + public boolean remove(Object o) { throw new UnsupportedOperationException(); } + public boolean containsAll(Collection<?> c) { - throw new UnsupportedOperationException(); + for (Object x: c) { + if (!contains(x)) + return false; + } + return true; } + public boolean addAll(Collection<? extends A> c) { - throw new UnsupportedOperationException(); + for (A a: c) + append(a); + return true; } + public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); } + public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } + + public boolean offer(A a) { + append(a); + return true; + } + + public A poll() { + return next(); + } + + public A peek() { + return first(); + } }
--- a/test/tools/javac/6199662/Tree.java Wed Jun 16 17:15:44 2010 -0700 +++ b/test/tools/javac/6199662/Tree.java Fri Jun 18 11:13:26 2010 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 6199662 6325201 + * @bug 6199662 6325201 6726015 * @summary javac: compilation success depends on compilation order * * @compile Tree.java TreeScanner.java TreeInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/6734819/T6734819a.java Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6734819 + * @summary Javac performs flows analysis on already translated classes + * @author Maurizio Cimadamore + * + * @compile/ref=T6734819a.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819a.java + */ +class Y extends W {} +class W extends Z {} + +class Z { + void m(Z z) { + W w = (W)z; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/6734819/T6734819a.out Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,12 @@ +[attribute Y] +[flow Y] +[attribute W] +[flow W] +[attribute Z] +[flow Z] +[desugar Y] +[generate code Y] +[desugar W] +[generate code W] +[desugar Z] +[generate code Z]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/6734819/T6734819b.java Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6734819 + * @summary Javac performs flows analysis on already translated classes + * @author Maurizio Cimadamore + * + * @compile/ref=T6734819b.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819b.java + */ +class A extends B {} +class B { + class C extends B {} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/6734819/T6734819b.out Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,9 @@ +[attribute A] +[flow A] +[attribute B] +[flow B] +[desugar A] +[generate code A] +[desugar B] +[generate code B] +[generate code B]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/6734819/T6734819c.java Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6734819 + * @summary Javac performs flows analysis on already translated classes + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6734819c.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819c.java + */ +class Y extends W {} +class W extends Z {} + +class Z { + void m(Z z) { + return; + W w = (W)z; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/6734819/T6734819c.out Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,8 @@ +[attribute Y] +[flow Y] +[attribute W] +[flow W] +[attribute Z] +[flow Z] +T6734819c.java:38:11: compiler.err.unreachable.stmt +1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T6956638.java Fri Jun 18 11:13:26 2010 -0700 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2010, 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. + */ + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.lang.model.element.Element; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.util.JavacTask; + +/** + * @test + * @bug 6956638 + * @summary JavacTask.generate does not generate all required files + */ +public class T6956638 { + public static void main(String[] args) throws Exception { + new T6956638().run(); + } + + void run() throws Exception { + File srcDir = new File("src"); + + File[] files = { + writeFile(new File(srcDir, "T1.java"), + "public class T1 extends T2 {}\n"), + writeFile(new File(srcDir, "T2.java"), + "public class T2 extends T3 {}\n"), + writeFile(new File(srcDir, "T3.java"), + "public class T3 { public static final int C = 1; }\n"), + writeFile(new File(srcDir, "Test.java"), + "public class Test { public static final int D = T1.C; }\n") + }; + + for (File f1: files) { + for (File f2: files) { + if (f2 == f1) continue; + for (File f3: files) { + if (f3 == f2 || f3 == f1) continue; + for (File f4: files) { + if (f4 == f3 || f4 == f2 || f4 == f1) continue; + try { + test(f1, f2, f3, f4); + } catch (Exception e) { + error(e); + } + } + } + } + } + + if (errors > 0) + throw new Exception(errors + " tests failed"); + } + + void test(File... sourceFiles) throws Exception { + System.err.println("Test " + (++count) + ": " + Arrays.asList(sourceFiles)); + + File classesDir = new File("classes" + count); + classesDir.mkdirs(); + + StringWriter compilerOutputStream = new StringWriter(); + + List<String> compileOptions = Arrays.asList("-d", classesDir.getPath()); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null); + Iterable<? extends JavaFileObject> sourceFileObjects = fileManager.getJavaFileObjects(sourceFiles); + System.err.println("1- javac given java source JavaFileObjects " + sourceFileObjects); + JavaCompiler.CompilationTask task = compiler.getTask(compilerOutputStream, fileManager, null, compileOptions, null, sourceFileObjects); + JavacTask javacTask = (JavacTask) task; + + Iterable<? extends CompilationUnitTree> parsedTrees = javacTask.parse(); + Iterable<? extends Element> analyzedTrees = javacTask.analyze(); + Iterable<? extends JavaFileObject> generatedFiles = javacTask.generate(); + + System.err.println("2- parsed:" + size(parsedTrees) + " analysed:" + size(analyzedTrees) + " generated:" + size(generatedFiles)); + + System.err.print("3-"); + for (JavaFileObject f : generatedFiles) + System.err.print(" " + f); + System.err.println(""); + + System.err.print("5-"); + for (File f : classesDir.listFiles()) + System.err.print(" " + f); + System.err.println(""); + + System.err.println("----"); + System.err.println(compilerOutputStream.toString()); + + if (size(generatedFiles) != size(parsedTrees)) { + throw new Exception("wrong number of files generated: " + size(generatedFiles) + + " expected: " + size(parsedTrees)); + } + } + + private void error(Throwable t) { + t.printStackTrace(); + errors++; + } + + int count; + int errors; + + private static <E> int size(Iterable<E> x) { + int n = 0; + for (Iterator<E> iter = x.iterator(); iter.hasNext(); ++n) + iter.next(); + return n; + } + + private static File writeFile(File f, String str) throws IOException { + f.getParentFile().mkdirs(); + BufferedWriter fout = new BufferedWriter(new FileWriter(f)); + try { + fout.write(str); + fout.flush(); + } finally { + fout.close(); + } + return f; + } +}