Tue, 07 Sep 2010 17:33:43 +0100
6970584: Flow.java should be more error-friendly
Summary: Added a post-attribution visitor that fixup uninitialized types/symbol in AST after erroneous attribution
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java Tue Sep 07 17:32:52 2010 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java Tue Sep 07 17:33:43 2010 +0100 1.3 @@ -93,6 +93,10 @@ 1.4 */ 1.5 public final ClassSymbol errSymbol; 1.6 1.7 + /** The unknown symbol. 1.8 + */ 1.9 + public final ClassSymbol unknownSymbol; 1.10 + 1.11 /** A value for the errType, with a originalType of noType */ 1.12 public final Type errType; 1.13 1.14 @@ -354,6 +358,7 @@ 1.15 1.16 // create the error symbols 1.17 errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage); 1.18 + unknownSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.fromString("<any?>"), null, rootPackage); 1.19 errType = new ErrorType(errSymbol, Type.noType); 1.20 1.21 // initialize builtin types 1.22 @@ -368,7 +373,7 @@ 1.23 initType(voidType, "void", "Void"); 1.24 initType(botType, "<nulltype>"); 1.25 initType(errType, errSymbol); 1.26 - initType(unknownType, "<any?>"); 1.27 + initType(unknownType, unknownSymbol); 1.28 1.29 // the builtin class of all arrays 1.30 arrayClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Array, noSymbol);
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Sep 07 17:32:52 2010 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Sep 07 17:33:43 2010 +0100 2.3 @@ -182,6 +182,7 @@ 2.4 if (!method.type.isErroneous()) 2.5 buf.append(new Pair<MethodSymbol,Attribute> 2.6 ((MethodSymbol)method, value)); 2.7 + t.type = result; 2.8 } 2.9 return new Attribute.Compound(a.type, buf.toList()); 2.10 } 2.11 @@ -234,6 +235,7 @@ 2.12 l.head, 2.13 env)); 2.14 } 2.15 + na.type = expected; 2.16 return new Attribute. 2.17 Array(expected, buf.toArray(new Attribute[buf.length()])); 2.18 }
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Sep 07 17:32:52 2010 +0100 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Sep 07 17:33:43 2010 +0100 3.3 @@ -3201,4 +3201,104 @@ 3.4 super.visitMethodDef(tree); 3.5 } 3.6 }; 3.7 + 3.8 + // <editor-fold desc="post-attribution visitor"> 3.9 + 3.10 + /** 3.11 + * Handle missing types/symbols in an AST. This routine is useful when 3.12 + * the compiler has encountered some errors (which might have ended up 3.13 + * terminating attribution abruptly); if the compiler is used in fail-over 3.14 + * mode (e.g. by an IDE) and the AST contains semantic errors, this routine 3.15 + * prevents NPE to be progagated during subsequent compilation steps. 3.16 + */ 3.17 + public void postAttr(Env<AttrContext> env) { 3.18 + new PostAttrAnalyzer().scan(env.tree); 3.19 + } 3.20 + 3.21 + class PostAttrAnalyzer extends TreeScanner { 3.22 + 3.23 + private void initTypeIfNeeded(JCTree that) { 3.24 + if (that.type == null) { 3.25 + that.type = syms.unknownType; 3.26 + } 3.27 + } 3.28 + 3.29 + @Override 3.30 + public void scan(JCTree tree) { 3.31 + if (tree == null) return; 3.32 + if (tree instanceof JCExpression) { 3.33 + initTypeIfNeeded(tree); 3.34 + } 3.35 + super.scan(tree); 3.36 + } 3.37 + 3.38 + @Override 3.39 + public void visitIdent(JCIdent that) { 3.40 + if (that.sym == null) { 3.41 + that.sym = syms.unknownSymbol; 3.42 + } 3.43 + } 3.44 + 3.45 + @Override 3.46 + public void visitSelect(JCFieldAccess that) { 3.47 + if (that.sym == null) { 3.48 + that.sym = syms.unknownSymbol; 3.49 + } 3.50 + super.visitSelect(that); 3.51 + } 3.52 + 3.53 + @Override 3.54 + public void visitClassDef(JCClassDecl that) { 3.55 + initTypeIfNeeded(that); 3.56 + if (that.sym == null) { 3.57 + that.sym = new ClassSymbol(0, that.name, that.type, syms.noSymbol); 3.58 + } 3.59 + super.visitClassDef(that); 3.60 + } 3.61 + 3.62 + @Override 3.63 + public void visitMethodDef(JCMethodDecl that) { 3.64 + initTypeIfNeeded(that); 3.65 + if (that.sym == null) { 3.66 + that.sym = new MethodSymbol(0, that.name, that.type, syms.noSymbol); 3.67 + } 3.68 + super.visitMethodDef(that); 3.69 + } 3.70 + 3.71 + @Override 3.72 + public void visitVarDef(JCVariableDecl that) { 3.73 + initTypeIfNeeded(that); 3.74 + if (that.sym == null) { 3.75 + that.sym = new VarSymbol(0, that.name, that.type, syms.noSymbol); 3.76 + that.sym.adr = 0; 3.77 + } 3.78 + super.visitVarDef(that); 3.79 + } 3.80 + 3.81 + @Override 3.82 + public void visitNewClass(JCNewClass that) { 3.83 + if (that.constructor == null) { 3.84 + that.constructor = new MethodSymbol(0, names.init, syms.unknownType, syms.noSymbol); 3.85 + } 3.86 + if (that.constructorType == null) { 3.87 + that.constructorType = syms.unknownType; 3.88 + } 3.89 + super.visitNewClass(that); 3.90 + } 3.91 + 3.92 + @Override 3.93 + public void visitBinary(JCBinary that) { 3.94 + if (that.operator == null) 3.95 + that.operator = new OperatorSymbol(names.empty, syms.unknownType, -1, syms.noSymbol); 3.96 + super.visitBinary(that); 3.97 + } 3.98 + 3.99 + @Override 3.100 + public void visitUnary(JCUnary that) { 3.101 + if (that.operator == null) 3.102 + that.operator = new OperatorSymbol(names.empty, syms.unknownType, -1, syms.noSymbol); 3.103 + super.visitUnary(that); 3.104 + } 3.105 + } 3.106 + // </editor-fold> 3.107 }
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Sep 07 17:32:52 2010 +0100 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Sep 07 17:33:43 2010 +0100 4.3 @@ -408,7 +408,9 @@ 4.4 tree = TreeInfo.skipParens(tree); 4.5 if (tree.getTag() == JCTree.IDENT || tree.getTag() == JCTree.SELECT) { 4.6 Symbol sym = TreeInfo.symbol(tree); 4.7 - letInit(tree.pos(), (VarSymbol)sym); 4.8 + if (sym.kind == VAR) { 4.9 + letInit(tree.pos(), (VarSymbol)sym); 4.10 + } 4.11 } 4.12 } 4.13 4.14 @@ -481,12 +483,13 @@ 4.15 4.16 /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets 4.17 */ 4.18 - void split() { 4.19 + void split(boolean setToNull) { 4.20 initsWhenFalse = inits.dup(); 4.21 uninitsWhenFalse = uninits.dup(); 4.22 initsWhenTrue = inits; 4.23 uninitsWhenTrue = uninits; 4.24 - inits = uninits = null; 4.25 + if (setToNull) 4.26 + inits = uninits = null; 4.27 } 4.28 4.29 /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. 4.30 @@ -568,9 +571,11 @@ 4.31 uninitsWhenTrue = uninits; 4.32 } else { 4.33 scan(tree); 4.34 - if (inits != null) split(); 4.35 + if (inits != null) 4.36 + split(tree.type != syms.unknownType); 4.37 } 4.38 - inits = uninits = null; 4.39 + if (tree.type != syms.unknownType) 4.40 + inits = uninits = null; 4.41 } 4.42 4.43 /* ------------ Visitor methods for various sorts of trees -------------*/ 4.44 @@ -1007,7 +1012,7 @@ 4.45 List.of(resource.type); 4.46 for (Type sup : closeableSupertypes) { 4.47 if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) { 4.48 - Symbol closeMethod = rs.resolveInternalMethod(tree, 4.49 + Symbol closeMethod = rs.resolveQualifiedMethod(tree, 4.50 attrEnv, 4.51 sup, 4.52 names.close, 4.53 @@ -1050,20 +1055,22 @@ 4.54 List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry); 4.55 for (JCExpression ct : subClauses) { 4.56 Type exc = ct.type; 4.57 - ctypes = ctypes.append(exc); 4.58 - if (types.isSameType(exc, syms.objectType)) 4.59 - continue; 4.60 - if (chk.subset(exc, caughtInTry)) { 4.61 - log.error(l.head.pos(), 4.62 - "except.already.caught", exc); 4.63 - } else if (!chk.isUnchecked(l.head.pos(), exc) && 4.64 - exc.tsym != syms.throwableType.tsym && 4.65 - exc.tsym != syms.exceptionType.tsym && 4.66 - !chk.intersects(exc, thrownInTry)) { 4.67 - log.error(l.head.pos(), 4.68 - "except.never.thrown.in.try", exc); 4.69 + if (exc != syms.unknownType) { 4.70 + ctypes = ctypes.append(exc); 4.71 + if (types.isSameType(exc, syms.objectType)) 4.72 + continue; 4.73 + if (chk.subset(exc, caughtInTry)) { 4.74 + log.error(l.head.pos(), 4.75 + "except.already.caught", exc); 4.76 + } else if (!chk.isUnchecked(l.head.pos(), exc) && 4.77 + exc.tsym != syms.throwableType.tsym && 4.78 + exc.tsym != syms.exceptionType.tsym && 4.79 + !chk.intersects(exc, thrownInTry)) { 4.80 + log.error(l.head.pos(), 4.81 + "except.never.thrown.in.try", exc); 4.82 + } 4.83 + caughtInTry = chk.incl(exc, caughtInTry); 4.84 } 4.85 - caughtInTry = chk.incl(exc, caughtInTry); 4.86 } 4.87 inits = initsTry.dup(); 4.88 uninits = uninitsTry.dup();
5.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Sep 07 17:32:52 2010 +0100 5.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Sep 07 17:33:43 2010 +0100 5.3 @@ -1144,6 +1144,11 @@ 5.4 env.toplevel.sourcefile); 5.5 try { 5.6 attr.attribClass(env.tree.pos(), env.enclClass.sym); 5.7 + if (errorCount() > 0 && !shouldStop(CompileState.ATTR)) { 5.8 + //if in fail-over mode, ensure that AST expression nodes 5.9 + //are correctly initialized (e.g. they have a type/symbol) 5.10 + attr.postAttr(env); 5.11 + } 5.12 compileStates.put(env, CompileState.ATTR); 5.13 } 5.14 finally {
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/failover/CheckAttributedTree.java Tue Sep 07 17:33:43 2010 +0100 6.3 @@ -0,0 +1,775 @@ 6.4 +/* 6.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +import com.sun.source.util.TaskEvent; 6.28 +import java.awt.BorderLayout; 6.29 +import java.awt.Color; 6.30 +import java.awt.Dimension; 6.31 +import java.awt.EventQueue; 6.32 +import java.awt.Font; 6.33 +import java.awt.GridBagConstraints; 6.34 +import java.awt.GridBagLayout; 6.35 +import java.awt.Rectangle; 6.36 +import java.awt.event.ActionEvent; 6.37 +import java.awt.event.ActionListener; 6.38 +import java.awt.event.MouseAdapter; 6.39 +import java.awt.event.MouseEvent; 6.40 +import javax.swing.DefaultComboBoxModel; 6.41 +import javax.swing.JComboBox; 6.42 +import javax.swing.JComponent; 6.43 +import javax.swing.JFrame; 6.44 +import javax.swing.JLabel; 6.45 +import javax.swing.JPanel; 6.46 +import javax.swing.JScrollPane; 6.47 +import javax.swing.JTextArea; 6.48 +import javax.swing.JTextField; 6.49 +import javax.swing.SwingUtilities; 6.50 +import javax.swing.event.CaretEvent; 6.51 +import javax.swing.event.CaretListener; 6.52 +import javax.swing.text.BadLocationException; 6.53 +import javax.swing.text.DefaultHighlighter; 6.54 +import javax.swing.text.Highlighter; 6.55 +import java.io.File; 6.56 +import java.io.IOException; 6.57 +import java.io.PrintStream; 6.58 +import java.io.PrintWriter; 6.59 +import java.io.StringWriter; 6.60 +import java.lang.reflect.Field; 6.61 +import java.lang.reflect.Modifier; 6.62 +import java.nio.charset.Charset; 6.63 +import java.util.ArrayList; 6.64 +import java.util.HashMap; 6.65 +import java.util.List; 6.66 +import java.util.Map; 6.67 +import javax.tools.Diagnostic; 6.68 +import javax.tools.DiagnosticListener; 6.69 +import javax.tools.JavaFileObject; 6.70 +import javax.tools.StandardJavaFileManager; 6.71 + 6.72 +import com.sun.source.tree.CompilationUnitTree; 6.73 +import com.sun.source.util.JavacTask; 6.74 +import com.sun.source.util.TaskListener; 6.75 +import com.sun.tools.javac.api.JavacTool; 6.76 +import com.sun.tools.javac.code.Symbol; 6.77 +import com.sun.tools.javac.code.Type; 6.78 +import com.sun.tools.javac.tree.JCTree; 6.79 +import com.sun.tools.javac.tree.JCTree.JCClassDecl; 6.80 +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 6.81 +import com.sun.tools.javac.tree.JCTree.JCImport; 6.82 +import com.sun.tools.javac.tree.TreeInfo; 6.83 +import com.sun.tools.javac.tree.TreeScanner; 6.84 +import com.sun.tools.javac.util.Pair; 6.85 + 6.86 +import java.util.Arrays; 6.87 +import java.util.HashSet; 6.88 +import java.util.Set; 6.89 +import javax.lang.model.element.Element; 6.90 + 6.91 +/** 6.92 + * Utility and test program to check validity of tree positions for tree nodes. 6.93 + * The program can be run standalone, or as a jtreg test. In standalone mode, 6.94 + * errors can be displayed in a gui viewer. For info on command line args, 6.95 + * run program with no args. 6.96 + * 6.97 + * <p> 6.98 + * jtreg: Note that by using the -r switch in the test description below, this test 6.99 + * will process all java files in the langtools/test directory, thus implicitly 6.100 + * covering any new language features that may be tested in this test suite. 6.101 + */ 6.102 + 6.103 +/* 6.104 + * @test 6.105 + * @bug 6970584 6.106 + * @summary assorted position errors in compiler syntax trees 6.107 + * @run main CheckAttributedTree -q -r -et ERRONEOUS . 6.108 + */ 6.109 +public class CheckAttributedTree { 6.110 + /** 6.111 + * Main entry point. 6.112 + * If test.src is set, program runs in jtreg mode, and will throw an Error 6.113 + * if any errors arise, otherwise System.exit will be used, unless the gui 6.114 + * viewer is being used. In jtreg mode, the default base directory for file 6.115 + * args is the value of ${test.src}. In jtreg mode, the -r option can be 6.116 + * given to change the default base directory to the root test directory. 6.117 + */ 6.118 + public static void main(String... args) { 6.119 + String testSrc = System.getProperty("test.src"); 6.120 + File baseDir = (testSrc == null) ? null : new File(testSrc); 6.121 + boolean ok = new CheckAttributedTree().run(baseDir, args); 6.122 + if (!ok) { 6.123 + if (testSrc != null) // jtreg mode 6.124 + throw new Error("failed"); 6.125 + else 6.126 + System.exit(1); 6.127 + } 6.128 + } 6.129 + 6.130 + /** 6.131 + * Run the program. A base directory can be provided for file arguments. 6.132 + * In jtreg mode, the -r option can be given to change the default base 6.133 + * directory to the test root directory. For other options, see usage(). 6.134 + * @param baseDir base directory for any file arguments. 6.135 + * @param args command line args 6.136 + * @return true if successful or in gui mode 6.137 + */ 6.138 + boolean run(File baseDir, String... args) { 6.139 + if (args.length == 0) { 6.140 + usage(System.out); 6.141 + return true; 6.142 + } 6.143 + 6.144 + List<File> files = new ArrayList<File>(); 6.145 + for (int i = 0; i < args.length; i++) { 6.146 + String arg = args[i]; 6.147 + if (arg.equals("-encoding") && i + 1 < args.length) 6.148 + encoding = args[++i]; 6.149 + else if (arg.equals("-gui")) 6.150 + gui = true; 6.151 + else if (arg.equals("-q")) 6.152 + quiet = true; 6.153 + else if (arg.equals("-v")) 6.154 + verbose = true; 6.155 + else if (arg.equals("-t") && i + 1 < args.length) 6.156 + tags.add(args[++i]); 6.157 + else if (arg.equals("-ef") && i + 1 < args.length) 6.158 + excludeFiles.add(new File(baseDir, args[++i])); 6.159 + else if (arg.equals("-et") && i + 1 < args.length) 6.160 + excludeTags.add(args[++i]); 6.161 + else if (arg.equals("-r")) { 6.162 + if (excludeFiles.size() > 0) 6.163 + throw new Error("-r must be used before -ef"); 6.164 + File d = baseDir; 6.165 + while (!new File(d, "TEST.ROOT").exists()) { 6.166 + if (d == null) 6.167 + throw new Error("cannot find TEST.ROOT"); 6.168 + d = d.getParentFile(); 6.169 + } 6.170 + baseDir = d; 6.171 + } 6.172 + else if (arg.startsWith("-")) 6.173 + throw new Error("unknown option: " + arg); 6.174 + else { 6.175 + while (i < args.length) 6.176 + files.add(new File(baseDir, args[i++])); 6.177 + } 6.178 + } 6.179 + 6.180 + for (File file: files) { 6.181 + if (file.exists()) 6.182 + test(file); 6.183 + else 6.184 + error("File not found: " + file); 6.185 + } 6.186 + 6.187 + if (fileCount != 1) 6.188 + System.err.println(fileCount + " files read"); 6.189 + if (errors > 0) 6.190 + System.err.println(errors + " errors"); 6.191 + 6.192 + return (gui || errors == 0); 6.193 + } 6.194 + 6.195 + /** 6.196 + * Print command line help. 6.197 + * @param out output stream 6.198 + */ 6.199 + void usage(PrintStream out) { 6.200 + out.println("Usage:"); 6.201 + out.println(" java CheckAttributedTree options... files..."); 6.202 + out.println(""); 6.203 + out.println("where options include:"); 6.204 + out.println("-q Quiet: don't report on inapplicable files"); 6.205 + out.println("-gui Display returns in a GUI viewer"); 6.206 + out.println("-v Verbose: report on files as they are being read"); 6.207 + out.println("-t tag Limit checks to tree nodes with this tag"); 6.208 + out.println(" Can be repeated if desired"); 6.209 + out.println("-ef file Exclude file or directory"); 6.210 + out.println("-et tag Exclude tree nodes with given tag name"); 6.211 + out.println(""); 6.212 + out.println("files may be directories or files"); 6.213 + out.println("directories will be scanned recursively"); 6.214 + out.println("non java files, or java files which cannot be parsed, will be ignored"); 6.215 + out.println(""); 6.216 + } 6.217 + 6.218 + /** 6.219 + * Test a file. If the file is a directory, it will be recursively scanned 6.220 + * for java files. 6.221 + * @param file the file or directory to test 6.222 + */ 6.223 + void test(File file) { 6.224 + if (excludeFiles.contains(file)) { 6.225 + if (!quiet) 6.226 + error("File " + file + " excluded"); 6.227 + return; 6.228 + } 6.229 + 6.230 + if (file.isDirectory()) { 6.231 + for (File f: file.listFiles()) { 6.232 + test(f); 6.233 + } 6.234 + return; 6.235 + } 6.236 + 6.237 + if (file.isFile() && file.getName().endsWith(".java")) { 6.238 + try { 6.239 + if (verbose) 6.240 + System.err.println(file); 6.241 + fileCount++; 6.242 + NPETester p = new NPETester(); 6.243 + p.test(read(file)); 6.244 + } catch (AttributionException e) { 6.245 + if (!quiet) { 6.246 + error("Error attributing " + file + "\n" + e.getMessage()); 6.247 + } 6.248 + } catch (IOException e) { 6.249 + error("Error reading " + file + ": " + e); 6.250 + } 6.251 + return; 6.252 + } 6.253 + 6.254 + if (!quiet) 6.255 + error("File " + file + " ignored"); 6.256 + } 6.257 + 6.258 + /** 6.259 + * Read a file. 6.260 + * @param file the file to be read 6.261 + * @return the tree for the content of the file 6.262 + * @throws IOException if any IO errors occur 6.263 + * @throws TreePosTest.ParseException if any errors occur while parsing the file 6.264 + */ 6.265 + List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException { 6.266 + StringWriter sw = new StringWriter(); 6.267 + PrintWriter pw = new PrintWriter(sw); 6.268 + Reporter r = new Reporter(pw); 6.269 + JavacTool tool = JavacTool.create(); 6.270 + Charset cs = (encoding == null ? null : Charset.forName(encoding)); 6.271 + StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); 6.272 + Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file); 6.273 + String[] opts = { "-XDshouldStopPolicy=ATTR", "-XDverboseCompilePolicy" }; 6.274 + JavacTask task = tool.getTask(pw, fm, r, Arrays.asList(opts), null, files); 6.275 + final List<Element> analyzedElems = new ArrayList<>(); 6.276 + task.setTaskListener(new TaskListener() { 6.277 + public void started(TaskEvent e) { 6.278 + if (e.getKind() == TaskEvent.Kind.ANALYZE) 6.279 + analyzedElems.add(e.getTypeElement()); 6.280 + } 6.281 + public void finished(TaskEvent e) { } 6.282 + }); 6.283 + 6.284 + try { 6.285 + Iterable<? extends CompilationUnitTree> trees = task.parse(); 6.286 + task.analyze(); 6.287 + List<Pair<JCCompilationUnit, JCTree>> res = new ArrayList<>(); 6.288 + System.out.println("Try to add pairs. Elems are " + analyzedElems); 6.289 + for (CompilationUnitTree t : trees) { 6.290 + JCCompilationUnit cu = (JCCompilationUnit)t; 6.291 + for (JCTree def : cu.defs) { 6.292 + if (def.getTag() == JCTree.CLASSDEF && 6.293 + analyzedElems.contains(((JCTree.JCClassDecl)def).sym)) { 6.294 + System.out.println("Adding pair..."); 6.295 + res.add(new Pair<>(cu, def)); 6.296 + } 6.297 + } 6.298 + } 6.299 + return res; 6.300 + } 6.301 + catch (Throwable t) { 6.302 + throw new AttributionException("Exception while attributing file: " + file); 6.303 + } 6.304 + } 6.305 + 6.306 + /** 6.307 + * Report an error. When the program is complete, the program will either 6.308 + * exit or throw an Error if any errors have been reported. 6.309 + * @param msg the error message 6.310 + */ 6.311 + void error(String msg) { 6.312 + System.err.println(msg); 6.313 + errors++; 6.314 + } 6.315 + 6.316 + /** Number of files that have been analyzed. */ 6.317 + int fileCount; 6.318 + /** Number of errors reported. */ 6.319 + int errors; 6.320 + /** Flag: don't report irrelevant files. */ 6.321 + boolean quiet; 6.322 + /** Flag: show errors in GUI viewer. */ 6.323 + boolean gui; 6.324 + /** The GUI viewer for errors. */ 6.325 + Viewer viewer; 6.326 + /** Flag: report files as they are processed. */ 6.327 + boolean verbose; 6.328 + /** Option: encoding for test files. */ 6.329 + String encoding; 6.330 + /** The set of tags for tree nodes to be analyzed; if empty, all tree nodes 6.331 + * are analyzed. */ 6.332 + Set<String> tags = new HashSet<String>(); 6.333 + /** Set of files and directories to be excluded from analysis. */ 6.334 + Set<File> excludeFiles = new HashSet<File>(); 6.335 + /** Set of tag names to be excluded from analysis. */ 6.336 + Set<String> excludeTags = new HashSet<String>(); 6.337 + /** Utility class for trees */ 6.338 + TreeUtil treeUtil = new TreeUtil(); 6.339 + 6.340 + /** 6.341 + * Main class for testing assertions concerning types/symbol 6.342 + * left uninitialized after attribution 6.343 + */ 6.344 + private class NPETester extends TreeScanner { 6.345 + void test(List<Pair<JCCompilationUnit, JCTree>> trees) { 6.346 + for (Pair<JCCompilationUnit, JCTree> p : trees) { 6.347 + sourcefile = p.fst.sourcefile; 6.348 + endPosTable = p.fst.endPositions; 6.349 + encl = new Info(p.snd, endPosTable); 6.350 + p.snd.accept(this); 6.351 + } 6.352 + } 6.353 + 6.354 + @Override 6.355 + public void scan(JCTree tree) { 6.356 + if (tree == null || 6.357 + excludeTags.contains(treeUtil.nameFromTag(tree.getTag()))) { 6.358 + return; 6.359 + } 6.360 + 6.361 + Info self = new Info(tree, endPosTable); 6.362 + check(!mandatoryType(tree) || 6.363 + (tree.type != null && 6.364 + checkFields(tree)), 6.365 + "'null' found in tree ", 6.366 + self); 6.367 + 6.368 + Info prevEncl = encl; 6.369 + encl = self; 6.370 + tree.accept(this); 6.371 + encl = prevEncl; 6.372 + } 6.373 + 6.374 + private boolean mandatoryType(JCTree that) { 6.375 + return that instanceof JCTree.JCExpression || 6.376 + that.getTag() == JCTree.VARDEF || 6.377 + that.getTag() == JCTree.METHODDEF || 6.378 + that.getTag() == JCTree.CLASSDEF; 6.379 + } 6.380 + 6.381 + private final List<String> excludedFields = Arrays.asList("varargsElement"); 6.382 + 6.383 + void check(boolean ok, String label, Info self) { 6.384 + if (!ok) { 6.385 + if (gui) { 6.386 + if (viewer == null) 6.387 + viewer = new Viewer(); 6.388 + viewer.addEntry(sourcefile, label, encl, self); 6.389 + } 6.390 + error(label + self.toString() + " encl: " + encl.toString() + " in file: " + sourcefile + " " + self.tree); 6.391 + } 6.392 + } 6.393 + 6.394 + boolean checkFields(JCTree t) { 6.395 + List<Field> fieldsToCheck = treeUtil.getFieldsOfType(t, 6.396 + excludedFields, 6.397 + Symbol.class, 6.398 + Type.class); 6.399 + for (Field f : fieldsToCheck) { 6.400 + try { 6.401 + if (f.get(t) == null) { 6.402 + return false; 6.403 + } 6.404 + } 6.405 + catch (IllegalAccessException e) { 6.406 + System.err.println("Cannot read field: " + f); 6.407 + //swallow it 6.408 + } 6.409 + } 6.410 + return true; 6.411 + } 6.412 + 6.413 + @Override 6.414 + public void visitImport(JCImport tree) { } 6.415 + 6.416 + @Override 6.417 + public void visitTopLevel(JCCompilationUnit tree) { 6.418 + scan(tree.defs); 6.419 + } 6.420 + 6.421 + JavaFileObject sourcefile; 6.422 + Map<JCTree, Integer> endPosTable; 6.423 + Info encl; 6.424 + } 6.425 + 6.426 + /** 6.427 + * Utility class providing easy access to position and other info for a tree node. 6.428 + */ 6.429 + private class Info { 6.430 + Info() { 6.431 + tree = null; 6.432 + tag = JCTree.ERRONEOUS; 6.433 + start = 0; 6.434 + pos = 0; 6.435 + end = Integer.MAX_VALUE; 6.436 + } 6.437 + 6.438 + Info(JCTree tree, Map<JCTree, Integer> endPosTable) { 6.439 + this.tree = tree; 6.440 + tag = tree.getTag(); 6.441 + start = TreeInfo.getStartPos(tree); 6.442 + pos = tree.pos; 6.443 + end = TreeInfo.getEndPos(tree, endPosTable); 6.444 + } 6.445 + 6.446 + @Override 6.447 + public String toString() { 6.448 + return treeUtil.nameFromTag(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]"; 6.449 + } 6.450 + 6.451 + final JCTree tree; 6.452 + final int tag; 6.453 + final int start; 6.454 + final int pos; 6.455 + final int end; 6.456 + } 6.457 + 6.458 + /** 6.459 + * Names for tree tags. 6.460 + * javac does not provide an API to convert tag values to strings, so this class uses 6.461 + * reflection to determine names of public static final int values in JCTree. 6.462 + */ 6.463 + private static class TreeUtil { 6.464 + String nameFromTag(int tag) { 6.465 + if (names == null) { 6.466 + names = new HashMap<Integer, String>(); 6.467 + Class c = JCTree.class; 6.468 + for (Field f : c.getDeclaredFields()) { 6.469 + if (f.getType().equals(int.class)) { 6.470 + int mods = f.getModifiers(); 6.471 + if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { 6.472 + try { 6.473 + names.put(f.getInt(null), f.getName()); 6.474 + } catch (IllegalAccessException e) { 6.475 + } 6.476 + } 6.477 + } 6.478 + } 6.479 + } 6.480 + String name = names.get(tag); 6.481 + return (name == null) ? "??" : name; 6.482 + } 6.483 + 6.484 + List<Field> getFieldsOfType(JCTree t, List<String> excludeNames, Class<?>... types) { 6.485 + List<Field> buf = new ArrayList<Field>(); 6.486 + for (Field f : t.getClass().getDeclaredFields()) { 6.487 + if (!excludeNames.contains(f.getName())) { 6.488 + for (Class<?> type : types) { 6.489 + if (type.isAssignableFrom(f.getType())) { 6.490 + f.setAccessible(true); 6.491 + buf.add(f); 6.492 + break; 6.493 + } 6.494 + } 6.495 + } 6.496 + } 6.497 + return buf; 6.498 + } 6.499 + 6.500 + private Map<Integer, String> names; 6.501 + } 6.502 + 6.503 + /** 6.504 + * Thrown when errors are found parsing a java file. 6.505 + */ 6.506 + private static class ParseException extends Exception { 6.507 + ParseException(String msg) { 6.508 + super(msg); 6.509 + } 6.510 + } 6.511 + 6.512 + private static class AttributionException extends Exception { 6.513 + AttributionException(String msg) { 6.514 + super(msg); 6.515 + } 6.516 + } 6.517 + 6.518 + /** 6.519 + * DiagnosticListener to report diagnostics and count any errors that occur. 6.520 + */ 6.521 + private static class Reporter implements DiagnosticListener<JavaFileObject> { 6.522 + Reporter(PrintWriter out) { 6.523 + this.out = out; 6.524 + } 6.525 + 6.526 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 6.527 + out.println(diagnostic); 6.528 + switch (diagnostic.getKind()) { 6.529 + case ERROR: 6.530 + errors++; 6.531 + } 6.532 + } 6.533 + int errors; 6.534 + PrintWriter out; 6.535 + } 6.536 + 6.537 + /** 6.538 + * GUI viewer for issues found by TreePosTester. The viewer provides a drop 6.539 + * down list for selecting error conditions, a header area providing details 6.540 + * about an error, and a text area with the ranges of text highlighted as 6.541 + * appropriate. 6.542 + */ 6.543 + private class Viewer extends JFrame { 6.544 + /** 6.545 + * Create a viewer. 6.546 + */ 6.547 + Viewer() { 6.548 + initGUI(); 6.549 + } 6.550 + 6.551 + /** 6.552 + * Add another entry to the list of errors. 6.553 + * @param file The file containing the error 6.554 + * @param check The condition that was being tested, and which failed 6.555 + * @param encl the enclosing tree node 6.556 + * @param self the tree node containing the error 6.557 + */ 6.558 + void addEntry(JavaFileObject file, String check, Info encl, Info self) { 6.559 + Entry e = new Entry(file, check, encl, self); 6.560 + DefaultComboBoxModel m = (DefaultComboBoxModel) entries.getModel(); 6.561 + m.addElement(e); 6.562 + if (m.getSize() == 1) 6.563 + entries.setSelectedItem(e); 6.564 + } 6.565 + 6.566 + /** 6.567 + * Initialize the GUI window. 6.568 + */ 6.569 + private void initGUI() { 6.570 + JPanel head = new JPanel(new GridBagLayout()); 6.571 + GridBagConstraints lc = new GridBagConstraints(); 6.572 + GridBagConstraints fc = new GridBagConstraints(); 6.573 + fc.anchor = GridBagConstraints.WEST; 6.574 + fc.fill = GridBagConstraints.HORIZONTAL; 6.575 + fc.gridwidth = GridBagConstraints.REMAINDER; 6.576 + 6.577 + entries = new JComboBox(); 6.578 + entries.addActionListener(new ActionListener() { 6.579 + public void actionPerformed(ActionEvent e) { 6.580 + showEntry((Entry) entries.getSelectedItem()); 6.581 + } 6.582 + }); 6.583 + fc.insets.bottom = 10; 6.584 + head.add(entries, fc); 6.585 + fc.insets.bottom = 0; 6.586 + head.add(new JLabel("check:"), lc); 6.587 + head.add(checkField = createTextField(80), fc); 6.588 + fc.fill = GridBagConstraints.NONE; 6.589 + head.add(setBackground(new JLabel("encl:"), enclColor), lc); 6.590 + head.add(enclPanel = new InfoPanel(), fc); 6.591 + head.add(setBackground(new JLabel("self:"), selfColor), lc); 6.592 + head.add(selfPanel = new InfoPanel(), fc); 6.593 + add(head, BorderLayout.NORTH); 6.594 + 6.595 + body = new JTextArea(); 6.596 + body.setFont(Font.decode(Font.MONOSPACED)); 6.597 + body.addCaretListener(new CaretListener() { 6.598 + public void caretUpdate(CaretEvent e) { 6.599 + int dot = e.getDot(); 6.600 + int mark = e.getMark(); 6.601 + if (dot == mark) 6.602 + statusText.setText("dot: " + dot); 6.603 + else 6.604 + statusText.setText("dot: " + dot + ", mark:" + mark); 6.605 + } 6.606 + }); 6.607 + JScrollPane p = new JScrollPane(body, 6.608 + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 6.609 + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 6.610 + p.setPreferredSize(new Dimension(640, 480)); 6.611 + add(p, BorderLayout.CENTER); 6.612 + 6.613 + statusText = createTextField(80); 6.614 + add(statusText, BorderLayout.SOUTH); 6.615 + 6.616 + pack(); 6.617 + setLocationRelativeTo(null); // centered on screen 6.618 + setVisible(true); 6.619 + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 6.620 + } 6.621 + 6.622 + /** Show an entry that has been selected. */ 6.623 + private void showEntry(Entry e) { 6.624 + try { 6.625 + // update simple fields 6.626 + setTitle(e.file.getName()); 6.627 + checkField.setText(e.check); 6.628 + enclPanel.setInfo(e.encl); 6.629 + selfPanel.setInfo(e.self); 6.630 + // show file text with highlights 6.631 + body.setText(e.file.getCharContent(true).toString()); 6.632 + Highlighter highlighter = body.getHighlighter(); 6.633 + highlighter.removeAllHighlights(); 6.634 + addHighlight(highlighter, e.encl, enclColor); 6.635 + addHighlight(highlighter, e.self, selfColor); 6.636 + scroll(body, getMinPos(enclPanel.info, selfPanel.info)); 6.637 + } catch (IOException ex) { 6.638 + body.setText("Cannot read " + e.file.getName() + ": " + e); 6.639 + } 6.640 + } 6.641 + 6.642 + /** Create a test field. */ 6.643 + private JTextField createTextField(int width) { 6.644 + JTextField f = new JTextField(width); 6.645 + f.setEditable(false); 6.646 + f.setBorder(null); 6.647 + return f; 6.648 + } 6.649 + 6.650 + /** Add a highlighted region based on the positions in an Info object. */ 6.651 + private void addHighlight(Highlighter h, Info info, Color c) { 6.652 + int start = info.start; 6.653 + int end = info.end; 6.654 + if (start == -1 && end == -1) 6.655 + return; 6.656 + if (start == -1) 6.657 + start = end; 6.658 + if (end == -1) 6.659 + end = start; 6.660 + try { 6.661 + h.addHighlight(info.start, info.end, 6.662 + new DefaultHighlighter.DefaultHighlightPainter(c)); 6.663 + if (info.pos != -1) { 6.664 + Color c2 = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(.4f * 255)); // 40% 6.665 + h.addHighlight(info.pos, info.pos + 1, 6.666 + new DefaultHighlighter.DefaultHighlightPainter(c2)); 6.667 + } 6.668 + } catch (BadLocationException e) { 6.669 + e.printStackTrace(); 6.670 + } 6.671 + } 6.672 + 6.673 + /** Get the minimum valid position in a set of info objects. */ 6.674 + private int getMinPos(Info... values) { 6.675 + int i = Integer.MAX_VALUE; 6.676 + for (Info info: values) { 6.677 + if (info.start >= 0) i = Math.min(i, info.start); 6.678 + if (info.pos >= 0) i = Math.min(i, info.pos); 6.679 + if (info.end >= 0) i = Math.min(i, info.end); 6.680 + } 6.681 + return (i == Integer.MAX_VALUE) ? 0 : i; 6.682 + } 6.683 + 6.684 + /** Set the background on a component. */ 6.685 + private JComponent setBackground(JComponent comp, Color c) { 6.686 + comp.setOpaque(true); 6.687 + comp.setBackground(c); 6.688 + return comp; 6.689 + } 6.690 + 6.691 + /** Scroll a text area to display a given position near the middle of the visible area. */ 6.692 + private void scroll(final JTextArea t, final int pos) { 6.693 + // Using invokeLater appears to give text a chance to sort itself out 6.694 + // before the scroll happens; otherwise scrollRectToVisible doesn't work. 6.695 + // Maybe there's a better way to sync with the text... 6.696 + EventQueue.invokeLater(new Runnable() { 6.697 + public void run() { 6.698 + try { 6.699 + Rectangle r = t.modelToView(pos); 6.700 + JScrollPane p = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, t); 6.701 + r.y = Math.max(0, r.y - p.getHeight() * 2 / 5); 6.702 + r.height += p.getHeight() * 4 / 5; 6.703 + t.scrollRectToVisible(r); 6.704 + } catch (BadLocationException ignore) { 6.705 + } 6.706 + } 6.707 + }); 6.708 + } 6.709 + 6.710 + private JComboBox entries; 6.711 + private JTextField checkField; 6.712 + private InfoPanel enclPanel; 6.713 + private InfoPanel selfPanel; 6.714 + private JTextArea body; 6.715 + private JTextField statusText; 6.716 + 6.717 + private Color selfColor = new Color(0.f, 1.f, 0.f, 0.2f); // 20% green 6.718 + private Color enclColor = new Color(1.f, 0.f, 0.f, 0.2f); // 20% red 6.719 + 6.720 + /** Panel to display an Info object. */ 6.721 + private class InfoPanel extends JPanel { 6.722 + InfoPanel() { 6.723 + add(tagName = createTextField(20)); 6.724 + add(new JLabel("start:")); 6.725 + add(addListener(start = createTextField(6))); 6.726 + add(new JLabel("pos:")); 6.727 + add(addListener(pos = createTextField(6))); 6.728 + add(new JLabel("end:")); 6.729 + add(addListener(end = createTextField(6))); 6.730 + } 6.731 + 6.732 + void setInfo(Info info) { 6.733 + this.info = info; 6.734 + tagName.setText(treeUtil.nameFromTag(info.tag)); 6.735 + start.setText(String.valueOf(info.start)); 6.736 + pos.setText(String.valueOf(info.pos)); 6.737 + end.setText(String.valueOf(info.end)); 6.738 + } 6.739 + 6.740 + JTextField addListener(final JTextField f) { 6.741 + f.addMouseListener(new MouseAdapter() { 6.742 + @Override 6.743 + public void mouseClicked(MouseEvent e) { 6.744 + body.setCaretPosition(Integer.valueOf(f.getText())); 6.745 + body.getCaret().setVisible(true); 6.746 + } 6.747 + }); 6.748 + return f; 6.749 + } 6.750 + 6.751 + Info info; 6.752 + JTextField tagName; 6.753 + JTextField start; 6.754 + JTextField pos; 6.755 + JTextField end; 6.756 + } 6.757 + 6.758 + /** Object to record information about an error to be displayed. */ 6.759 + private class Entry { 6.760 + Entry(JavaFileObject file, String check, Info encl, Info self) { 6.761 + this.file = file; 6.762 + this.check = check; 6.763 + this.encl = encl; 6.764 + this.self= self; 6.765 + } 6.766 + 6.767 + @Override 6.768 + public String toString() { 6.769 + return file.getName() + " " + check + " " + getMinPos(encl, self); 6.770 + } 6.771 + 6.772 + final JavaFileObject file; 6.773 + final String check; 6.774 + final Info encl; 6.775 + final Info self; 6.776 + } 6.777 + } 6.778 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/failover/FailOver01.java Tue Sep 07 17:33:43 2010 +0100 7.3 @@ -0,0 +1,10 @@ 7.4 +/* 7.5 + * @test /nodynamiccopyright/ 7.6 + * @bug 6970584 7.7 + * @summary Flow.java should be more error-friendly 7.8 + * @author mcimadamore 7.9 + * 7.10 + * @compile/fail/ref=FailOver01.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver01.java 7.11 + */ 7.12 + 7.13 +class Test { { x = "" } }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/tools/javac/failover/FailOver01.out Tue Sep 07 17:33:43 2010 +0100 8.3 @@ -0,0 +1,3 @@ 8.4 +FailOver01.java:10:22: compiler.err.expected: ';' 8.5 +FailOver01.java:10:16: compiler.err.cant.resolve.location: kindname.variable, x, , , kindname.class, Test 8.6 +2 errors
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/tools/javac/failover/FailOver02.java Tue Sep 07 17:33:43 2010 +0100 9.3 @@ -0,0 +1,14 @@ 9.4 +/* 9.5 + * @test /nodynamiccopyright/ 9.6 + * @bug 6970584 9.7 + * @summary Flow.java should be more error-friendly 9.8 + * @author mcimadamore 9.9 + * 9.10 + * @compile/fail/ref=FailOver02.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver02.java 9.11 + */ 9.12 + 9.13 +class Test implements AutoCloseable { 9.14 + void test() { 9.15 + try(Test t = null) {} 9.16 + } 9.17 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/tools/javac/failover/FailOver02.out Tue Sep 07 17:33:43 2010 +0100 10.3 @@ -0,0 +1,3 @@ 10.4 +FailOver02.java:10:1: compiler.err.does.not.override.abstract: Test, close(), java.lang.AutoCloseable 10.5 +FailOver02.java:12:9: compiler.err.cant.resolve.location.args: kindname.method, close, , , kindname.class, Test 10.6 +2 errors
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/tools/javac/failover/FailOver03.java Tue Sep 07 17:33:43 2010 +0100 11.3 @@ -0,0 +1,12 @@ 11.4 +/* 11.5 + * @test /nodynamiccopyright/ 11.6 + * @bug 6970584 11.7 + * @summary Flow.java should be more error-friendly 11.8 + * @author mcimadamore 11.9 + * 11.10 + * @compile/fail/ref=FailOver03.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver03.java 11.11 + */ 11.12 + 11.13 +class Test extends Test { 11.14 + Test i; 11.15 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/tools/javac/failover/FailOver03.out Tue Sep 07 17:33:43 2010 +0100 12.3 @@ -0,0 +1,2 @@ 12.4 +FailOver03.java:10:1: compiler.err.cyclic.inheritance: Test 12.5 +1 error
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/tools/javac/failover/FailOver04.java Tue Sep 07 17:33:43 2010 +0100 13.3 @@ -0,0 +1,12 @@ 13.4 +/* 13.5 + * @test /nodynamiccopyright/ 13.6 + * @bug 6970584 13.7 + * @summary Flow.java should be more error-friendly 13.8 + * @author mcimadamore 13.9 + * 13.10 + * @compile/fail/ref=FailOver04.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver04.java 13.11 + */ 13.12 + 13.13 +class Test { 13.14 + { new Unknown() {}; } 13.15 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/test/tools/javac/failover/FailOver04.out Tue Sep 07 17:33:43 2010 +0100 14.3 @@ -0,0 +1,2 @@ 14.4 +FailOver04.java:11:10: compiler.err.cant.resolve.location: kindname.class, Unknown, , , kindname.class, Test 14.5 +1 error
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/test/tools/javac/failover/FailOver05.java Tue Sep 07 17:33:43 2010 +0100 15.3 @@ -0,0 +1,12 @@ 15.4 +/* 15.5 + * @test /nodynamiccopyright/ 15.6 + * @bug 6970584 15.7 + * @summary Flow.java should be more error-friendly 15.8 + * @author mcimadamore 15.9 + * 15.10 + * @compile/fail/ref=FailOver05.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver05.java 15.11 + */ 15.12 + 15.13 +class Test extends Test { 15.14 + { for ( Integer x : null) {} } 15.15 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/test/tools/javac/failover/FailOver05.out Tue Sep 07 17:33:43 2010 +0100 16.3 @@ -0,0 +1,2 @@ 16.4 +FailOver05.java:10:1: compiler.err.cyclic.inheritance: Test 16.5 +1 error
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/test/tools/javac/failover/FailOver06.java Tue Sep 07 17:33:43 2010 +0100 17.3 @@ -0,0 +1,13 @@ 17.4 +/* 17.5 + * @test /nodynamiccopyright/ 17.6 + * @bug 6970584 17.7 + * @summary Flow.java should be more error-friendly 17.8 + * @author mcimadamore 17.9 + * 17.10 + * @compile/fail/ref=FailOver06.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver06.java 17.11 + */ 17.12 + 17.13 +class Test extends Test { 17.14 + Inference x = 1; 17.15 + { if (x == 1) { } else { } } 17.16 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/test/tools/javac/failover/FailOver06.out Tue Sep 07 17:33:43 2010 +0100 18.3 @@ -0,0 +1,2 @@ 18.4 +FailOver06.java:10:1: compiler.err.cyclic.inheritance: Test 18.5 +1 error
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/test/tools/javac/failover/FailOver07.java Tue Sep 07 17:33:43 2010 +0100 19.3 @@ -0,0 +1,13 @@ 19.4 +/* 19.5 + * @test /nodynamiccopyright/ 19.6 + * @bug 6970584 19.7 + * @summary Flow.java should be more error-friendly 19.8 + * @author mcimadamore 19.9 + * 19.10 + * @compile/fail/ref=FailOver07.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver07.java 19.11 + */ 19.12 + 19.13 +class Test extends Test { 19.14 + Integer x = 1; 19.15 + { do {} while (x); } 19.16 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/tools/javac/failover/FailOver07.out Tue Sep 07 17:33:43 2010 +0100 20.3 @@ -0,0 +1,2 @@ 20.4 +FailOver07.java:10:1: compiler.err.cyclic.inheritance: Test 20.5 +1 error
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/tools/javac/failover/FailOver08.java Tue Sep 07 17:33:43 2010 +0100 21.3 @@ -0,0 +1,13 @@ 21.4 +/* 21.5 + * @test /nodynamiccopyright/ 21.6 + * @bug 6970584 21.7 + * @summary Flow.java should be more error-friendly 21.8 + * @author mcimadamore 21.9 + * 21.10 + * @compile/fail/ref=FailOver08.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver08.java 21.11 + */ 21.12 + 21.13 +class Test extends Test { 21.14 + Integer x = 1; 21.15 + { while (x) {}; } 21.16 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/tools/javac/failover/FailOver08.out Tue Sep 07 17:33:43 2010 +0100 22.3 @@ -0,0 +1,2 @@ 22.4 +FailOver08.java:10:1: compiler.err.cyclic.inheritance: Test 22.5 +1 error
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/tools/javac/failover/FailOver09.java Tue Sep 07 17:33:43 2010 +0100 23.3 @@ -0,0 +1,13 @@ 23.4 +/* 23.5 + * @test /nodynamiccopyright/ 23.6 + * @bug 6970584 23.7 + * @summary Flow.java should be more error-friendly 23.8 + * @author mcimadamore 23.9 + * 23.10 + * @compile/fail/ref=FailOver09.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver09.java 23.11 + */ 23.12 + 23.13 +class Test extends Test { 23.14 + Integer x = 1; 23.15 + { for (x = 0 ; x ; x++) {}; } 23.16 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/test/tools/javac/failover/FailOver09.out Tue Sep 07 17:33:43 2010 +0100 24.3 @@ -0,0 +1,2 @@ 24.4 +FailOver09.java:10:1: compiler.err.cyclic.inheritance: Test 24.5 +1 error
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/test/tools/javac/failover/FailOver10.java Tue Sep 07 17:33:43 2010 +0100 25.3 @@ -0,0 +1,15 @@ 25.4 +/* 25.5 + * @test /nodynamiccopyright/ 25.6 + * @bug 6970584 25.7 + * @summary Flow.java should be more error-friendly 25.8 + * @author mcimadamore 25.9 + * 25.10 + * @compile/fail/ref=FailOver10.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver10.java 25.11 + */ 25.12 + 25.13 +class Test extends Test { 25.14 + 25.15 + boolean cond; 25.16 + 25.17 + { Object o = null; } 25.18 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/test/tools/javac/failover/FailOver10.out Tue Sep 07 17:33:43 2010 +0100 26.3 @@ -0,0 +1,2 @@ 26.4 +FailOver10.java:10:1: compiler.err.cyclic.inheritance: Test 26.5 +1 error
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/test/tools/javac/failover/FailOver11.java Tue Sep 07 17:33:43 2010 +0100 27.3 @@ -0,0 +1,17 @@ 27.4 +/* 27.5 + * @test /nodynamiccopyright/ 27.6 + * @bug 6970584 27.7 + * @summary Flow.java should be more error-friendly 27.8 + * @author mcimadamore 27.9 + * 27.10 + * @compile/fail/ref=FailOver11.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver11.java 27.11 + */ 27.12 + 27.13 +class Test extends Test { 27.14 + 27.15 + boolean cond; 27.16 + 27.17 + void m(Object o) {} 27.18 + 27.19 + { m(cond ? null : null); } 27.20 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/test/tools/javac/failover/FailOver11.out Tue Sep 07 17:33:43 2010 +0100 28.3 @@ -0,0 +1,2 @@ 28.4 +FailOver11.java:10:1: compiler.err.cyclic.inheritance: Test 28.5 +1 error
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/test/tools/javac/failover/FailOver12.java Tue Sep 07 17:33:43 2010 +0100 29.3 @@ -0,0 +1,15 @@ 29.4 +/* 29.5 + * @test /nodynamiccopyright/ 29.6 + * @bug 6970584 29.7 + * @summary Flow.java should be more error-friendly 29.8 + * @author mcimadamore 29.9 + * 29.10 + * @compile/fail/ref=FailOver12.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver12.java 29.11 + */ 29.12 + 29.13 +class Test extends Test { 29.14 + 29.15 + Integer x = 1; 29.16 + 29.17 + { try {} catch (Exception e) {} } 29.18 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/tools/javac/failover/FailOver12.out Tue Sep 07 17:33:43 2010 +0100 30.3 @@ -0,0 +1,2 @@ 30.4 +FailOver12.java:10:1: compiler.err.cyclic.inheritance: Test 30.5 +1 error
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/tools/javac/failover/FailOver13.java Tue Sep 07 17:33:43 2010 +0100 31.3 @@ -0,0 +1,15 @@ 31.4 +/* 31.5 + * @test /nodynamiccopyright/ 31.6 + * @bug 6970584 31.7 + * @summary Flow.java should be more error-friendly 31.8 + * @author mcimadamore 31.9 + * 31.10 + * @compile/fail/ref=FailOver13.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver13.java 31.11 + */ 31.12 + 31.13 +class Test extends Test { 31.14 + 31.15 + Integer x = 1; 31.16 + 31.17 + { x = (Object)o; } 31.18 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/tools/javac/failover/FailOver13.out Tue Sep 07 17:33:43 2010 +0100 32.3 @@ -0,0 +1,2 @@ 32.4 +FailOver13.java:10:1: compiler.err.cyclic.inheritance: Test 32.5 +1 error
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/tools/javac/failover/FailOver14.java Tue Sep 07 17:33:43 2010 +0100 33.3 @@ -0,0 +1,14 @@ 33.4 +/* 33.5 + * @test /nodynamiccopyright/ 33.6 + * @bug 6970584 33.7 + * @summary Flow.java should be more error-friendly 33.8 + * @author mcimadamore 33.9 + * 33.10 + * @compile/fail/ref=FailOver14.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW -XDdev FailOver14.java 33.11 + */ 33.12 + 33.13 +class Test extends Test { 33.14 + 33.15 + { for (Integer x : !x) { } } 33.16 + 33.17 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/test/tools/javac/failover/FailOver14.out Tue Sep 07 17:33:43 2010 +0100 34.3 @@ -0,0 +1,2 @@ 34.4 +FailOver14.java:10:1: compiler.err.cyclic.inheritance: Test 34.5 +1 error