Tue, 09 Mar 2010 15:29:45 -0800
Merge
test/tools/javac/treepostests/TreePosTest.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/classes/com/sun/tools/apt/comp/Apt.java Thu Mar 04 13:50:33 2010 -0800 1.2 +++ b/src/share/classes/com/sun/tools/apt/comp/Apt.java Tue Mar 09 15:29:45 2010 -0800 1.3 @@ -457,8 +457,10 @@ 1.4 throw new UsageMessageNeededException(); 1.5 1.6 try { 1.7 - for(AnnotationProcessorFactory apFactory: factoryToAnnotation.keySet()) { 1.8 - AnnotationProcessor processor = apFactory.getProcessorFor(factoryToAnnotation.get(apFactory), 1.9 + for(Map.Entry<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> entry : 1.10 + factoryToAnnotation.entrySet()) { 1.11 + AnnotationProcessorFactory apFactory = entry.getKey(); 1.12 + AnnotationProcessor processor = apFactory.getProcessorFor(entry.getValue(), 1.13 trivAPE); 1.14 if (processor != null) 1.15 processors.add(processor);
2.1 --- a/src/share/classes/com/sun/tools/apt/main/CommandLine.java Thu Mar 04 13:50:33 2010 -0800 2.2 +++ b/src/share/classes/com/sun/tools/apt/main/CommandLine.java Tue Mar 09 15:29:45 2010 -0800 2.3 @@ -82,7 +82,7 @@ 2.4 st.commentChar('#'); 2.5 st.quoteChar('"'); 2.6 st.quoteChar('\''); 2.7 - while (st.nextToken() != st.TT_EOF) { 2.8 + while (st.nextToken() != StreamTokenizer.TT_EOF) { 2.9 args.append(st.sval); 2.10 } 2.11 r.close();
3.1 --- a/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java Thu Mar 04 13:50:33 2010 -0800 3.2 +++ b/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java Tue Mar 09 15:29:45 2010 -0800 3.3 @@ -270,7 +270,7 @@ 3.4 * The toString, hashCode, and equals methods foward to the underlying 3.5 * type. 3.6 */ 3.7 - private static class MirroredTypeExceptionProxy extends ExceptionProxy { 3.8 + private static final class MirroredTypeExceptionProxy extends ExceptionProxy { 3.9 private static final long serialVersionUID = 6662035281599933545L; 3.10 3.11 private MirroredTypeException ex; 3.12 @@ -312,7 +312,7 @@ 3.13 * The toString, hashCode, and equals methods foward to the underlying 3.14 * types. 3.15 */ 3.16 - private static class MirroredTypesExceptionProxy extends ExceptionProxy { 3.17 + private static final class MirroredTypesExceptionProxy extends ExceptionProxy { 3.18 private static final long serialVersionUID = -6670822532616693951L; 3.19 3.20 private MirroredTypesException ex;
4.1 --- a/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java Thu Mar 04 13:50:33 2010 -0800 4.2 +++ b/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java Tue Mar 09 15:29:45 2010 -0800 4.3 @@ -58,7 +58,7 @@ 4.4 protected final AptEnv env; 4.5 public final Symbol sym; 4.6 4.7 - protected static DeclarationFilter identityFilter = 4.8 + protected static final DeclarationFilter identityFilter = 4.9 new DeclarationFilter(); 4.10 4.11
5.1 --- a/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java Thu Mar 04 13:50:33 2010 -0800 5.2 +++ b/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java Tue Mar 09 15:29:45 2010 -0800 5.3 @@ -71,6 +71,6 @@ 5.4 * {@inheritDoc} 5.5 */ 5.6 public int hashCode() { 5.7 - return env.jctypes.hashCode(type); 5.8 + return Types.hashCode(type); 5.9 } 5.10 }
6.1 --- a/src/share/classes/com/sun/tools/classfile/ConstantPool.java Thu Mar 04 13:50:33 2010 -0800 6.2 +++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java Tue Mar 09 15:29:45 2010 -0800 6.3 @@ -40,7 +40,7 @@ 6.4 */ 6.5 public class ConstantPool { 6.6 6.7 - public class InvalidIndex extends ConstantPoolException { 6.8 + public static class InvalidIndex extends ConstantPoolException { 6.9 private static final long serialVersionUID = -4350294289300939730L; 6.10 InvalidIndex(int index) { 6.11 super(index); 6.12 @@ -53,7 +53,7 @@ 6.13 } 6.14 } 6.15 6.16 - public class UnexpectedEntry extends ConstantPoolException { 6.17 + public static class UnexpectedEntry extends ConstantPoolException { 6.18 private static final long serialVersionUID = 6986335935377933211L; 6.19 UnexpectedEntry(int index, int expected_tag, int found_tag) { 6.20 super(index); 6.21 @@ -71,7 +71,7 @@ 6.22 public final int found_tag; 6.23 } 6.24 6.25 - public class InvalidEntry extends ConstantPoolException { 6.26 + public static class InvalidEntry extends ConstantPoolException { 6.27 private static final long serialVersionUID = 1000087545585204447L; 6.28 InvalidEntry(int index, int tag) { 6.29 super(index); 6.30 @@ -87,7 +87,7 @@ 6.31 public final int tag; 6.32 } 6.33 6.34 - public class EntryNotFound extends ConstantPoolException { 6.35 + public static class EntryNotFound extends ConstantPoolException { 6.36 private static final long serialVersionUID = 2885537606468581850L; 6.37 EntryNotFound(Object value) { 6.38 super(-1); 6.39 @@ -694,7 +694,7 @@ 6.40 public int byteLength() { 6.41 class SizeOutputStream extends OutputStream { 6.42 @Override 6.43 - public void write(int b) throws IOException { 6.44 + public void write(int b) { 6.45 size++; 6.46 } 6.47 int size;
7.1 --- a/src/share/classes/com/sun/tools/doclets/standard/Standard.java Thu Mar 04 13:50:33 2010 -0800 7.2 +++ b/src/share/classes/com/sun/tools/doclets/standard/Standard.java Tue Mar 09 15:29:45 2010 -0800 7.3 @@ -31,23 +31,21 @@ 7.4 7.5 public class Standard { 7.6 7.7 - public static final HtmlDoclet htmlDoclet = new HtmlDoclet(); 7.8 - 7.9 public static int optionLength(String option) { 7.10 - return htmlDoclet.optionLength(option); 7.11 + return HtmlDoclet.optionLength(option); 7.12 } 7.13 7.14 public static boolean start(RootDoc root) { 7.15 - return htmlDoclet.start(root); 7.16 + return HtmlDoclet.start(root); 7.17 } 7.18 7.19 public static boolean validOptions(String[][] options, 7.20 DocErrorReporter reporter) { 7.21 - return htmlDoclet.validOptions(options, reporter); 7.22 + return HtmlDoclet.validOptions(options, reporter); 7.23 } 7.24 7.25 public static LanguageVersion languageVersion() { 7.26 - return htmlDoclet.languageVersion(); 7.27 + return HtmlDoclet.languageVersion(); 7.28 } 7.29 7.30 }
8.1 --- a/src/share/classes/com/sun/tools/javac/Launcher.java Thu Mar 04 13:50:33 2010 -0800 8.2 +++ b/src/share/classes/com/sun/tools/javac/Launcher.java Tue Mar 09 15:29:45 2010 -0800 8.3 @@ -64,7 +64,7 @@ 8.4 fileChooser.setSelectedFile(new File(fileName)); 8.5 } 8.6 } 8.7 - if (fileChooser.showOpenDialog(null) == fileChooser.APPROVE_OPTION) { 8.8 + if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { 8.9 String fileName = fileChooser.getSelectedFile().getPath(); 8.10 prefs.put("recent.file", fileName); 8.11 javac.run(System.in, null, null, "-d", "/tmp", fileName);
9.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTool.java Thu Mar 04 13:50:33 2010 -0800 9.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTool.java Tue Mar 09 15:29:45 2010 -0800 9.3 @@ -137,7 +137,7 @@ 9.4 } 9.5 9.6 private static boolean match(OptionKind clientKind, OptionKind optionKind) { 9.7 - return (clientKind == (optionKind == OptionKind.HIDDEN ? optionKind.EXTENDED : optionKind)); 9.8 + return (clientKind == (optionKind == OptionKind.HIDDEN ? OptionKind.EXTENDED : optionKind)); 9.9 } 9.10 9.11 public JavacFileManager getStandardFileManager(
10.1 --- a/src/share/classes/com/sun/tools/javac/code/Lint.java Thu Mar 04 13:50:33 2010 -0800 10.2 +++ b/src/share/classes/com/sun/tools/javac/code/Lint.java Tue Mar 09 15:29:45 2010 -0800 10.3 @@ -198,7 +198,12 @@ 10.4 /** 10.5 * Warn about Sun proprietary API that may be removed in a future release. 10.6 */ 10.7 - SUNAPI("sunapi", true); 10.8 + SUNAPI("sunapi", true), 10.9 + 10.10 + /** 10.11 + * Warn about issues relating to use of statics 10.12 + */ 10.13 + STATIC("static"); 10.14 10.15 LintCategory(String option) { 10.16 this(option, false);
11.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Mar 04 13:50:33 2010 -0800 11.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Tue Mar 09 15:29:45 2010 -0800 11.3 @@ -162,7 +162,7 @@ 11.4 * the default package; otherwise, the owner symbol is returned 11.5 */ 11.6 public Symbol location() { 11.7 - if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK)) { 11.8 + if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK && owner.kind != TYP)) { 11.9 return null; 11.10 } 11.11 return owner;
12.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Thu Mar 04 13:50:33 2010 -0800 12.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue Mar 09 15:29:45 2010 -0800 12.3 @@ -2504,7 +2504,7 @@ 12.4 } 12.5 @Override 12.6 public int hashCode() { 12.7 - return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); 12.8 + return 127 * Types.hashCode(t1) + Types.hashCode(t2); 12.9 } 12.10 @Override 12.11 public boolean equals(Object obj) { 12.12 @@ -3375,7 +3375,7 @@ 12.13 this.t = t; 12.14 } 12.15 public int hashCode() { 12.16 - return Types.this.hashCode(t); 12.17 + return Types.hashCode(t); 12.18 } 12.19 public boolean equals(Object obj) { 12.20 return (obj instanceof SingletonType) &&
13.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Mar 04 13:50:33 2010 -0800 13.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Mar 09 15:29:45 2010 -0800 13.3 @@ -2020,6 +2020,10 @@ 13.4 tree.pos(), site, sym.name, true); 13.5 } 13.6 } 13.7 + } else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && sym.name != names._class) { 13.8 + // If the qualified item is not a type and the selected item is static, report 13.9 + // a warning. Make allowance for the class of an array type e.g. Object[].class) 13.10 + chk.warnStatic(tree, "static.not.qualified.by.type", Kinds.kindName(sym.kind), sym.owner); 13.11 } 13.12 13.13 // If we are selecting an instance member via a `super', ... 13.14 @@ -2636,6 +2640,7 @@ 13.15 if (tree.bounds.tail.nonEmpty()) { 13.16 log.error(tree.bounds.tail.head.pos(), 13.17 "type.var.may.not.be.followed.by.other.bounds"); 13.18 + log.unrecoverableError = true; 13.19 tree.bounds = List.of(tree.bounds.head); 13.20 a.bound = bs.head; 13.21 }
14.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Mar 04 13:50:33 2010 -0800 14.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Mar 09 15:29:45 2010 -0800 14.3 @@ -189,6 +189,11 @@ 14.4 sunApiHandler.report(pos, msg, args); 14.5 } 14.6 14.7 + public void warnStatic(DiagnosticPosition pos, String msg, Object... args) { 14.8 + if (lint.isEnabled(LintCategory.STATIC)) 14.9 + log.warning(pos, msg, args); 14.10 + } 14.11 + 14.12 /** 14.13 * Report any deferred diagnostics. 14.14 */
15.1 --- a/src/share/classes/com/sun/tools/javac/comp/Enter.java Thu Mar 04 13:50:33 2010 -0800 15.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Mar 09 15:29:45 2010 -0800 15.3 @@ -270,6 +270,7 @@ 15.4 return ts.toList(); 15.5 } 15.6 15.7 + @Override 15.8 public void visitTopLevel(JCCompilationUnit tree) { 15.9 JavaFileObject prev = log.useSource(tree.sourcefile); 15.10 boolean addEnv = false; 15.11 @@ -289,13 +290,13 @@ 15.12 tree.packge = syms.unnamedPackage; 15.13 } 15.14 tree.packge.complete(); // Find all classes in package. 15.15 - Env<AttrContext> env = topLevelEnv(tree); 15.16 + Env<AttrContext> topEnv = topLevelEnv(tree); 15.17 15.18 // Save environment of package-info.java file. 15.19 if (isPkgInfo) { 15.20 Env<AttrContext> env0 = typeEnvs.get(tree.packge); 15.21 if (env0 == null) { 15.22 - typeEnvs.put(tree.packge, env); 15.23 + typeEnvs.put(tree.packge, topEnv); 15.24 } else { 15.25 JCCompilationUnit tree0 = env0.toplevel; 15.26 if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) { 15.27 @@ -306,7 +307,7 @@ 15.28 if (addEnv || (tree0.packageAnnotations.isEmpty() && 15.29 tree.docComments != null && 15.30 tree.docComments.get(tree) != null)) { 15.31 - typeEnvs.put(tree.packge, env); 15.32 + typeEnvs.put(tree.packge, topEnv); 15.33 } 15.34 } 15.35 } 15.36 @@ -322,14 +323,15 @@ 15.37 c.members_field = new Scope(c); 15.38 tree.packge.package_info = c; 15.39 } 15.40 - classEnter(tree.defs, env); 15.41 + classEnter(tree.defs, topEnv); 15.42 if (addEnv) { 15.43 - todo.append(env); 15.44 + todo.append(topEnv); 15.45 } 15.46 log.useSource(prev); 15.47 result = null; 15.48 } 15.49 15.50 + @Override 15.51 public void visitClassDef(JCClassDecl tree) { 15.52 Symbol owner = env.info.scope.owner; 15.53 Scope enclScope = enterScope(env); 15.54 @@ -435,6 +437,7 @@ 15.55 * Enter a symbol for type parameter in local scope, after checking that it 15.56 * is unique. 15.57 */ 15.58 + @Override 15.59 public void visitTypeParameter(JCTypeParameter tree) { 15.60 TypeVar a = (tree.type != null) 15.61 ? (TypeVar)tree.type 15.62 @@ -448,6 +451,7 @@ 15.63 15.64 /** Default class enter visitor method: do nothing. 15.65 */ 15.66 + @Override 15.67 public void visitTree(JCTree tree) { 15.68 result = null; 15.69 } 15.70 @@ -489,10 +493,8 @@ 15.71 for (JCCompilationUnit tree : trees) { 15.72 if (tree.starImportScope.elems == null) { 15.73 JavaFileObject prev = log.useSource(tree.sourcefile); 15.74 - Env<AttrContext> env = typeEnvs.get(tree); 15.75 - if (env == null) 15.76 - env = topLevelEnv(tree); 15.77 - memberEnter.memberEnter(tree, env); 15.78 + Env<AttrContext> topEnv = topLevelEnv(tree); 15.79 + memberEnter.memberEnter(tree, topEnv); 15.80 log.useSource(prev); 15.81 } 15.82 }
16.1 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu Mar 04 13:50:33 2010 -0800 16.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Tue Mar 09 15:29:45 2010 -0800 16.3 @@ -607,10 +607,12 @@ 16.4 public void visitNewArray(JCNewArray tree) { 16.5 tree.elemtype = translate(tree.elemtype, null); 16.6 translate(tree.dims, syms.intType); 16.7 - tree.elems = translate(tree.elems, 16.8 - (tree.type == null) ? null 16.9 - : erasure(types.elemtype(tree.type))); 16.10 - tree.type = erasure(tree.type); 16.11 + if (tree.type != null) { 16.12 + tree.elems = translate(tree.elems, erasure(types.elemtype(tree.type))); 16.13 + tree.type = erasure(tree.type); 16.14 + } else { 16.15 + tree.elems = translate(tree.elems, null); 16.16 + } 16.17 16.18 result = tree; 16.19 }
17.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Mar 04 13:50:33 2010 -0800 17.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Tue Mar 09 15:29:45 2010 -0800 17.3 @@ -260,7 +260,7 @@ 17.4 archive = openArchive(directory); 17.5 } catch (IOException ex) { 17.6 log.error("error.reading.file", 17.7 - directory, ex.getLocalizedMessage()); 17.8 + directory, getMessage(ex)); 17.9 return; 17.10 } 17.11 } 17.12 @@ -489,7 +489,7 @@ 17.13 archive = new MissingArchive(zipFileName); 17.14 } catch (IOException ex) { 17.15 if (zipFileName.exists()) 17.16 - log.error("error.reading.file", zipFileName, ex.getLocalizedMessage()); 17.17 + log.error("error.reading.file", zipFileName, getMessage(ex)); 17.18 archive = new MissingArchive(zipFileName); 17.19 } 17.20 17.21 @@ -838,4 +838,23 @@ 17.22 } 17.23 throw new IllegalArgumentException("Invalid relative path: " + file); 17.24 } 17.25 + 17.26 + /** 17.27 + * Get a detail message from an IOException. 17.28 + * Most, but not all, instances of IOException provide a non-null result 17.29 + * for getLocalizedMessage(). But some instances return null: in these 17.30 + * cases, fallover to getMessage(), and if even that is null, return the 17.31 + * name of the exception itself. 17.32 + * @param e an IOException 17.33 + * @return a string to include in a compiler diagnostic 17.34 + */ 17.35 + public static String getMessage(IOException e) { 17.36 + String s = e.getLocalizedMessage(); 17.37 + if (s != null) 17.38 + return s; 17.39 + s = e.getMessage(); 17.40 + if (s != null) 17.41 + return s; 17.42 + return e.toString(); 17.43 + } 17.44 }
18.1 --- a/src/share/classes/com/sun/tools/javac/file/Paths.java Thu Mar 04 13:50:33 2010 -0800 18.2 +++ b/src/share/classes/com/sun/tools/javac/file/Paths.java Tue Mar 09 15:29:45 2010 -0800 18.3 @@ -320,7 +320,7 @@ 18.4 addFile(f, warn); 18.5 } 18.6 } catch (IOException e) { 18.7 - log.error("error.reading.file", jarFile, e.getLocalizedMessage()); 18.8 + log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e)); 18.9 } 18.10 } 18.11 }
19.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Mar 04 13:50:33 2010 -0800 19.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Mar 09 15:29:45 2010 -0800 19.3 @@ -1135,7 +1135,7 @@ 19.4 self.name = simpleBinaryName(self.flatname, c.flatname) ; 19.5 self.owner = m != null ? m : c; 19.6 if (self.name.isEmpty()) 19.7 - self.fullname = null; 19.8 + self.fullname = names.empty; 19.9 else 19.10 self.fullname = ClassSymbol.formFullName(self.name, self.owner); 19.11
20.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Mar 04 13:50:33 2010 -0800 20.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Mar 09 15:29:45 2010 -0800 20.3 @@ -808,8 +808,8 @@ 20.4 code.resolve(secondJumps); 20.5 CondItem second = genCond(tree.falsepart, CRT_FLOW_TARGET); 20.6 CondItem result = items.makeCondItem(second.opcode, 20.7 - code.mergeChains(trueJumps, second.trueJumps), 20.8 - code.mergeChains(falseJumps, second.falseJumps)); 20.9 + Code.mergeChains(trueJumps, second.trueJumps), 20.10 + Code.mergeChains(falseJumps, second.falseJumps)); 20.11 if (markBranches) result.tree = tree.falsepart; 20.12 return result; 20.13 } else { 20.14 @@ -1322,7 +1322,7 @@ 20.15 if (useJsrLocally) { 20.16 if (tree.finalizer != null) { 20.17 Code.State jsrState = code.state.dup(); 20.18 - jsrState.push(code.jsrReturnValue); 20.19 + jsrState.push(Code.jsrReturnValue); 20.20 tryEnv.info.cont = 20.21 new Chain(code.emitJump(jsr), 20.22 tryEnv.info.cont, 20.23 @@ -1375,7 +1375,7 @@ 20.24 genFinalizer(env); 20.25 if (hasFinalizer || l.tail.nonEmpty()) { 20.26 code.statBegin(TreeInfo.endPos(env.tree)); 20.27 - exitChain = code.mergeChains(exitChain, 20.28 + exitChain = Code.mergeChains(exitChain, 20.29 code.branch(goto_)); 20.30 } 20.31 endFinalizerGap(env); 20.32 @@ -1963,7 +1963,7 @@ 20.33 result = items. 20.34 makeCondItem(rcond.opcode, 20.35 rcond.trueJumps, 20.36 - code.mergeChains(falseJumps, 20.37 + Code.mergeChains(falseJumps, 20.38 rcond.falseJumps)); 20.39 } else { 20.40 result = lcond; 20.41 @@ -1976,7 +1976,7 @@ 20.42 CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET); 20.43 result = items. 20.44 makeCondItem(rcond.opcode, 20.45 - code.mergeChains(trueJumps, rcond.trueJumps), 20.46 + Code.mergeChains(trueJumps, rcond.trueJumps), 20.47 rcond.falseJumps); 20.48 } else { 20.49 result = lcond;
21.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Items.java Thu Mar 04 13:50:33 2010 -0800 21.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Items.java Tue Mar 09 15:29:45 2010 -0800 21.3 @@ -792,25 +792,25 @@ 21.4 } 21.5 21.6 Chain jumpTrue() { 21.7 - if (tree == null) return code.mergeChains(trueJumps, code.branch(opcode)); 21.8 + if (tree == null) return Code.mergeChains(trueJumps, code.branch(opcode)); 21.9 // we should proceed further in -Xjcov mode only 21.10 int startpc = code.curPc(); 21.11 - Chain c = code.mergeChains(trueJumps, code.branch(opcode)); 21.12 + Chain c = Code.mergeChains(trueJumps, code.branch(opcode)); 21.13 code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc()); 21.14 return c; 21.15 } 21.16 21.17 Chain jumpFalse() { 21.18 - if (tree == null) return code.mergeChains(falseJumps, code.branch(code.negate(opcode))); 21.19 + if (tree == null) return Code.mergeChains(falseJumps, code.branch(Code.negate(opcode))); 21.20 // we should proceed further in -Xjcov mode only 21.21 int startpc = code.curPc(); 21.22 - Chain c = code.mergeChains(falseJumps, code.branch(code.negate(opcode))); 21.23 + Chain c = Code.mergeChains(falseJumps, code.branch(Code.negate(opcode))); 21.24 code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc()); 21.25 return c; 21.26 } 21.27 21.28 CondItem negate() { 21.29 - CondItem c = new CondItem(code.negate(opcode), falseJumps, trueJumps); 21.30 + CondItem c = new CondItem(Code.negate(opcode), falseJumps, trueJumps); 21.31 c.tree = tree; 21.32 return c; 21.33 }
22.1 --- a/src/share/classes/com/sun/tools/javac/main/CommandLine.java Thu Mar 04 13:50:33 2010 -0800 22.2 +++ b/src/share/classes/com/sun/tools/javac/main/CommandLine.java Tue Mar 09 15:29:45 2010 -0800 22.3 @@ -82,7 +82,7 @@ 22.4 st.commentChar('#'); 22.5 st.quoteChar('"'); 22.6 st.quoteChar('\''); 22.7 - while (st.nextToken() != st.TT_EOF) { 22.8 + while (st.nextToken() != StreamTokenizer.TT_EOF) { 22.9 args.append(st.sval); 22.10 } 22.11 r.close();
23.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Mar 04 13:50:33 2010 -0800 23.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Mar 09 15:29:45 2010 -0800 23.3 @@ -549,12 +549,6 @@ 23.4 return log.nwarnings; 23.5 } 23.6 23.7 - /** Whether or not any parse errors have occurred. 23.8 - */ 23.9 - public boolean parseErrors() { 23.10 - return parseErrors; 23.11 - } 23.12 - 23.13 /** Try to open input stream with given name. 23.14 * Report an error if this fails. 23.15 * @param filename The file name of the input stream to be opened. 23.16 @@ -564,7 +558,7 @@ 23.17 inputFiles.add(filename); 23.18 return filename.getCharContent(false); 23.19 } catch (IOException e) { 23.20 - log.error("error.reading.file", filename, e.getLocalizedMessage()); 23.21 + log.error("error.reading.file", filename, JavacFileManager.getMessage(e)); 23.22 return null; 23.23 } 23.24 } 23.25 @@ -588,7 +582,7 @@ 23.26 int initialErrorCount = log.nerrors; 23.27 Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo); 23.28 tree = parser.parseCompilationUnit(); 23.29 - parseErrors |= (log.nerrors > initialErrorCount); 23.30 + log.unrecoverableError |= (log.nerrors > initialErrorCount); 23.31 if (verbose) { 23.32 printVerbose("parsing.done", Long.toString(elapsed(msec))); 23.33 } 23.34 @@ -723,7 +717,7 @@ 23.35 try { 23.36 tree = parse(filename, filename.getCharContent(false)); 23.37 } catch (IOException e) { 23.38 - log.error("error.reading.file", filename, e); 23.39 + log.error("error.reading.file", filename, JavacFileManager.getMessage(e)); 23.40 tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil()); 23.41 } finally { 23.42 log.useSource(prev); 23.43 @@ -768,9 +762,6 @@ 23.44 private long start_msec = 0; 23.45 public long elapsed_msec = 0; 23.46 23.47 - /** Track whether any errors occurred while parsing source text. */ 23.48 - private boolean parseErrors = false; 23.49 - 23.50 public void compile(List<JavaFileObject> sourceFileObject) 23.51 throws Throwable { 23.52 compile(sourceFileObject, List.<String>nil(), null); 23.53 @@ -1114,7 +1105,7 @@ 23.54 return env; 23.55 23.56 if (verboseCompilePolicy) 23.57 - log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]"); 23.58 + Log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]"); 23.59 if (verbose) 23.60 printVerbose("checking.attribution", env.enclClass.sym); 23.61
24.1 --- a/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Thu Mar 04 13:50:33 2010 -0800 24.2 +++ b/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Tue Mar 09 15:29:45 2010 -0800 24.3 @@ -26,6 +26,8 @@ 24.4 package com.sun.tools.javac.model; 24.5 24.6 import com.sun.tools.javac.util.*; 24.7 +import java.io.ObjectInputStream; 24.8 +import java.io.IOException; 24.9 import java.lang.annotation.*; 24.10 import java.lang.reflect.Array; 24.11 import java.lang.reflect.Method; 24.12 @@ -268,10 +270,10 @@ 24.13 * The toString, hashCode, and equals methods foward to the underlying 24.14 * type. 24.15 */ 24.16 - private static class MirroredTypeExceptionProxy extends ExceptionProxy { 24.17 + private static final class MirroredTypeExceptionProxy extends ExceptionProxy { 24.18 static final long serialVersionUID = 269; 24.19 24.20 - private transient final TypeMirror type; 24.21 + private transient TypeMirror type; 24.22 private final String typeString; 24.23 24.24 MirroredTypeExceptionProxy(TypeMirror t) { 24.25 @@ -296,6 +298,13 @@ 24.26 protected RuntimeException generateException() { 24.27 return new MirroredTypeException(type); 24.28 } 24.29 + 24.30 + // Explicitly set all transient fields. 24.31 + private void readObject(ObjectInputStream s) 24.32 + throws IOException, ClassNotFoundException { 24.33 + s.defaultReadObject(); 24.34 + type = null; 24.35 + } 24.36 } 24.37 24.38 24.39 @@ -304,10 +313,10 @@ 24.40 * The toString, hashCode, and equals methods foward to the underlying 24.41 * types. 24.42 */ 24.43 - private static class MirroredTypesExceptionProxy extends ExceptionProxy { 24.44 + private static final class MirroredTypesExceptionProxy extends ExceptionProxy { 24.45 static final long serialVersionUID = 269; 24.46 24.47 - private transient final List<TypeMirror> types; 24.48 + private transient List<TypeMirror> types; 24.49 private final String typeStrings; 24.50 24.51 MirroredTypesExceptionProxy(List<TypeMirror> ts) { 24.52 @@ -333,5 +342,12 @@ 24.53 protected RuntimeException generateException() { 24.54 return new MirroredTypesException(types); 24.55 } 24.56 + 24.57 + // Explicitly set all transient fields. 24.58 + private void readObject(ObjectInputStream s) 24.59 + throws IOException, ClassNotFoundException { 24.60 + s.defaultReadObject(); 24.61 + types = null; 24.62 + } 24.63 } 24.64 }
25.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Mar 04 13:50:33 2010 -0800 25.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Mar 09 15:29:45 2010 -0800 25.3 @@ -1561,7 +1561,10 @@ 25.4 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t); 25.5 if (newClass.def != null) { 25.6 assert newClass.def.mods.annotations.isEmpty(); 25.7 - newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations); 25.8 + if (newAnnotations.nonEmpty()) { 25.9 + newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos); 25.10 + newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations); 25.11 + } 25.12 } 25.13 return newClass; 25.14 } else { 25.15 @@ -3016,6 +3019,18 @@ 25.16 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; 25.17 } 25.18 25.19 + /** 25.20 + * Return the lesser of two positions, making allowance for either one 25.21 + * being unset. 25.22 + */ 25.23 + static int earlier(int pos1, int pos2) { 25.24 + if (pos1 == Position.NOPOS) 25.25 + return pos2; 25.26 + if (pos2 == Position.NOPOS) 25.27 + return pos1; 25.28 + return (pos1 < pos2 ? pos1 : pos2); 25.29 + } 25.30 + 25.31 /** Return operation tag of binary operator represented by token, 25.32 * -1 if token is not a binary operator. 25.33 */
26.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Mar 04 13:50:33 2010 -0800 26.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Mar 09 15:29:45 2010 -0800 26.3 @@ -690,10 +690,12 @@ 26.4 ProcessorState ps = psi.next(); 26.5 Set<String> matchedNames = new HashSet<String>(); 26.6 Set<TypeElement> typeElements = new LinkedHashSet<TypeElement>(); 26.7 - for (String unmatchedAnnotationName : unmatchedAnnotations.keySet()) { 26.8 + 26.9 + for (Map.Entry<String, TypeElement> entry: unmatchedAnnotations.entrySet()) { 26.10 + String unmatchedAnnotationName = entry.getKey(); 26.11 if (ps.annotationSupported(unmatchedAnnotationName) ) { 26.12 matchedNames.add(unmatchedAnnotationName); 26.13 - TypeElement te = unmatchedAnnotations.get(unmatchedAnnotationName); 26.14 + TypeElement te = entry.getValue(); 26.15 if (te != null) 26.16 typeElements.add(te); 26.17 } 26.18 @@ -790,16 +792,13 @@ 26.19 List<JCCompilationUnit> roots, 26.20 List<ClassSymbol> classSymbols, 26.21 Iterable<? extends PackageSymbol> pckSymbols) 26.22 - throws IOException { 26.23 + throws IOException { 26.24 26.25 log = Log.instance(context); 26.26 // Writer for -XprintRounds and -XprintProcessorInfo data 26.27 PrintWriter xout = context.get(Log.outKey); 26.28 TaskListener taskListener = context.get(TaskListener.class); 26.29 26.30 - 26.31 - AnnotationCollector collector = new AnnotationCollector(); 26.32 - 26.33 JavaCompiler compiler = JavaCompiler.instance(context); 26.34 compiler.todo.clear(); // free the compiler's resources 26.35 26.36 @@ -878,7 +877,7 @@ 26.37 roots = cleanTrees(roots).appendList(parsedFiles); 26.38 26.39 // Check for errors after parsing 26.40 - if (compiler.parseErrors()) { 26.41 + if (log.unrecoverableError) { 26.42 errorStatus = true; 26.43 break runAround; 26.44 } else { 26.45 @@ -912,7 +911,7 @@ 26.46 roots = runLastRound(xout, roundNumber, errorStatus, compiler, roots, taskListener); 26.47 // Set error status for any files compiled and generated in 26.48 // the last round 26.49 - if (compiler.parseErrors()) 26.50 + if (log.unrecoverableError) 26.51 errorStatus = true; 26.52 26.53 compiler.close(false); 26.54 @@ -1218,45 +1217,6 @@ 26.55 return false; 26.56 } 26.57 26.58 - private class AnnotationCollector extends TreeScanner { 26.59 - List<JCTree> path = List.nil(); 26.60 - static final boolean verbose = false; 26.61 - List<JCAnnotation> annotations = List.nil(); 26.62 - 26.63 - public List<JCAnnotation> findAnnotations(List<? extends JCTree> nodes) { 26.64 - annotations = List.nil(); 26.65 - scan(nodes); 26.66 - List<JCAnnotation> found = annotations; 26.67 - annotations = List.nil(); 26.68 - return found.reverse(); 26.69 - } 26.70 - 26.71 - public void scan(JCTree node) { 26.72 - if (node == null) 26.73 - return; 26.74 - Symbol sym = TreeInfo.symbolFor(node); 26.75 - if (sym != null) 26.76 - path = path.prepend(node); 26.77 - super.scan(node); 26.78 - if (sym != null) 26.79 - path = path.tail; 26.80 - } 26.81 - 26.82 - public void visitAnnotation(JCAnnotation node) { 26.83 - annotations = annotations.prepend(node); 26.84 - if (verbose) { 26.85 - StringBuilder sb = new StringBuilder(); 26.86 - for (JCTree tree : path.reverse()) { 26.87 - System.err.print(sb); 26.88 - System.err.println(TreeInfo.symbolFor(tree)); 26.89 - sb.append(" "); 26.90 - } 26.91 - System.err.print(sb); 26.92 - System.err.println(node); 26.93 - } 26.94 - } 26.95 - } 26.96 - 26.97 private static <T extends JCTree> List<T> cleanTrees(List<T> nodes) { 26.98 for (T node : nodes) 26.99 treeCleaner.scan(node);
27.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Mar 04 13:50:33 2010 -0800 27.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Mar 09 15:29:45 2010 -0800 27.3 @@ -720,6 +720,9 @@ 27.4 {0}: major version {1} is newer than {2}, the highest major version supported by this compiler.\n\ 27.5 It is recommended that the compiler be upgraded. 27.6 27.7 +compiler.warn.static.not.qualified.by.type=\ 27.8 + [static] static {0} should be qualified by type name, {1}, instead of by an expression 27.9 + 27.10 # Warnings related to annotation processing 27.11 compiler.warn.proc.package.does.not.exist=\ 27.12 package {0} does not exist
28.1 --- a/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Thu Mar 04 13:50:33 2010 -0800 28.2 +++ b/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Tue Mar 09 15:29:45 2010 -0800 28.3 @@ -201,7 +201,7 @@ 28.4 private String selectFormat(JCDiagnostic d) { 28.5 DiagnosticSource source = d.getDiagnosticSource(); 28.6 String format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT); 28.7 - if (source != null) { 28.8 + if (source != null && source != DiagnosticSource.NO_SOURCE) { 28.9 if (d.getIntPosition() != Position.NOPOS) { 28.10 format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_POS_FORMAT); 28.11 } else if (source.getFile() != null &&
29.1 --- a/src/share/classes/com/sun/tools/javac/util/Log.java Thu Mar 04 13:50:33 2010 -0800 29.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java Tue Mar 09 15:29:45 2010 -0800 29.3 @@ -192,6 +192,12 @@ 29.4 */ 29.5 public int nwarnings = 0; 29.6 29.7 + /** 29.8 + * Whether or not an unrecoverable error has been seen. 29.9 + * Unrecoverable errors prevent subsequent annotation processing. 29.10 + */ 29.11 + public boolean unrecoverableError; 29.12 + 29.13 /** A set of all errors generated so far. This is used to avoid printing an 29.14 * error message more than once. For each error, a pair consisting of the 29.15 * source file name and source code position of the error is added to the set.
30.1 --- a/src/share/classes/com/sun/tools/javadoc/DocEnv.java Thu Mar 04 13:50:33 2010 -0800 30.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Mar 09 15:29:45 2010 -0800 30.3 @@ -34,7 +34,6 @@ 30.4 import com.sun.tools.javac.code.*; 30.5 import com.sun.tools.javac.code.Symbol.*; 30.6 import com.sun.tools.javac.code.Type.ClassType; 30.7 -import com.sun.tools.javac.comp.Attr; 30.8 import com.sun.tools.javac.comp.Check; 30.9 import com.sun.tools.javac.tree.JCTree.*; 30.10 import com.sun.tools.javac.util.Context; 30.11 @@ -73,10 +72,6 @@ 30.12 /** Referenced directly in RootDocImpl. */ 30.13 JavadocClassReader reader; 30.14 30.15 - /** The compiler's attribution phase (needed to evaluate 30.16 - * constant initializers). */ 30.17 - Attr attr; 30.18 - 30.19 /** Javadoc's own version of the compiler's enter phase. */ 30.20 JavadocEnter enter; 30.21 30.22 @@ -91,8 +86,6 @@ 30.23 /** Access filter (public, protected, ...). */ 30.24 ModifierFilter showAccess; 30.25 30.26 - private ClassDocImpl runtimeException; 30.27 - 30.28 /** True if we are using a sentence BreakIterator. */ 30.29 boolean breakiterator; 30.30 30.31 @@ -129,7 +122,6 @@ 30.32 syms = Symtab.instance(context); 30.33 reader = JavadocClassReader.instance0(context); 30.34 enter = JavadocEnter.instance0(context); 30.35 - attr = Attr.instance(context); 30.36 names = Names.instance(context); 30.37 externalizableSym = reader.enterClass(names.fromString("java.io.Externalizable")); 30.38 chk = Check.instance(context);
31.1 --- a/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Thu Mar 04 13:50:33 2010 -0800 31.2 +++ b/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Tue Mar 09 15:29:45 2010 -0800 31.3 @@ -349,12 +349,12 @@ 31.4 // (int i, String s) ==> [0] = "int", [1] = String 31.5 // (int[][], String[]) ==> [0] = "int[][]" // [1] = "String[]" 31.6 class ParameterParseMachine { 31.7 - final int START = 0; 31.8 - final int TYPE = 1; 31.9 - final int NAME = 2; 31.10 - final int TNSPACE = 3; // space between type and name 31.11 - final int ARRAYDECORATION = 4; 31.12 - final int ARRAYSPACE = 5; 31.13 + static final int START = 0; 31.14 + static final int TYPE = 1; 31.15 + static final int NAME = 2; 31.16 + static final int TNSPACE = 3; // space between type and name 31.17 + static final int ARRAYDECORATION = 4; 31.18 + static final int ARRAYSPACE = 5; 31.19 31.20 String parameters; 31.21
32.1 --- a/src/share/classes/com/sun/tools/javah/JavahTask.java Thu Mar 04 13:50:33 2010 -0800 32.2 +++ b/src/share/classes/com/sun/tools/javah/JavahTask.java Tue Mar 09 15:29:45 2010 -0800 32.3 @@ -255,9 +255,11 @@ 32.4 } 32.5 32.6 this.classes = new ArrayList<String>(); 32.7 - for (String classname: classes) { 32.8 - classname.getClass(); // null-check 32.9 - this.classes.add(classname); 32.10 + if (classes != null) { 32.11 + for (String classname: classes) { 32.12 + classname.getClass(); // null-check 32.13 + this.classes.add(classname); 32.14 + } 32.15 } 32.16 } 32.17 32.18 @@ -316,6 +318,12 @@ 32.19 int run(String[] args) { 32.20 try { 32.21 handleOptions(args); 32.22 + if (classes == null || classes.size() == 0) { 32.23 + if (help || version || fullVersion) 32.24 + return 0; 32.25 + else 32.26 + return 1; 32.27 + } 32.28 boolean ok = run(); 32.29 return ok ? 0 : 1; 32.30 } catch (BadArgs e) { 32.31 @@ -347,8 +355,7 @@ 32.32 fileManager = getDefaultFileManager(diagnosticListener, log); 32.33 32.34 Iterator<String> iter = args.iterator(); 32.35 - if (!iter.hasNext()) 32.36 - help = true; 32.37 + boolean noArgs = !iter.hasNext(); 32.38 32.39 while (iter.hasNext()) { 32.40 String arg = iter.next(); 32.41 @@ -365,7 +372,7 @@ 32.42 } 32.43 32.44 if ((classes == null || classes.size() == 0) && 32.45 - !(help || version || fullVersion)) { 32.46 + !(noArgs || help || version || fullVersion)) { 32.47 throw new BadArgs("err.no.classes.specified"); 32.48 } 32.49
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/tools/javac/4880220/T4880220.error.out Tue Mar 09 15:29:45 2010 -0800 33.3 @@ -0,0 +1,9 @@ 33.4 +T4880220.java:20:27: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C 33.5 +T4880220.java:21:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 33.6 +T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 33.7 +T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C 33.8 +T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 33.9 +T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 33.10 +- compiler.err.warnings.and.werror 33.11 +1 error 33.12 +6 warnings
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/test/tools/javac/4880220/T4880220.java Tue Mar 09 15:29:45 2010 -0800 34.3 @@ -0,0 +1,43 @@ 34.4 +/* 34.5 + * @test /nodynamiccopyright/ 34.6 + * @bug 4880220 34.7 + * @summary Add a warning when accessing a static method via an reference 34.8 + * 34.9 + * @compile/ref=T4880220.empty.out T4880220.java 34.10 + * @compile/ref=T4880220.warn.out -XDrawDiagnostics -Xlint:static T4880220.java 34.11 + * @compile/ref=T4880220.warn.out -XDrawDiagnostics -Xlint:all T4880220.java 34.12 + * @compile/ref=T4880220.empty.out -XDrawDiagnostics -Xlint:all,-static T4880220.java 34.13 + * @compile/ref=T4880220.error.out/fail -XDrawDiagnostics -Werror -Xlint:all T4880220.java 34.14 + */ 34.15 + 34.16 +public class T4880220 { 34.17 + void m1() { 34.18 + int good_1 = C.m(); 34.19 + int good_2 = C.f; 34.20 + int good_3 = C.x; 34.21 + 34.22 + C c = new C(); 34.23 + int bad_inst_1 = c.m(); 34.24 + int bad_inst_2 = c.f; 34.25 + int bad_inst_3 = c.x; 34.26 + 34.27 + int bad_expr_1 = c().m(); 34.28 + int bad_expr_2 = c().f; 34.29 + int bad_expr_3 = c().x; 34.30 + } 34.31 + 34.32 + void m2() { 34.33 + Class<?> good_1 = C.class; 34.34 + Class<?> good_2 = C[].class; 34.35 + } 34.36 + 34.37 + C c() { 34.38 + return new C(); 34.39 + } 34.40 + 34.41 + static class C { 34.42 + static int m() { return 0; } 34.43 + static int f; 34.44 + static final int x = 3; 34.45 + } 34.46 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/test/tools/javac/4880220/T4880220.warn.out Tue Mar 09 15:29:45 2010 -0800 35.3 @@ -0,0 +1,7 @@ 35.4 +T4880220.java:20:27: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C 35.5 +T4880220.java:21:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 35.6 +T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 35.7 +T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C 35.8 +T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 35.9 +T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C 35.10 +6 warnings
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/test/tools/javac/T6881645.java Tue Mar 09 15:29:45 2010 -0800 36.3 @@ -0,0 +1,38 @@ 36.4 +/* 36.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.7 + * 36.8 + * This code is free software; you can redistribute it and/or modify it 36.9 + * under the terms of the GNU General Public License version 2 only, as 36.10 + * published by the Free Software Foundation. 36.11 + * 36.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 36.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 36.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36.15 + * version 2 for more details (a copy is included in the LICENSE file that 36.16 + * accompanied this code). 36.17 + * 36.18 + * You should have received a copy of the GNU General Public License version 36.19 + * 2 along with this work; if not, write to the Free Software Foundation, 36.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 36.21 + * 36.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 36.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 36.24 + * have any questions. 36.25 + */ 36.26 + 36.27 +/* 36.28 + * @test 36.29 + * @summary Unchecked method call on a method declared inside anonymous inner causes javac to crash 36.30 + * @compile -Xlint:unchecked T6881645.java 36.31 + */ 36.32 + 36.33 +class T6881645 { 36.34 + Object o = new Object() { 36.35 + <Z> void m (Class<Z> x) {} 36.36 + void test() { 36.37 + m((Class)null); 36.38 + } 36.39 + }; 36.40 +} 36.41 +
37.1 --- a/test/tools/javac/ThrowsIntersection_1.java Thu Mar 04 13:50:33 2010 -0800 37.2 +++ b/test/tools/javac/ThrowsIntersection_1.java Tue Mar 09 15:29:45 2010 -0800 37.3 @@ -30,6 +30,8 @@ 37.4 * @compile ThrowsIntersection_1.java 37.5 */ 37.6 37.7 +package ThrowsIntersection_1; 37.8 + 37.9 class Ex1 extends Exception {} 37.10 class Ex2 extends Exception {} 37.11
38.1 --- a/test/tools/javac/ThrowsIntersection_2.java Thu Mar 04 13:50:33 2010 -0800 38.2 +++ b/test/tools/javac/ThrowsIntersection_2.java Tue Mar 09 15:29:45 2010 -0800 38.3 @@ -30,6 +30,8 @@ 38.4 * @compile ThrowsIntersection_2.java 38.5 */ 38.6 38.7 +package ThrowsIntersection_2; 38.8 + 38.9 class Ex1 extends Exception {} 38.10 class Ex2 extends Exception {} 38.11 class Ex3 extends Exception {}
39.1 --- a/test/tools/javac/ThrowsIntersection_3.java Thu Mar 04 13:50:33 2010 -0800 39.2 +++ b/test/tools/javac/ThrowsIntersection_3.java Tue Mar 09 15:29:45 2010 -0800 39.3 @@ -30,6 +30,8 @@ 39.4 * @run compile/fail ThrowsIntersection_3.java 39.5 */ 39.6 39.7 +package ThrowsIntersection_3; 39.8 + 39.9 class Ex1 extends Exception {} 39.10 class Ex2 extends Exception {} 39.11
40.1 --- a/test/tools/javac/ThrowsIntersection_4.java Thu Mar 04 13:50:33 2010 -0800 40.2 +++ b/test/tools/javac/ThrowsIntersection_4.java Tue Mar 09 15:29:45 2010 -0800 40.3 @@ -30,6 +30,8 @@ 40.4 * @run compile/fail ThrowsIntersection_4.java 40.5 */ 40.6 40.7 +package ThrowsIntersection_4; 40.8 + 40.9 // Note: This is the test that actually failed for 4042259. The others are for completeness. 40.10 40.11 class Ex1 extends Exception {}
41.1 --- a/test/tools/javac/annotations/neg/Constant.java Thu Mar 04 13:50:33 2010 -0800 41.2 +++ b/test/tools/javac/annotations/neg/Constant.java Tue Mar 09 15:29:45 2010 -0800 41.3 @@ -30,7 +30,7 @@ 41.4 * @compile/fail Constant.java 41.5 */ 41.6 41.7 -package test.tools.javac.annotation.Constant; 41.8 +package Constant; 41.9 41.10 @T(a = X.x) 41.11 @interface T {
42.1 --- a/test/tools/javac/api/TestJavacTaskScanner.java Thu Mar 04 13:50:33 2010 -0800 42.2 +++ b/test/tools/javac/api/TestJavacTaskScanner.java Tue Mar 09 15:29:45 2010 -0800 42.3 @@ -34,7 +34,10 @@ 42.4 import com.sun.tools.javac.parser.*; // XXX 42.5 import com.sun.tools.javac.util.*; // XXX 42.6 import java.io.*; 42.7 +import java.net.*; 42.8 import java.nio.*; 42.9 +import java.nio.charset.Charset; 42.10 +import java.util.Arrays; 42.11 import javax.lang.model.element.Element; 42.12 import javax.lang.model.element.TypeElement; 42.13 import javax.lang.model.type.DeclaredType; 42.14 @@ -43,6 +46,10 @@ 42.15 import javax.lang.model.util.Types; 42.16 import javax.tools.*; 42.17 42.18 +import static javax.tools.StandardLocation.CLASS_PATH; 42.19 +import static javax.tools.StandardLocation.SOURCE_PATH; 42.20 +import static javax.tools.StandardLocation.CLASS_OUTPUT; 42.21 + 42.22 public class TestJavacTaskScanner extends ToolTester { 42.23 42.24 final JavacTaskImpl task; 42.25 @@ -56,6 +63,7 @@ 42.26 TestJavacTaskScanner(File file) { 42.27 final Iterable<? extends JavaFileObject> compilationUnits = 42.28 fm.getJavaFileObjects(new File[] {file}); 42.29 + StandardJavaFileManager fm = getLocalFileManager(tool, null, null); 42.30 task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits); 42.31 task.getContext().put(Scanner.Factory.scannerFactoryKey, 42.32 new MyScanner.Factory(task.getContext(), this)); 42.33 @@ -83,7 +91,7 @@ 42.34 System.out.println("#parseTypeElements: " + numParseTypeElements); 42.35 System.out.println("#allMembers: " + numAllMembers); 42.36 42.37 - check(numTokens, "#Tokens", 891); 42.38 + check(numTokens, "#Tokens", 1222); 42.39 check(numParseTypeElements, "#parseTypeElements", 136); 42.40 check(numAllMembers, "#allMembers", 67); 42.41 } 42.42 @@ -117,6 +125,47 @@ 42.43 numAllMembers++; 42.44 } 42.45 } 42.46 + 42.47 + /* Similar to ToolTester.getFileManager, except that this version also ensures 42.48 + * javac classes will be available on the classpath. The javac classes are assumed 42.49 + * to be on the classpath used to run this test (this is true when using jtreg). 42.50 + * The classes are found by obtaining the URL for a sample javac class, using 42.51 + * getClassLoader().getResource(), and then deconstructing the URL to find the 42.52 + * underlying directory or jar file to place on the classpath. 42.53 + */ 42.54 + public StandardJavaFileManager getLocalFileManager(JavaCompiler tool, 42.55 + DiagnosticListener<JavaFileObject> dl, 42.56 + Charset encoding) { 42.57 + File javac_classes; 42.58 + try { 42.59 + final String javacMainClass = "com/sun/tools/javac/Main.class"; 42.60 + URL url = getClass().getClassLoader().getResource(javacMainClass); 42.61 + if (url == null) 42.62 + throw new Error("can't locate javac classes"); 42.63 + URI uri = url.toURI(); 42.64 + String scheme = uri.getScheme(); 42.65 + String ssp = uri.getSchemeSpecificPart(); 42.66 + if (scheme.equals("jar")) { 42.67 + javac_classes = new File(new URI(ssp.substring(0, ssp.indexOf("!/")))); 42.68 + } else if (scheme.equals("file")) { 42.69 + javac_classes = new File(ssp.substring(0, ssp.indexOf(javacMainClass))); 42.70 + } else 42.71 + throw new Error("unknown URL: " + url); 42.72 + } catch (URISyntaxException e) { 42.73 + throw new Error(e); 42.74 + } 42.75 + System.err.println("javac_classes: " + javac_classes); 42.76 + 42.77 + StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, encoding); 42.78 + try { 42.79 + fm.setLocation(SOURCE_PATH, Arrays.asList(test_src)); 42.80 + fm.setLocation(CLASS_PATH, Arrays.asList(test_classes, javac_classes)); 42.81 + fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes)); 42.82 + } catch (IOException e) { 42.83 + throw new AssertionError(e); 42.84 + } 42.85 + return fm; 42.86 + } 42.87 } 42.88 42.89 class MyScanner extends Scanner {
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/test/tools/javac/api/TestResolveError.java Tue Mar 09 15:29:45 2010 -0800 43.3 @@ -0,0 +1,101 @@ 43.4 +/* 43.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.7 + * 43.8 + * This code is free software; you can redistribute it and/or modify it 43.9 + * under the terms of the GNU General Public License version 2 only, as 43.10 + * published by the Free Software Foundation. 43.11 + * 43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 43.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 43.15 + * version 2 for more details (a copy is included in the LICENSE file that 43.16 + * accompanied this code). 43.17 + * 43.18 + * You should have received a copy of the GNU General Public License version 43.19 + * 2 along with this work; if not, write to the Free Software Foundation, 43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 43.21 + * 43.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 43.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 43.24 + * have any questions. 43.25 + */ 43.26 + 43.27 +/** 43.28 + * @test 43.29 + * @bug 6930108 43.30 + * @summary IllegalArgumentException in AbstractDiagnosticFormatter for tools/javac/api/TestJavacTaskScanner.java 43.31 + * @library ./lib 43.32 + * @build ToolTester 43.33 + * @run main TestResolveError 43.34 + */ 43.35 + 43.36 +import java.io.*; 43.37 +import javax.lang.model.element.Element; 43.38 +import javax.lang.model.element.TypeElement; 43.39 +import javax.lang.model.type.DeclaredType; 43.40 +import javax.lang.model.type.TypeMirror; 43.41 +import javax.lang.model.util.Elements; 43.42 +import javax.lang.model.util.Types; 43.43 +import javax.tools.*; 43.44 + 43.45 +import com.sun.tools.javac.api.JavacTaskImpl; 43.46 + 43.47 +/* 43.48 + * This is a cut down version of TestJavacTaskScanner, which as originally written 43.49 + * caused an IllegalArgumentException in AbstractDiagnosticFormatter as a result 43.50 + * of calling task.parseType with a name whose resolution depended on the setting 43.51 + * of the bootclasspath. 43.52 + * This test has the same call, task.parseType("List<String>", clazz), but checks 43.53 + * that the error is handled in a reasonable way by javac. 43.54 + */ 43.55 +public class TestResolveError extends ToolTester { 43.56 + public static void main(String... args) throws Exception { 43.57 + new TestResolveError().run(); 43.58 + } 43.59 + 43.60 + void run() throws Exception { 43.61 + StringWriter sw = new StringWriter(); 43.62 + PrintWriter pw = new PrintWriter(sw); 43.63 + File file = new File(test_src, "TestResolveError.java"); 43.64 + final Iterable<? extends JavaFileObject> compilationUnits = 43.65 + fm.getJavaFileObjects(new File[] {file}); 43.66 + task = (JavacTaskImpl)tool.getTask(pw, fm, null, null, null, compilationUnits); 43.67 + elements = task.getElements(); 43.68 + types = task.getTypes(); 43.69 + 43.70 + Iterable<? extends TypeElement> toplevels; 43.71 + try { 43.72 + toplevels = task.enter(task.parse()); 43.73 + } catch (IOException ex) { 43.74 + throw new AssertionError(ex); 43.75 + } 43.76 + 43.77 + for (TypeElement clazz : toplevels) { 43.78 + System.out.format("Testing %s:%n%n", clazz.getSimpleName()); 43.79 + // this should not cause any exception from the compiler, 43.80 + // such as IllegalArgumentException 43.81 + testParseType(clazz); 43.82 + } 43.83 + 43.84 + pw.close(); 43.85 + 43.86 + String out = sw.toString(); 43.87 + System.out.println(out); 43.88 + 43.89 + if (out.contains("com.sun.tools.javac.util")) 43.90 + throw new Exception("Unexpected output from compiler"); 43.91 + } 43.92 + 43.93 + void testParseType(TypeElement clazz) { 43.94 + DeclaredType type = (DeclaredType)task.parseType("List<String>", clazz); 43.95 + for (Element member : elements.getAllMembers((TypeElement)type.asElement())) { 43.96 + TypeMirror mt = types.asMemberOf(type, member); 43.97 + System.out.format("%s : %s -> %s%n", member.getSimpleName(), member.asType(), mt); 43.98 + } 43.99 + } 43.100 + 43.101 + JavacTaskImpl task; 43.102 + Elements elements; 43.103 + Types types; 43.104 +}
44.1 --- a/test/tools/javac/generics/Casting.java Thu Mar 04 13:50:33 2010 -0800 44.2 +++ b/test/tools/javac/generics/Casting.java Tue Mar 09 15:29:45 2010 -0800 44.3 @@ -30,7 +30,7 @@ 44.4 * @compile Casting.java 44.5 */ 44.6 44.7 -package test.tools.javac.generics.Casting; 44.8 +package Casting; 44.9 44.10 class Test {} 44.11
45.1 --- a/test/tools/javac/generics/Casting3.java Thu Mar 04 13:50:33 2010 -0800 45.2 +++ b/test/tools/javac/generics/Casting3.java Tue Mar 09 15:29:45 2010 -0800 45.3 @@ -30,7 +30,7 @@ 45.4 * @compile Casting3.java 45.5 */ 45.6 45.7 -package test.tools.javac.generics.Casting3; 45.8 +package Casting3; 45.9 45.10 class A<T extends A<T>> { 45.11 <U extends A<U>> void f() {
46.1 --- a/test/tools/javac/generics/Casting4.java Thu Mar 04 13:50:33 2010 -0800 46.2 +++ b/test/tools/javac/generics/Casting4.java Tue Mar 09 15:29:45 2010 -0800 46.3 @@ -30,7 +30,7 @@ 46.4 * @compile -Werror -Xlint:unchecked Casting4.java 46.5 */ 46.6 46.7 -package test.tools.javac.generics.Casting4; 46.8 +package Casting4; 46.9 46.10 class Casting4 { 46.11 <M> Integer f(Comparable<M> c) {
47.1 --- a/test/tools/javac/generics/InnerInterface1.java Thu Mar 04 13:50:33 2010 -0800 47.2 +++ b/test/tools/javac/generics/InnerInterface1.java Tue Mar 09 15:29:45 2010 -0800 47.3 @@ -30,7 +30,7 @@ 47.4 * @compile InnerInterface1.java 47.5 */ 47.6 47.7 -package test.tools.javac.generics.InnerInterface1; 47.8 +package InnerInterface1; 47.9 47.10 interface Iterator<E> { 47.11 }
48.1 --- a/test/tools/javac/generics/InnerInterface2.java Thu Mar 04 13:50:33 2010 -0800 48.2 +++ b/test/tools/javac/generics/InnerInterface2.java Tue Mar 09 15:29:45 2010 -0800 48.3 @@ -30,7 +30,7 @@ 48.4 * @compile InnerInterface2.java 48.5 */ 48.6 48.7 -package test.tools.javac.generics.InnerInterface2; 48.8 +package InnerInterface2; 48.9 48.10 class Builder<Community> { 48.11
49.1 --- a/test/tools/javac/generics/Multibound1.java Thu Mar 04 13:50:33 2010 -0800 49.2 +++ b/test/tools/javac/generics/Multibound1.java Tue Mar 09 15:29:45 2010 -0800 49.3 @@ -30,7 +30,7 @@ 49.4 * @compile/fail Multibound1.java 49.5 */ 49.6 49.7 -package test.tools.javac.generics.Multibound1; 49.8 +package Multibound1; 49.9 49.10 interface A {} 49.11 interface B {}
50.1 --- a/test/tools/javac/generics/MultipleInheritance.java Thu Mar 04 13:50:33 2010 -0800 50.2 +++ b/test/tools/javac/generics/MultipleInheritance.java Tue Mar 09 15:29:45 2010 -0800 50.3 @@ -30,7 +30,7 @@ 50.4 * @compile MultipleInheritance.java 50.5 */ 50.6 50.7 -package test.tools.javac.generics.MultipleInheritance; 50.8 +package MultipleInheritance; 50.9 50.10 import java.util.*; 50.11
51.1 --- a/test/tools/javac/generics/NameOrder.java Thu Mar 04 13:50:33 2010 -0800 51.2 +++ b/test/tools/javac/generics/NameOrder.java Tue Mar 09 15:29:45 2010 -0800 51.3 @@ -27,22 +27,22 @@ 51.4 * @summary generics: type inference failure due to a bug in ClassSymbol.isLess 51.5 * @author gafter 51.6 * 51.7 - * @compile NameOrder.java 51.8 + * @compile NameOrder.java 51.9 */ 51.10 51.11 -package test.tools.javac.generics.NameOrder; 51.12 +package NameOrder; 51.13 51.14 interface a {} 51.15 interface b {} 51.16 interface c {} 51.17 51.18 -class A implements a, b {} 51.19 -class B implements c, a {} 51.20 +class AB implements a, b {} 51.21 +class CA implements c, a {} 51.22 51.23 // this is how to trigger a symptom: 51.24 -abstract class C { 51.25 +abstract class X { 51.26 <T> T f(T t1, T t2) { return null; } 51.27 void g() { 51.28 - a x = f( new A(), new B() ); 51.29 + a x = f( new AB(), new CA() ); 51.30 } 51.31 }
52.1 --- a/test/tools/javac/generics/PermuteBound.java Thu Mar 04 13:50:33 2010 -0800 52.2 +++ b/test/tools/javac/generics/PermuteBound.java Tue Mar 09 15:29:45 2010 -0800 52.3 @@ -30,7 +30,7 @@ 52.4 * @compile PermuteBound.java 52.5 */ 52.6 52.7 -package test.tools.javac.generics.PermuteBound; 52.8 +package PermuteBound; 52.9 52.10 class C<X, Y> {} 52.11
53.1 --- a/test/tools/javac/generics/PrimitiveVariant.java Thu Mar 04 13:50:33 2010 -0800 53.2 +++ b/test/tools/javac/generics/PrimitiveVariant.java Tue Mar 09 15:29:45 2010 -0800 53.3 @@ -30,7 +30,7 @@ 53.4 * @compile/fail PrimitiveVariant.java 53.5 */ 53.6 53.7 -package test.tools.javac.generics.PrimitiveVariant; 53.8 +package PrimitiveVariant; 53.9 53.10 interface I { 53.11 double m();
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/test/tools/javac/processing/6511613/DummyProcessor.java Tue Mar 09 15:29:45 2010 -0800 54.3 @@ -0,0 +1,40 @@ 54.4 +/* 54.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 54.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 54.7 + * 54.8 + * This code is free software; you can redistribute it and/or modify it 54.9 + * under the terms of the GNU General Public License version 2 only, as 54.10 + * published by the Free Software Foundation. 54.11 + * 54.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 54.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 54.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 54.15 + * version 2 for more details (a copy is included in the LICENSE file that 54.16 + * accompanied this code). 54.17 + * 54.18 + * You should have received a copy of the GNU General Public License version 54.19 + * 2 along with this work; if not, write to the Free Software Foundation, 54.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 54.21 + * 54.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 54.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 54.24 + * have any questions. 54.25 + */ 54.26 + 54.27 +import javax.annotation.processing.*; 54.28 +import javax.lang.model.*; 54.29 +import javax.lang.model.element.*; 54.30 +import java.util.Set; 54.31 + 54.32 +@SupportedAnnotationTypes("*") 54.33 +public class DummyProcessor extends AbstractProcessor { 54.34 + public boolean process(Set<? extends TypeElement> annotations, 54.35 + RoundEnvironment roundEnv) { 54.36 + return true; 54.37 + } 54.38 + @Override 54.39 + public SourceVersion getSupportedSourceVersion() { 54.40 + return SourceVersion.latest(); 54.41 + } 54.42 +} 54.43 +
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/test/tools/javac/processing/6511613/clss41701.java Tue Mar 09 15:29:45 2010 -0800 55.3 @@ -0,0 +1,43 @@ 55.4 +/* 55.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 55.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 55.7 + * 55.8 + * This code is free software; you can redistribute it and/or modify it 55.9 + * under the terms of the GNU General Public License version 2 only, as 55.10 + * published by the Free Software Foundation. 55.11 + * 55.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 55.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 55.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 55.15 + * version 2 for more details (a copy is included in the LICENSE file that 55.16 + * accompanied this code). 55.17 + * 55.18 + * You should have received a copy of the GNU General Public License version 55.19 + * 2 along with this work; if not, write to the Free Software Foundation, 55.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 55.21 + * 55.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 55.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 55.24 + * have any questions. 55.25 + */ 55.26 + 55.27 +/* 55.28 + * @test 55.29 + * @bug 6511613 55.30 + * @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified 55.31 + * 55.32 + * @build DummyProcessor 55.33 + * @compile/fail clss41701.java 55.34 + * @compile/fail -processor DummyProcessor clss41701.java 55.35 + */ 55.36 + 55.37 +import java.io.PrintStream; 55.38 + 55.39 +interface clss41701i { 55.40 + void run(); 55.41 +} 55.42 + 55.43 +class clss41701a<A extends clss41701i, 55.44 + B extends clss41701i, 55.45 + C extends A&B> { 55.46 +}
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/test/tools/javac/processing/model/element/TestAnonClassNames.java Tue Mar 09 15:29:45 2010 -0800 56.3 @@ -0,0 +1,186 @@ 56.4 +/* 56.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 56.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 56.7 + * 56.8 + * This code is free software; you can redistribute it and/or modify it 56.9 + * under the terms of the GNU General Public License version 2 only, as 56.10 + * published by the Free Software Foundation. 56.11 + * 56.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 56.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 56.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 56.15 + * version 2 for more details (a copy is included in the LICENSE file that 56.16 + * accompanied this code). 56.17 + * 56.18 + * You should have received a copy of the GNU General Public License version 56.19 + * 2 along with this work; if not, write to the Free Software Foundation, 56.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 56.21 + * 56.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 56.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 56.24 + * have any questions. 56.25 + */ 56.26 + 56.27 +/* 56.28 + * @test 56.29 + * @bug 6449781 56.30 + * @summary Test that reported names of anonymous classes are non-null. 56.31 + * @author Joseph D. Darcy 56.32 + * @build TestAnonSourceNames 56.33 + * @compile/fail -processor TestAnonSourceNames TestAnonClassNames.java 56.34 + * @build TestAnonClassNames 56.35 + * @run main TestAnonClassNames 56.36 + */ 56.37 + 56.38 +/* 56.39 + * This test operates in phases to test retrieving the qualified name 56.40 + * of anonymous classes from type elements modeling the anonymous 56.41 + * class. The type elements are generated using both source files and 56.42 + * class files as the basis of constructing the elements. 56.43 + * 56.44 + * Source files will be tested by the @compile line which runs 56.45 + * TestAnonSourceNames as an annotation processor over this file. 56.46 + * This compile line is expected to fail until 6930507 is fixed. Once 56.47 + * bug 6930507 is fixed, the "@compile/fail -processor ..." and 56.48 + * following "@build..." steps can be replaced with a single "@compile 56.49 + * -processor ..." directive. 56.50 + * 56.51 + * Class files are tested by the @run command on this type. This 56.52 + * class gets the names of classes with different nesting kinds, 56.53 + * including anonymous classes, and then invokes the compiler with an 56.54 + * annotation processor having the class files names as inputs. The 56.55 + * compiler is invoked via the javax.tools mechanism. 56.56 + */ 56.57 + 56.58 +import java.lang.annotation.*; 56.59 +import javax.lang.model.element.*; 56.60 +import javax.annotation.processing.*; 56.61 +import javax.lang.model.SourceVersion; 56.62 +import javax.lang.model.element.*; 56.63 +import javax.lang.model.util.*; 56.64 +import javax.tools.*; 56.65 +import java.util.*; 56.66 + 56.67 +import static java.lang.annotation.RetentionPolicy.*; 56.68 +import static javax.lang.model.element.NestingKind.*; 56.69 +import static javax.lang.model.util.ElementFilter.*; 56.70 +import static javax.tools.Diagnostic.Kind.*; 56.71 +import static javax.tools.StandardLocation.*; 56.72 + 56.73 +@Nesting(TOP_LEVEL) 56.74 +public class TestAnonClassNames { 56.75 + @Nesting(MEMBER) 56.76 + static class MemberClass1{} 56.77 + 56.78 + @Nesting(MEMBER) 56.79 + class MemberClass2{} 56.80 + 56.81 + @Nesting(MEMBER) 56.82 + class Win$$AtVegas { } // Class with funny name. 56.83 + 56.84 + public static void main(String... argv) { 56.85 + @Nesting(LOCAL) 56.86 + class LocalClass{}; 56.87 + 56.88 + Object o = new @Nesting(ANONYMOUS) Object() { // An anonymous annotated class 56.89 + public String toString() { 56.90 + return "I have no name!"; 56.91 + } 56.92 + }; 56.93 + 56.94 + Class<?>[] classes = { 56.95 + MemberClass1.class, 56.96 + MemberClass2.class, 56.97 + LocalClass.class, 56.98 + Win$$AtVegas.class, 56.99 + o.getClass(), 56.100 + TestAnonClassNames.class, 56.101 + }; 56.102 + 56.103 + for(Class<?> clazz : classes) { 56.104 + String name = clazz.getName(); 56.105 + System.out.format("%s is %s%n", 56.106 + clazz.getName(), 56.107 + clazz.getAnnotation(Nesting.class).value()); 56.108 + testClassName(name); 56.109 + } 56.110 + } 56.111 + 56.112 + /** 56.113 + * Perform annotation processing on the class file name and verify 56.114 + * the existence of different flavors of class names when the 56.115 + * input classes are modeled as elements. 56.116 + */ 56.117 + static void testClassName(String className) { 56.118 + JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 56.119 + List<String> classNames = new ArrayList<>(); 56.120 + classNames.add(className); 56.121 + 56.122 + List<String> options = new ArrayList<>(); 56.123 + options.add("-proc:only"); 56.124 + options.add("-classpath"); 56.125 + options.add(System.getProperty("test.classes")); 56.126 + 56.127 + JavaCompiler.CompilationTask compileTask = 56.128 + javaCompiler.getTask(null, // Output 56.129 + null, // File manager 56.130 + null, // Diagnostics 56.131 + options, 56.132 + classNames, 56.133 + null); // Sources 56.134 + List<Processor> processors = new ArrayList<>(); 56.135 + processors.add(new ClassNameProber()); 56.136 + compileTask.setProcessors(processors); 56.137 + Boolean goodResult = compileTask.call(); 56.138 + if (!goodResult) { 56.139 + throw new RuntimeException("Errors found during compile."); 56.140 + } 56.141 + } 56.142 +} 56.143 + 56.144 +@Retention(RUNTIME) 56.145 +@interface Nesting { 56.146 + NestingKind value(); 56.147 +} 56.148 + 56.149 +/** 56.150 + * Probe at the various kinds of names of a type element. 56.151 + */ 56.152 +@SupportedAnnotationTypes("*") 56.153 +class ClassNameProber extends AbstractProcessor { 56.154 + public ClassNameProber(){super();} 56.155 + 56.156 + private boolean classesFound=false; 56.157 + 56.158 + public boolean process(Set<? extends TypeElement> annotations, 56.159 + RoundEnvironment roundEnv) { 56.160 + if (!roundEnv.processingOver()) { 56.161 + for(TypeElement typeElt : typesIn(roundEnv.getRootElements())) { 56.162 + classesFound = true; 56.163 + 56.164 + // Verify different names are non-null; an NPE will 56.165 + // result in failed compile status being reported. 56.166 + NestingKind nestingKind = typeElt.getNestingKind(); 56.167 + System.out.printf("\tSimple name: ''%s''\tQualified Name: ''%s''\tKind ''%s''\tNesting ''%s''%n", 56.168 + typeElt.getSimpleName().toString(), 56.169 + typeElt.getQualifiedName().toString(), 56.170 + typeElt.getKind().toString(), 56.171 + nestingKind.toString()); 56.172 + 56.173 + if (typeElt.getAnnotation(Nesting.class).value() != nestingKind) { 56.174 + throw new RuntimeException("Mismatch of expected and reported nesting kind."); 56.175 + } 56.176 + } 56.177 + 56.178 + } 56.179 + 56.180 + if (!classesFound) { 56.181 + throw new RuntimeException("Error: no classes processed."); 56.182 + } 56.183 + return true; 56.184 + } 56.185 + 56.186 + public SourceVersion getSupportedSourceVersion() { 56.187 + return SourceVersion.latest(); 56.188 + } 56.189 +}
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/test/tools/javac/processing/model/element/TestAnonSourceNames.java Tue Mar 09 15:29:45 2010 -0800 57.3 @@ -0,0 +1,92 @@ 57.4 +/* 57.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 57.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 57.7 + * 57.8 + * This code is free software; you can redistribute it and/or modify it 57.9 + * under the terms of the GNU General Public License version 2 only, as 57.10 + * published by the Free Software Foundation. 57.11 + * 57.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 57.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 57.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 57.15 + * version 2 for more details (a copy is included in the LICENSE file that 57.16 + * accompanied this code). 57.17 + * 57.18 + * You should have received a copy of the GNU General Public License version 57.19 + * 2 along with this work; if not, write to the Free Software Foundation, 57.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 57.21 + * 57.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 57.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 57.24 + * have any questions. 57.25 + */ 57.26 + 57.27 +import java.io.*; 57.28 +import javax.annotation.processing.*; 57.29 +import javax.lang.model.*; 57.30 +import javax.lang.model.element.*; 57.31 +import javax.lang.model.type.*; 57.32 +import javax.lang.model.util.*; 57.33 +import java.util.*; 57.34 +import com.sun.source.tree.*; 57.35 +import com.sun.source.util.*; 57.36 +import static javax.tools.Diagnostic.Kind.*; 57.37 + 57.38 +/** 57.39 + * Using the tree API, retrieve element representations of anonymous 57.40 + * classes and verify their names are as specified. 57.41 + */ 57.42 +@SupportedAnnotationTypes("*") 57.43 +public class TestAnonSourceNames extends AbstractProcessor { 57.44 + 57.45 + public boolean process(Set<? extends TypeElement> annotations, 57.46 + RoundEnvironment roundEnv) { 57.47 + if (!roundEnv.processingOver()) { 57.48 + Trees trees = Trees.instance(processingEnv); 57.49 + 57.50 + for(Element rootElement : roundEnv.getRootElements()) { 57.51 + TreePath treePath = trees.getPath(rootElement); 57.52 + 57.53 + (new ClassTreeScanner(trees)). 57.54 + scan(trees.getTree(rootElement), 57.55 + treePath.getCompilationUnit()); 57.56 + } 57.57 + } 57.58 + return true; 57.59 + } 57.60 + 57.61 + class ClassTreeScanner extends TreeScanner<Void, CompilationUnitTree> { 57.62 + private Trees trees; 57.63 + 57.64 + public ClassTreeScanner(Trees trees) { 57.65 + super(); 57.66 + this.trees = trees; 57.67 + } 57.68 + @Override 57.69 + public Void visitClass(ClassTree node, CompilationUnitTree cu) { 57.70 + Element element = trees.getElement(trees.getPath(cu, node)); 57.71 + if (element == null) { 57.72 + processingEnv.getMessager().printMessage(ERROR, 57.73 + "No element retreived for node named ''" + 57.74 + node.getSimpleName() + "''."); 57.75 + } else { 57.76 + 57.77 + System.out.println("\nVisiting class ``" + element.getSimpleName() + 57.78 + "'' of kind " + element.getKind()); 57.79 + if (element instanceof TypeElement) { 57.80 + TypeElement typeElement = (TypeElement) element; 57.81 + String s = typeElement.getQualifiedName().toString(); 57.82 + System.out.println("\tqualified name:" + s); 57.83 + } else { 57.84 + throw new RuntimeException("TypeElement not gotten from ClassTree."); 57.85 + } 57.86 + } 57.87 + return super.visitClass(node, cu); 57.88 + } 57.89 + } 57.90 + 57.91 + @Override 57.92 + public SourceVersion getSupportedSourceVersion() { 57.93 + return SourceVersion.latest(); 57.94 + } 57.95 +}
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/test/tools/javac/tree/TestAnnotatedAnonClass.java Tue Mar 09 15:29:45 2010 -0800 58.3 @@ -0,0 +1,37 @@ 58.4 +/* 58.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 58.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 58.7 + * 58.8 + * This code is free software; you can redistribute it and/or modify it 58.9 + * under the terms of the GNU General Public License version 2 only, as 58.10 + * published by the Free Software Foundation. 58.11 + * 58.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 58.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 58.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 58.15 + * version 2 for more details (a copy is included in the LICENSE file that 58.16 + * accompanied this code). 58.17 + * 58.18 + * You should have received a copy of the GNU General Public License version 58.19 + * 2 along with this work; if not, write to the Free Software Foundation, 58.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 58.21 + * 58.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 58.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 58.24 + * have any questions. 58.25 + */ 58.26 + 58.27 + 58.28 +/* 58.29 + * This file is not a regular test, but is processed by ./TreePosTest.java, 58.30 + * which verifies the position info in the javac tree. 58.31 + * To run the test standalone, compile TreePosTest, then run TreePosTest 58.32 + * on this file. 58.33 + * @bug 6931927 58.34 + * @summary position issues with synthesized anonymous class 58.35 + */ 58.36 +class TestAnnotatedAnonClass { 58.37 + void m() { 58.38 + Object o = new @Deprecated Object() { }; 58.39 + } 58.40 +}
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/test/tools/javac/tree/TreePosTest.java Tue Mar 09 15:29:45 2010 -0800 59.3 @@ -0,0 +1,762 @@ 59.4 +/* 59.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 59.7 + * 59.8 + * This code is free software; you can redistribute it and/or modify it 59.9 + * under the terms of the GNU General Public License version 2 only, as 59.10 + * published by the Free Software Foundation. 59.11 + * 59.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 59.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 59.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 59.15 + * version 2 for more details (a copy is included in the LICENSE file that 59.16 + * accompanied this code). 59.17 + * 59.18 + * You should have received a copy of the GNU General Public License version 59.19 + * 2 along with this work; if not, write to the Free Software Foundation, 59.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 59.21 + * 59.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 59.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 59.24 + * have any questions. 59.25 + */ 59.26 + 59.27 +import java.awt.BorderLayout; 59.28 +import java.awt.Color; 59.29 +import java.awt.Dimension; 59.30 +import java.awt.EventQueue; 59.31 +import java.awt.Font; 59.32 +import java.awt.GridBagConstraints; 59.33 +import java.awt.GridBagLayout; 59.34 +import java.awt.Rectangle; 59.35 +import java.awt.event.ActionEvent; 59.36 +import java.awt.event.ActionListener; 59.37 +import java.awt.event.MouseAdapter; 59.38 +import java.awt.event.MouseEvent; 59.39 +import java.io.File; 59.40 +import java.io.IOException; 59.41 +import java.io.PrintStream; 59.42 +import java.io.PrintWriter; 59.43 +import java.io.StringWriter; 59.44 +import java.lang.reflect.Field; 59.45 +import java.lang.reflect.Modifier; 59.46 +import java.nio.charset.Charset; 59.47 +import java.util.ArrayList; 59.48 +import java.util.Collections; 59.49 +import java.util.HashMap; 59.50 +import java.util.HashSet; 59.51 +import java.util.Iterator; 59.52 +import java.util.List; 59.53 +import java.util.Map; 59.54 +import java.util.Set; 59.55 +import javax.swing.DefaultComboBoxModel; 59.56 +import javax.swing.JComboBox; 59.57 +import javax.swing.JComponent; 59.58 +import javax.swing.JFrame; 59.59 +import javax.swing.JLabel; 59.60 +import javax.swing.JPanel; 59.61 +import javax.swing.JScrollPane; 59.62 +import javax.swing.JTextArea; 59.63 +import javax.swing.JTextField; 59.64 +import javax.swing.SwingUtilities; 59.65 +import javax.swing.event.CaretEvent; 59.66 +import javax.swing.event.CaretListener; 59.67 +import javax.swing.text.BadLocationException; 59.68 +import javax.swing.text.DefaultHighlighter; 59.69 +import javax.swing.text.Highlighter; 59.70 +import javax.tools.Diagnostic; 59.71 +import javax.tools.DiagnosticListener; 59.72 +import javax.tools.JavaFileObject; 59.73 +import javax.tools.StandardJavaFileManager; 59.74 + 59.75 +import com.sun.source.tree.CompilationUnitTree; 59.76 +import com.sun.source.util.JavacTask; 59.77 +import com.sun.tools.javac.api.JavacTool; 59.78 +import com.sun.tools.javac.code.Flags; 59.79 +import com.sun.tools.javac.tree.JCTree; 59.80 +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 59.81 +import com.sun.tools.javac.tree.JCTree.JCNewClass; 59.82 +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 59.83 +import com.sun.tools.javac.tree.TreeInfo; 59.84 +import com.sun.tools.javac.tree.TreeScanner; 59.85 + 59.86 +import static com.sun.tools.javac.util.Position.NOPOS; 59.87 + 59.88 +/** 59.89 + * Utility and test program to check validity of tree positions for tree nodes. 59.90 + * The program can be run standalone, or as a jtreg test. In standalone mode, 59.91 + * errors can be displayed in a gui viewer. For info on command line args, 59.92 + * run program with no args. 59.93 + * 59.94 + * <p> 59.95 + * jtreg: Note that by using the -r switch in the test description below, this test 59.96 + * will process all java files in the langtools/test directory, thus implicitly 59.97 + * covering any new language features that may be tested in this test suite. 59.98 + */ 59.99 + 59.100 +/* 59.101 + * @test 59.102 + * @bug 6919889 59.103 + * @summary assorted position errors in compiler syntax trees 59.104 + * @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE . 59.105 + */ 59.106 +public class TreePosTest { 59.107 + /** 59.108 + * Main entry point. 59.109 + * If test.src is set, program runs in jtreg mode, and will throw an Error 59.110 + * if any errors arise, otherwise System.exit will be used, unless the gui 59.111 + * viewer is being used. In jtreg mode, the default base directory for file 59.112 + * args is the value of ${test.src}. In jtreg mode, the -r option can be 59.113 + * given to change the default base directory to the root test directory. 59.114 + */ 59.115 + public static void main(String... args) { 59.116 + String testSrc = System.getProperty("test.src"); 59.117 + File baseDir = (testSrc == null) ? null : new File(testSrc); 59.118 + boolean ok = new TreePosTest().run(baseDir, args); 59.119 + if (!ok) { 59.120 + if (testSrc != null) // jtreg mode 59.121 + throw new Error("failed"); 59.122 + else 59.123 + System.exit(1); 59.124 + } 59.125 + } 59.126 + 59.127 + /** 59.128 + * Run the program. A base directory can be provided for file arguments. 59.129 + * In jtreg mode, the -r option can be given to change the default base 59.130 + * directory to the test root directory. For other options, see usage(). 59.131 + * @param baseDir base directory for any file arguments. 59.132 + * @param args command line args 59.133 + * @return true if successful or in gui mode 59.134 + */ 59.135 + boolean run(File baseDir, String... args) { 59.136 + if (args.length == 0) { 59.137 + usage(System.out); 59.138 + return true; 59.139 + } 59.140 + 59.141 + List<File> files = new ArrayList<File>(); 59.142 + for (int i = 0; i < args.length; i++) { 59.143 + String arg = args[i]; 59.144 + if (arg.equals("-encoding") && i + 1 < args.length) 59.145 + encoding = args[++i]; 59.146 + else if (arg.equals("-gui")) 59.147 + gui = true; 59.148 + else if (arg.equals("-q")) 59.149 + quiet = true; 59.150 + else if (arg.equals("-v")) 59.151 + verbose = true; 59.152 + else if (arg.equals("-t") && i + 1 < args.length) 59.153 + tags.add(args[++i]); 59.154 + else if (arg.equals("-ef") && i + 1 < args.length) 59.155 + excludeFiles.add(new File(baseDir, args[++i])); 59.156 + else if (arg.equals("-et") && i + 1 < args.length) 59.157 + excludeTags.add(args[++i]); 59.158 + else if (arg.equals("-r")) { 59.159 + if (excludeFiles.size() > 0) 59.160 + throw new Error("-r must be used before -ef"); 59.161 + File d = baseDir; 59.162 + while (!new File(d, "TEST.ROOT").exists()) { 59.163 + d = d.getParentFile(); 59.164 + if (d == null) 59.165 + throw new Error("cannot find TEST.ROOT"); 59.166 + } 59.167 + baseDir = d; 59.168 + } 59.169 + else if (arg.startsWith("-")) 59.170 + throw new Error("unknown option: " + arg); 59.171 + else { 59.172 + while (i < args.length) 59.173 + files.add(new File(baseDir, args[i++])); 59.174 + } 59.175 + } 59.176 + 59.177 + for (File file: files) { 59.178 + if (file.exists()) 59.179 + test(file); 59.180 + else 59.181 + error("File not found: " + file); 59.182 + } 59.183 + 59.184 + if (fileCount != 1) 59.185 + System.err.println(fileCount + " files read"); 59.186 + if (errors > 0) 59.187 + System.err.println(errors + " errors"); 59.188 + 59.189 + return (gui || errors == 0); 59.190 + } 59.191 + 59.192 + /** 59.193 + * Print command line help. 59.194 + * @param out output stream 59.195 + */ 59.196 + void usage(PrintStream out) { 59.197 + out.println("Usage:"); 59.198 + out.println(" java TreePosTest options... files..."); 59.199 + out.println(""); 59.200 + out.println("where options include:"); 59.201 + out.println("-gui Display returns in a GUI viewer"); 59.202 + out.println("-q Quiet: don't report on inapplicable files"); 59.203 + out.println("-v Verbose: report on files as they are being read"); 59.204 + out.println("-t tag Limit checks to tree nodes with this tag"); 59.205 + out.println(" Can be repeated if desired"); 59.206 + out.println("-ef file Exclude file or directory"); 59.207 + out.println("-et tag Exclude tree nodes with given tag name"); 59.208 + out.println(""); 59.209 + out.println("files may be directories or files"); 59.210 + out.println("directories will be scanned recursively"); 59.211 + out.println("non java files, or java files which cannot be parsed, will be ignored"); 59.212 + out.println(""); 59.213 + } 59.214 + 59.215 + /** 59.216 + * Test a file. If the file is a directory, it will be recursively scanned 59.217 + * for java files. 59.218 + * @param file the file or directory to test 59.219 + */ 59.220 + void test(File file) { 59.221 + if (excludeFiles.contains(file)) { 59.222 + if (!quiet) 59.223 + error("File " + file + " excluded"); 59.224 + return; 59.225 + } 59.226 + 59.227 + if (file.isDirectory()) { 59.228 + for (File f: file.listFiles()) { 59.229 + test(f); 59.230 + } 59.231 + return; 59.232 + } 59.233 + 59.234 + if (file.isFile() && file.getName().endsWith(".java")) { 59.235 + try { 59.236 + if (verbose) 59.237 + System.err.println(file); 59.238 + fileCount++; 59.239 + PosTester p = new PosTester(); 59.240 + p.test(read(file)); 59.241 + } catch (ParseException e) { 59.242 + if (!quiet) { 59.243 + error("Error parsing " + file + "\n" + e.getMessage()); 59.244 + } 59.245 + } catch (IOException e) { 59.246 + error("Error reading " + file + ": " + e); 59.247 + } 59.248 + return; 59.249 + } 59.250 + 59.251 + if (!quiet) 59.252 + error("File " + file + " ignored"); 59.253 + } 59.254 + 59.255 + /** 59.256 + * Read a file. 59.257 + * @param file the file to be read 59.258 + * @return the tree for the content of the file 59.259 + * @throws IOException if any IO errors occur 59.260 + * @throws TreePosTest.ParseException if any errors occur while parsing the file 59.261 + */ 59.262 + JCCompilationUnit read(File file) throws IOException, ParseException { 59.263 + StringWriter sw = new StringWriter(); 59.264 + PrintWriter pw = new PrintWriter(sw); 59.265 + Reporter r = new Reporter(pw); 59.266 + JavacTool tool = JavacTool.create(); 59.267 + Charset cs = (encoding == null ? null : Charset.forName(encoding)); 59.268 + StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); 59.269 + Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file); 59.270 + JavacTask task = tool.getTask(pw, fm, r, Collections.<String>emptyList(), null, files); 59.271 + Iterable<? extends CompilationUnitTree> trees = task.parse(); 59.272 + pw.flush(); 59.273 + if (r.errors > 0) 59.274 + throw new ParseException(sw.toString()); 59.275 + Iterator<? extends CompilationUnitTree> iter = trees.iterator(); 59.276 + if (!iter.hasNext()) 59.277 + throw new Error("no trees found"); 59.278 + JCCompilationUnit t = (JCCompilationUnit) iter.next(); 59.279 + if (iter.hasNext()) 59.280 + throw new Error("too many trees found"); 59.281 + return t; 59.282 + } 59.283 + 59.284 + /** 59.285 + * Report an error. When the program is complete, the program will either 59.286 + * exit or throw an Error if any errors have been reported. 59.287 + * @param msg the error message 59.288 + */ 59.289 + void error(String msg) { 59.290 + System.err.println(msg); 59.291 + errors++; 59.292 + } 59.293 + 59.294 + /** Number of files that have been analyzed. */ 59.295 + int fileCount; 59.296 + /** Number of errors reported. */ 59.297 + int errors; 59.298 + /** Flag: don't report irrelevant files. */ 59.299 + boolean quiet; 59.300 + /** Flag: report files as they are processed. */ 59.301 + boolean verbose; 59.302 + /** Flag: show errors in GUI viewer. */ 59.303 + boolean gui; 59.304 + /** Option: encoding for test files. */ 59.305 + String encoding; 59.306 + /** The GUI viewer for errors. */ 59.307 + Viewer viewer; 59.308 + /** The set of tags for tree nodes to be analyzed; if empty, all tree nodes 59.309 + * are analyzed. */ 59.310 + Set<String> tags = new HashSet<String>(); 59.311 + /** Set of files and directories to be excluded from analysis. */ 59.312 + Set<File> excludeFiles = new HashSet<File>(); 59.313 + /** Set of tag names to be excluded from analysis. */ 59.314 + Set<String> excludeTags = new HashSet<String>(); 59.315 + /** Table of printable names for tree tag values. */ 59.316 + TagNames tagNames = new TagNames(); 59.317 + 59.318 + /** 59.319 + * Main class for testing assertions concerning tree positions for tree nodes. 59.320 + */ 59.321 + private class PosTester extends TreeScanner { 59.322 + void test(JCCompilationUnit tree) { 59.323 + sourcefile = tree.sourcefile; 59.324 + endPosTable = tree.endPositions; 59.325 + encl = new Info(); 59.326 + tree.accept(this); 59.327 + } 59.328 + 59.329 + @Override 59.330 + public void scan(JCTree tree) { 59.331 + if (tree == null) 59.332 + return; 59.333 + 59.334 + Info self = new Info(tree, endPosTable); 59.335 + if (check(encl, self)) { 59.336 + // Modifiers nodes are present throughout the tree even where 59.337 + // there is no corresponding source text. 59.338 + // Redundant semicolons in a class definition can cause empty 59.339 + // initializer blocks with no positions. 59.340 + if ((self.tag == JCTree.MODIFIERS || self.tag == JCTree.BLOCK) 59.341 + && self.pos == NOPOS) { 59.342 + // If pos is NOPOS, so should be the start and end positions 59.343 + check("start == NOPOS", encl, self, self.start == NOPOS); 59.344 + check("end == NOPOS", encl, self, self.end == NOPOS); 59.345 + } else { 59.346 + // For this node, start , pos, and endpos should be all defined 59.347 + check("start != NOPOS", encl, self, self.start != NOPOS); 59.348 + check("pos != NOPOS", encl, self, self.pos != NOPOS); 59.349 + check("end != NOPOS", encl, self, self.end != NOPOS); 59.350 + // The following should normally be ordered 59.351 + // encl.start <= start <= pos <= end <= encl.end 59.352 + // In addition, the position of the enclosing node should be 59.353 + // within this node. 59.354 + // The primary exceptions are for array type nodes, because of the 59.355 + // need to support legacy syntax: 59.356 + // e.g. int a[]; int[] b[]; int f()[] { return null; } 59.357 + // and because of inconsistent nesting of left and right of 59.358 + // array declarations: 59.359 + // e.g. int[][] a = new int[2][]; 59.360 + check("encl.start <= start", encl, self, encl.start <= self.start); 59.361 + check("start <= pos", encl, self, self.start <= self.pos); 59.362 + if (!(self.tag == JCTree.TYPEARRAY 59.363 + && (encl.tag == JCTree.VARDEF || encl.tag == JCTree.TYPEARRAY))) { 59.364 + check("encl.pos <= start || end <= encl.pos", 59.365 + encl, self, encl.pos <= self.start || self.end <= encl.pos); 59.366 + } 59.367 + check("pos <= end", encl, self, self.pos <= self.end); 59.368 + if (!(self.tag == JCTree.TYPEARRAY && encl.tag == JCTree.TYPEARRAY)) { 59.369 + check("end <= encl.end", encl, self, self.end <= encl.end); 59.370 + } 59.371 + } 59.372 + } 59.373 + 59.374 + Info prevEncl = encl; 59.375 + encl = self; 59.376 + tree.accept(this); 59.377 + encl = prevEncl; 59.378 + } 59.379 + 59.380 + @Override 59.381 + public void visitVarDef(JCVariableDecl tree) { 59.382 + // enum member declarations are desugared in the parser and have 59.383 + // ill-defined semantics for tree positions, so for now, we 59.384 + // skip the synthesized bits and just check parts which came from 59.385 + // the original source text 59.386 + if ((tree.mods.flags & Flags.ENUM) != 0) { 59.387 + scan(tree.mods); 59.388 + if (tree.init != null) { 59.389 + if (tree.init.getTag() == JCTree.NEWCLASS) { 59.390 + JCNewClass init = (JCNewClass) tree.init; 59.391 + if (init.args != null && init.args.nonEmpty()) { 59.392 + scan(init.args); 59.393 + } 59.394 + if (init.def != null && init.def.defs != null) { 59.395 + scan(init.def.defs); 59.396 + } 59.397 + } 59.398 + } 59.399 + } else 59.400 + super.visitVarDef(tree); 59.401 + } 59.402 + 59.403 + boolean check(Info encl, Info self) { 59.404 + if (excludeTags.size() > 0) { 59.405 + if (encl != null && excludeTags.contains(tagNames.get(encl.tag)) 59.406 + || excludeTags.contains(tagNames.get(self.tag))) 59.407 + return false; 59.408 + } 59.409 + return tags.size() == 0 || tags.contains(tagNames.get(self.tag)); 59.410 + } 59.411 + 59.412 + void check(String label, Info encl, Info self, boolean ok) { 59.413 + if (!ok) { 59.414 + if (gui) { 59.415 + if (viewer == null) 59.416 + viewer = new Viewer(); 59.417 + viewer.addEntry(sourcefile, label, encl, self); 59.418 + } 59.419 + 59.420 + String s = self.tree.toString(); 59.421 + String msg = sourcefile.getName() + ": " + label + ": " + 59.422 + "encl:" + encl + " this:" + self + "\n" + 59.423 + s.substring(0, Math.min(80, s.length())).replaceAll("[\r\n]+", " "); 59.424 + error(msg); 59.425 + } 59.426 + } 59.427 + 59.428 + JavaFileObject sourcefile; 59.429 + Map<JCTree, Integer> endPosTable; 59.430 + Info encl; 59.431 + 59.432 + } 59.433 + 59.434 + /** 59.435 + * Utility class providing easy access to position and other info for a tree node. 59.436 + */ 59.437 + private class Info { 59.438 + Info() { 59.439 + tree = null; 59.440 + tag = JCTree.ERRONEOUS; 59.441 + start = 0; 59.442 + pos = 0; 59.443 + end = Integer.MAX_VALUE; 59.444 + } 59.445 + 59.446 + Info(JCTree tree, Map<JCTree, Integer> endPosTable) { 59.447 + this.tree = tree; 59.448 + tag = tree.getTag(); 59.449 + start = TreeInfo.getStartPos(tree); 59.450 + pos = tree.pos; 59.451 + end = TreeInfo.getEndPos(tree, endPosTable); 59.452 + } 59.453 + 59.454 + @Override 59.455 + public String toString() { 59.456 + return tagNames.get(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]"; 59.457 + } 59.458 + 59.459 + final JCTree tree; 59.460 + final int tag; 59.461 + final int start; 59.462 + final int pos; 59.463 + final int end; 59.464 + } 59.465 + 59.466 + /** 59.467 + * Names for tree tags. 59.468 + * javac does not provide an API to convert tag values to strings, so this class uses 59.469 + * reflection to determine names of public static final int values in JCTree. 59.470 + */ 59.471 + private static class TagNames { 59.472 + String get(int tag) { 59.473 + if (map == null) { 59.474 + map = new HashMap<Integer, String>(); 59.475 + Class c = JCTree.class; 59.476 + for (Field f : c.getDeclaredFields()) { 59.477 + if (f.getType().equals(int.class)) { 59.478 + int mods = f.getModifiers(); 59.479 + if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { 59.480 + try { 59.481 + map.put(f.getInt(null), f.getName()); 59.482 + } catch (IllegalAccessException e) { 59.483 + } 59.484 + } 59.485 + } 59.486 + } 59.487 + } 59.488 + String name = map.get(tag); 59.489 + return (name == null) ? "??" : name; 59.490 + } 59.491 + 59.492 + private Map<Integer, String> map; 59.493 + } 59.494 + 59.495 + /** 59.496 + * Thrown when errors are found parsing a java file. 59.497 + */ 59.498 + private static class ParseException extends Exception { 59.499 + ParseException(String msg) { 59.500 + super(msg); 59.501 + } 59.502 + } 59.503 + 59.504 + /** 59.505 + * DiagnosticListener to report diagnostics and count any errors that occur. 59.506 + */ 59.507 + private static class Reporter implements DiagnosticListener<JavaFileObject> { 59.508 + Reporter(PrintWriter out) { 59.509 + this.out = out; 59.510 + } 59.511 + 59.512 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 59.513 + out.println(diagnostic); 59.514 + switch (diagnostic.getKind()) { 59.515 + case ERROR: 59.516 + errors++; 59.517 + } 59.518 + } 59.519 + int errors; 59.520 + PrintWriter out; 59.521 + } 59.522 + 59.523 + /** 59.524 + * GUI viewer for issues found by TreePosTester. The viewer provides a drop 59.525 + * down list for selecting error conditions, a header area providing details 59.526 + * about an error, and a text area with the ranges of text highlighted as 59.527 + * appropriate. 59.528 + */ 59.529 + private class Viewer extends JFrame { 59.530 + /** 59.531 + * Create a viewer. 59.532 + */ 59.533 + Viewer() { 59.534 + initGUI(); 59.535 + } 59.536 + 59.537 + /** 59.538 + * Add another entry to the list of errors. 59.539 + * @param file The file containing the error 59.540 + * @param check The condition that was being tested, and which failed 59.541 + * @param encl the enclosing tree node 59.542 + * @param self the tree node containing the error 59.543 + */ 59.544 + void addEntry(JavaFileObject file, String check, Info encl, Info self) { 59.545 + Entry e = new Entry(file, check, encl, self); 59.546 + DefaultComboBoxModel m = (DefaultComboBoxModel) entries.getModel(); 59.547 + m.addElement(e); 59.548 + if (m.getSize() == 1) 59.549 + entries.setSelectedItem(e); 59.550 + } 59.551 + 59.552 + /** 59.553 + * Initialize the GUI window. 59.554 + */ 59.555 + private void initGUI() { 59.556 + JPanel head = new JPanel(new GridBagLayout()); 59.557 + GridBagConstraints lc = new GridBagConstraints(); 59.558 + GridBagConstraints fc = new GridBagConstraints(); 59.559 + fc.anchor = GridBagConstraints.WEST; 59.560 + fc.fill = GridBagConstraints.HORIZONTAL; 59.561 + fc.gridwidth = GridBagConstraints.REMAINDER; 59.562 + 59.563 + entries = new JComboBox(); 59.564 + entries.addActionListener(new ActionListener() { 59.565 + public void actionPerformed(ActionEvent e) { 59.566 + showEntry((Entry) entries.getSelectedItem()); 59.567 + } 59.568 + }); 59.569 + fc.insets.bottom = 10; 59.570 + head.add(entries, fc); 59.571 + fc.insets.bottom = 0; 59.572 + head.add(new JLabel("check:"), lc); 59.573 + head.add(checkField = createTextField(80), fc); 59.574 + fc.fill = GridBagConstraints.NONE; 59.575 + head.add(setBackground(new JLabel("encl:"), enclColor), lc); 59.576 + head.add(enclPanel = new InfoPanel(), fc); 59.577 + head.add(setBackground(new JLabel("self:"), selfColor), lc); 59.578 + head.add(selfPanel = new InfoPanel(), fc); 59.579 + add(head, BorderLayout.NORTH); 59.580 + 59.581 + body = new JTextArea(); 59.582 + body.setFont(Font.decode(Font.MONOSPACED)); 59.583 + body.addCaretListener(new CaretListener() { 59.584 + public void caretUpdate(CaretEvent e) { 59.585 + int dot = e.getDot(); 59.586 + int mark = e.getMark(); 59.587 + if (dot == mark) 59.588 + statusText.setText("dot: " + dot); 59.589 + else 59.590 + statusText.setText("dot: " + dot + ", mark:" + mark); 59.591 + } 59.592 + }); 59.593 + JScrollPane p = new JScrollPane(body, 59.594 + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 59.595 + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 59.596 + p.setPreferredSize(new Dimension(640, 480)); 59.597 + add(p, BorderLayout.CENTER); 59.598 + 59.599 + statusText = createTextField(80); 59.600 + add(statusText, BorderLayout.SOUTH); 59.601 + 59.602 + pack(); 59.603 + setLocationRelativeTo(null); // centered on screen 59.604 + setVisible(true); 59.605 + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 59.606 + } 59.607 + 59.608 + /** Show an entry that has been selected. */ 59.609 + private void showEntry(Entry e) { 59.610 + try { 59.611 + // update simple fields 59.612 + setTitle(e.file.getName()); 59.613 + checkField.setText(e.check); 59.614 + enclPanel.setInfo(e.encl); 59.615 + selfPanel.setInfo(e.self); 59.616 + // show file text with highlights 59.617 + body.setText(e.file.getCharContent(true).toString()); 59.618 + Highlighter highlighter = body.getHighlighter(); 59.619 + highlighter.removeAllHighlights(); 59.620 + addHighlight(highlighter, e.encl, enclColor); 59.621 + addHighlight(highlighter, e.self, selfColor); 59.622 + scroll(body, getMinPos(enclPanel.info, selfPanel.info)); 59.623 + } catch (IOException ex) { 59.624 + body.setText("Cannot read " + e.file.getName() + ": " + e); 59.625 + } 59.626 + } 59.627 + 59.628 + /** Create a test field. */ 59.629 + private JTextField createTextField(int width) { 59.630 + JTextField f = new JTextField(width); 59.631 + f.setEditable(false); 59.632 + f.setBorder(null); 59.633 + return f; 59.634 + } 59.635 + 59.636 + /** Add a highlighted region based on the positions in an Info object. */ 59.637 + private void addHighlight(Highlighter h, Info info, Color c) { 59.638 + int start = info.start; 59.639 + int end = info.end; 59.640 + if (start == -1 && end == -1) 59.641 + return; 59.642 + if (start == -1) 59.643 + start = end; 59.644 + if (end == -1) 59.645 + end = start; 59.646 + try { 59.647 + h.addHighlight(info.start, info.end, 59.648 + new DefaultHighlighter.DefaultHighlightPainter(c)); 59.649 + if (info.pos != -1) { 59.650 + Color c2 = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(.4f * 255)); // 40% 59.651 + h.addHighlight(info.pos, info.pos + 1, 59.652 + new DefaultHighlighter.DefaultHighlightPainter(c2)); 59.653 + } 59.654 + } catch (BadLocationException e) { 59.655 + e.printStackTrace(); 59.656 + } 59.657 + } 59.658 + 59.659 + /** Get the minimum valid position in a set of info objects. */ 59.660 + private int getMinPos(Info... values) { 59.661 + int i = Integer.MAX_VALUE; 59.662 + for (Info info: values) { 59.663 + if (info.start >= 0) i = Math.min(i, info.start); 59.664 + if (info.pos >= 0) i = Math.min(i, info.pos); 59.665 + if (info.end >= 0) i = Math.min(i, info.end); 59.666 + } 59.667 + return (i == Integer.MAX_VALUE) ? 0 : i; 59.668 + } 59.669 + 59.670 + /** Set the background on a component. */ 59.671 + private JComponent setBackground(JComponent comp, Color c) { 59.672 + comp.setOpaque(true); 59.673 + comp.setBackground(c); 59.674 + return comp; 59.675 + } 59.676 + 59.677 + /** Scroll a text area to display a given position near the middle of the visible area. */ 59.678 + private void scroll(final JTextArea t, final int pos) { 59.679 + // Using invokeLater appears to give text a chance to sort itself out 59.680 + // before the scroll happens; otherwise scrollRectToVisible doesn't work. 59.681 + // Maybe there's a better way to sync with the text... 59.682 + EventQueue.invokeLater(new Runnable() { 59.683 + public void run() { 59.684 + try { 59.685 + Rectangle r = t.modelToView(pos); 59.686 + JScrollPane p = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, t); 59.687 + r.y = Math.max(0, r.y - p.getHeight() * 2 / 5); 59.688 + r.height += p.getHeight() * 4 / 5; 59.689 + t.scrollRectToVisible(r); 59.690 + } catch (BadLocationException ignore) { 59.691 + } 59.692 + } 59.693 + }); 59.694 + } 59.695 + 59.696 + private JComboBox entries; 59.697 + private JTextField checkField; 59.698 + private InfoPanel enclPanel; 59.699 + private InfoPanel selfPanel; 59.700 + private JTextArea body; 59.701 + private JTextField statusText; 59.702 + 59.703 + private Color selfColor = new Color(0.f, 1.f, 0.f, 0.2f); // 20% green 59.704 + private Color enclColor = new Color(1.f, 0.f, 0.f, 0.2f); // 20% red 59.705 + 59.706 + /** Panel to display an Info object. */ 59.707 + private class InfoPanel extends JPanel { 59.708 + InfoPanel() { 59.709 + add(tagName = createTextField(20)); 59.710 + add(new JLabel("start:")); 59.711 + add(addListener(start = createTextField(6))); 59.712 + add(new JLabel("pos:")); 59.713 + add(addListener(pos = createTextField(6))); 59.714 + add(new JLabel("end:")); 59.715 + add(addListener(end = createTextField(6))); 59.716 + } 59.717 + 59.718 + void setInfo(Info info) { 59.719 + this.info = info; 59.720 + tagName.setText(tagNames.get(info.tag)); 59.721 + start.setText(String.valueOf(info.start)); 59.722 + pos.setText(String.valueOf(info.pos)); 59.723 + end.setText(String.valueOf(info.end)); 59.724 + } 59.725 + 59.726 + JTextField addListener(final JTextField f) { 59.727 + f.addMouseListener(new MouseAdapter() { 59.728 + @Override 59.729 + public void mouseClicked(MouseEvent e) { 59.730 + body.setCaretPosition(Integer.valueOf(f.getText())); 59.731 + body.getCaret().setVisible(true); 59.732 + } 59.733 + }); 59.734 + return f; 59.735 + } 59.736 + 59.737 + Info info; 59.738 + JTextField tagName; 59.739 + JTextField start; 59.740 + JTextField pos; 59.741 + JTextField end; 59.742 + } 59.743 + 59.744 + /** Object to record information about an error to be displayed. */ 59.745 + private class Entry { 59.746 + Entry(JavaFileObject file, String check, Info encl, Info self) { 59.747 + this.file = file; 59.748 + this.check = check; 59.749 + this.encl = encl; 59.750 + this.self= self; 59.751 + } 59.752 + 59.753 + @Override 59.754 + public String toString() { 59.755 + return file.getName() + " " + check + " " + getMinPos(encl, self); 59.756 + } 59.757 + 59.758 + final JavaFileObject file; 59.759 + final String check; 59.760 + final Info encl; 59.761 + final Info self; 59.762 + } 59.763 + } 59.764 +} 59.765 +
60.1 --- a/test/tools/javac/treepostests/TreePosTest.java Thu Mar 04 13:50:33 2010 -0800 60.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 60.3 @@ -1,762 +0,0 @@ 60.4 -/* 60.5 - * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 60.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 60.7 - * 60.8 - * This code is free software; you can redistribute it and/or modify it 60.9 - * under the terms of the GNU General Public License version 2 only, as 60.10 - * published by the Free Software Foundation. 60.11 - * 60.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 60.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 60.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 60.15 - * version 2 for more details (a copy is included in the LICENSE file that 60.16 - * accompanied this code). 60.17 - * 60.18 - * You should have received a copy of the GNU General Public License version 60.19 - * 2 along with this work; if not, write to the Free Software Foundation, 60.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 60.21 - * 60.22 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 60.23 - * CA 95054 USA or visit www.sun.com if you need additional information or 60.24 - * have any questions. 60.25 - */ 60.26 - 60.27 -import java.awt.BorderLayout; 60.28 -import java.awt.Color; 60.29 -import java.awt.Dimension; 60.30 -import java.awt.EventQueue; 60.31 -import java.awt.Font; 60.32 -import java.awt.GridBagConstraints; 60.33 -import java.awt.GridBagLayout; 60.34 -import java.awt.Rectangle; 60.35 -import java.awt.event.ActionEvent; 60.36 -import java.awt.event.ActionListener; 60.37 -import java.awt.event.MouseAdapter; 60.38 -import java.awt.event.MouseEvent; 60.39 -import java.io.File; 60.40 -import java.io.IOException; 60.41 -import java.io.PrintStream; 60.42 -import java.io.PrintWriter; 60.43 -import java.io.StringWriter; 60.44 -import java.lang.reflect.Field; 60.45 -import java.lang.reflect.Modifier; 60.46 -import java.nio.charset.Charset; 60.47 -import java.util.ArrayList; 60.48 -import java.util.Collections; 60.49 -import java.util.HashMap; 60.50 -import java.util.HashSet; 60.51 -import java.util.Iterator; 60.52 -import java.util.List; 60.53 -import java.util.Map; 60.54 -import java.util.Set; 60.55 -import javax.swing.DefaultComboBoxModel; 60.56 -import javax.swing.JComboBox; 60.57 -import javax.swing.JComponent; 60.58 -import javax.swing.JFrame; 60.59 -import javax.swing.JLabel; 60.60 -import javax.swing.JPanel; 60.61 -import javax.swing.JScrollPane; 60.62 -import javax.swing.JTextArea; 60.63 -import javax.swing.JTextField; 60.64 -import javax.swing.SwingUtilities; 60.65 -import javax.swing.event.CaretEvent; 60.66 -import javax.swing.event.CaretListener; 60.67 -import javax.swing.text.BadLocationException; 60.68 -import javax.swing.text.DefaultHighlighter; 60.69 -import javax.swing.text.Highlighter; 60.70 -import javax.tools.Diagnostic; 60.71 -import javax.tools.DiagnosticListener; 60.72 -import javax.tools.JavaFileObject; 60.73 -import javax.tools.StandardJavaFileManager; 60.74 - 60.75 -import com.sun.source.tree.CompilationUnitTree; 60.76 -import com.sun.source.util.JavacTask; 60.77 -import com.sun.tools.javac.api.JavacTool; 60.78 -import com.sun.tools.javac.code.Flags; 60.79 -import com.sun.tools.javac.tree.JCTree; 60.80 -import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 60.81 -import com.sun.tools.javac.tree.JCTree.JCNewClass; 60.82 -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 60.83 -import com.sun.tools.javac.tree.TreeInfo; 60.84 -import com.sun.tools.javac.tree.TreeScanner; 60.85 - 60.86 -import static com.sun.tools.javac.util.Position.NOPOS; 60.87 - 60.88 -/** 60.89 - * Utility and test program to check validity of tree positions for tree nodes. 60.90 - * The program can be run standalone, or as a jtreg test. In standalone mode, 60.91 - * errors can be displayed in a gui viewer. For info on command line args, 60.92 - * run program with no args. 60.93 - * 60.94 - * <p> 60.95 - * jtreg: Note that by using the -r switch in the test description below, this test 60.96 - * will process all java files in the langtools/test directory, thus implicitly 60.97 - * covering any new language features that may be tested in this test suite. 60.98 - */ 60.99 - 60.100 -/* 60.101 - * @test 60.102 - * @bug 6919889 60.103 - * @summary assorted position errors in compiler syntax trees 60.104 - * @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE . 60.105 - */ 60.106 -public class TreePosTest { 60.107 - /** 60.108 - * Main entry point. 60.109 - * If test.src is set, program runs in jtreg mode, and will throw an Error 60.110 - * if any errors arise, otherwise System.exit will be used, unless the gui 60.111 - * viewer is being used. In jtreg mode, the default base directory for file 60.112 - * args is the value of ${test.src}. In jtreg mode, the -r option can be 60.113 - * given to change the default base directory to the root test directory. 60.114 - */ 60.115 - public static void main(String... args) { 60.116 - String testSrc = System.getProperty("test.src"); 60.117 - File baseDir = (testSrc == null) ? null : new File(testSrc); 60.118 - boolean ok = new TreePosTest().run(baseDir, args); 60.119 - if (!ok) { 60.120 - if (testSrc != null) // jtreg mode 60.121 - throw new Error("failed"); 60.122 - else 60.123 - System.exit(1); 60.124 - } 60.125 - } 60.126 - 60.127 - /** 60.128 - * Run the program. A base directory can be provided for file arguments. 60.129 - * In jtreg mode, the -r option can be given to change the default base 60.130 - * directory to the test root directory. For other options, see usage(). 60.131 - * @param baseDir base directory for any file arguments. 60.132 - * @param args command line args 60.133 - * @return true if successful or in gui mode 60.134 - */ 60.135 - boolean run(File baseDir, String... args) { 60.136 - if (args.length == 0) { 60.137 - usage(System.out); 60.138 - return true; 60.139 - } 60.140 - 60.141 - List<File> files = new ArrayList<File>(); 60.142 - for (int i = 0; i < args.length; i++) { 60.143 - String arg = args[i]; 60.144 - if (arg.equals("-encoding") && i + 1 < args.length) 60.145 - encoding = args[++i]; 60.146 - else if (arg.equals("-gui")) 60.147 - gui = true; 60.148 - else if (arg.equals("-q")) 60.149 - quiet = true; 60.150 - else if (arg.equals("-v")) 60.151 - verbose = true; 60.152 - else if (arg.equals("-t") && i + 1 < args.length) 60.153 - tags.add(args[++i]); 60.154 - else if (arg.equals("-ef") && i + 1 < args.length) 60.155 - excludeFiles.add(new File(baseDir, args[++i])); 60.156 - else if (arg.equals("-et") && i + 1 < args.length) 60.157 - excludeTags.add(args[++i]); 60.158 - else if (arg.equals("-r")) { 60.159 - if (excludeFiles.size() > 0) 60.160 - throw new Error("-r must be used before -ef"); 60.161 - File d = baseDir; 60.162 - while (!new File(d, "TEST.ROOT").exists()) { 60.163 - d = d.getParentFile(); 60.164 - if (d == null) 60.165 - throw new Error("cannot find TEST.ROOT"); 60.166 - } 60.167 - baseDir = d; 60.168 - } 60.169 - else if (arg.startsWith("-")) 60.170 - throw new Error("unknown option: " + arg); 60.171 - else { 60.172 - while (i < args.length) 60.173 - files.add(new File(baseDir, args[i++])); 60.174 - } 60.175 - } 60.176 - 60.177 - for (File file: files) { 60.178 - if (file.exists()) 60.179 - test(file); 60.180 - else 60.181 - error("File not found: " + file); 60.182 - } 60.183 - 60.184 - if (fileCount != 1) 60.185 - System.err.println(fileCount + " files read"); 60.186 - if (errors > 0) 60.187 - System.err.println(errors + " errors"); 60.188 - 60.189 - return (gui || errors == 0); 60.190 - } 60.191 - 60.192 - /** 60.193 - * Print command line help. 60.194 - * @param out output stream 60.195 - */ 60.196 - void usage(PrintStream out) { 60.197 - out.println("Usage:"); 60.198 - out.println(" java TreePosTest options... files..."); 60.199 - out.println(""); 60.200 - out.println("where options include:"); 60.201 - out.println("-gui Display returns in a GUI viewer"); 60.202 - out.println("-q Quiet: don't report on inapplicable files"); 60.203 - out.println("-v Verbose: report on files as they are being read"); 60.204 - out.println("-t tag Limit checks to tree nodes with this tag"); 60.205 - out.println(" Can be repeated if desired"); 60.206 - out.println("-ef file Exclude file or directory"); 60.207 - out.println("-et tag Exclude tree nodes with given tag name"); 60.208 - out.println(""); 60.209 - out.println("files may be directories or files"); 60.210 - out.println("directories will be scanned recursively"); 60.211 - out.println("non java files, or java files which cannot be parsed, will be ignored"); 60.212 - out.println(""); 60.213 - } 60.214 - 60.215 - /** 60.216 - * Test a file. If the file is a directory, it will be recursively scanned 60.217 - * for java files. 60.218 - * @param file the file or directory to test 60.219 - */ 60.220 - void test(File file) { 60.221 - if (excludeFiles.contains(file)) { 60.222 - if (!quiet) 60.223 - error("File " + file + " excluded"); 60.224 - return; 60.225 - } 60.226 - 60.227 - if (file.isDirectory()) { 60.228 - for (File f: file.listFiles()) { 60.229 - test(f); 60.230 - } 60.231 - return; 60.232 - } 60.233 - 60.234 - if (file.isFile() && file.getName().endsWith(".java")) { 60.235 - try { 60.236 - if (verbose) 60.237 - System.err.println(file); 60.238 - fileCount++; 60.239 - PosTester p = new PosTester(); 60.240 - p.test(read(file)); 60.241 - } catch (ParseException e) { 60.242 - if (!quiet) { 60.243 - error("Error parsing " + file + "\n" + e.getMessage()); 60.244 - } 60.245 - } catch (IOException e) { 60.246 - error("Error reading " + file + ": " + e); 60.247 - } 60.248 - return; 60.249 - } 60.250 - 60.251 - if (!quiet) 60.252 - error("File " + file + " ignored"); 60.253 - } 60.254 - 60.255 - /** 60.256 - * Read a file. 60.257 - * @param file the file to be read 60.258 - * @return the tree for the content of the file 60.259 - * @throws IOException if any IO errors occur 60.260 - * @throws TreePosTest.ParseException if any errors occur while parsing the file 60.261 - */ 60.262 - JCCompilationUnit read(File file) throws IOException, ParseException { 60.263 - StringWriter sw = new StringWriter(); 60.264 - PrintWriter pw = new PrintWriter(sw); 60.265 - Reporter r = new Reporter(pw); 60.266 - JavacTool tool = JavacTool.create(); 60.267 - Charset cs = (encoding == null ? null : Charset.forName(encoding)); 60.268 - StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null); 60.269 - Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file); 60.270 - JavacTask task = tool.getTask(pw, fm, r, Collections.<String>emptyList(), null, files); 60.271 - Iterable<? extends CompilationUnitTree> trees = task.parse(); 60.272 - pw.flush(); 60.273 - if (r.errors > 0) 60.274 - throw new ParseException(sw.toString()); 60.275 - Iterator<? extends CompilationUnitTree> iter = trees.iterator(); 60.276 - if (!iter.hasNext()) 60.277 - throw new Error("no trees found"); 60.278 - JCCompilationUnit t = (JCCompilationUnit) iter.next(); 60.279 - if (iter.hasNext()) 60.280 - throw new Error("too many trees found"); 60.281 - return t; 60.282 - } 60.283 - 60.284 - /** 60.285 - * Report an error. When the program is complete, the program will either 60.286 - * exit or throw an Error if any errors have been reported. 60.287 - * @param msg the error message 60.288 - */ 60.289 - void error(String msg) { 60.290 - System.err.println(msg); 60.291 - errors++; 60.292 - } 60.293 - 60.294 - /** Number of files that have been analyzed. */ 60.295 - int fileCount; 60.296 - /** Number of errors reported. */ 60.297 - int errors; 60.298 - /** Flag: don't report irrelevant files. */ 60.299 - boolean quiet; 60.300 - /** Flag: report files as they are processed. */ 60.301 - boolean verbose; 60.302 - /** Flag: show errors in GUI viewer. */ 60.303 - boolean gui; 60.304 - /** Option: encoding for test files. */ 60.305 - String encoding; 60.306 - /** The GUI viewer for errors. */ 60.307 - Viewer viewer; 60.308 - /** The set of tags for tree nodes to be analyzed; if empty, all tree nodes 60.309 - * are analyzed. */ 60.310 - Set<String> tags = new HashSet<String>(); 60.311 - /** Set of files and directories to be excluded from analysis. */ 60.312 - Set<File> excludeFiles = new HashSet<File>(); 60.313 - /** Set of tag names to be excluded from analysis. */ 60.314 - Set<String> excludeTags = new HashSet<String>(); 60.315 - /** Table of printable names for tree tag values. */ 60.316 - TagNames tagNames = new TagNames(); 60.317 - 60.318 - /** 60.319 - * Main class for testing assertions concerning tree positions for tree nodes. 60.320 - */ 60.321 - private class PosTester extends TreeScanner { 60.322 - void test(JCCompilationUnit tree) { 60.323 - sourcefile = tree.sourcefile; 60.324 - endPosTable = tree.endPositions; 60.325 - encl = new Info(); 60.326 - tree.accept(this); 60.327 - } 60.328 - 60.329 - @Override 60.330 - public void scan(JCTree tree) { 60.331 - if (tree == null) 60.332 - return; 60.333 - 60.334 - Info self = new Info(tree, endPosTable); 60.335 - if (check(encl, self)) { 60.336 - // Modifiers nodes are present throughout the tree even where 60.337 - // there is no corresponding source text. 60.338 - // Redundant semicolons in a class definition can cause empty 60.339 - // initializer blocks with no positions. 60.340 - if ((self.tag == JCTree.MODIFIERS || self.tag == JCTree.BLOCK) 60.341 - && self.pos == NOPOS) { 60.342 - // If pos is NOPOS, so should be the start and end positions 60.343 - check("start == NOPOS", encl, self, self.start == NOPOS); 60.344 - check("end == NOPOS", encl, self, self.end == NOPOS); 60.345 - } else { 60.346 - // For this node, start , pos, and endpos should be all defined 60.347 - check("start != NOPOS", encl, self, self.start != NOPOS); 60.348 - check("pos != NOPOS", encl, self, self.pos != NOPOS); 60.349 - check("end != NOPOS", encl, self, self.end != NOPOS); 60.350 - // The following should normally be ordered 60.351 - // encl.start <= start <= pos <= end <= encl.end 60.352 - // In addition, the position of the enclosing node should be 60.353 - // within this node. 60.354 - // The primary exceptions are for array type nodes, because of the 60.355 - // need to support legacy syntax: 60.356 - // e.g. int a[]; int[] b[]; int f()[] { return null; } 60.357 - // and because of inconsistent nesting of left and right of 60.358 - // array declarations: 60.359 - // e.g. int[][] a = new int[2][]; 60.360 - check("encl.start <= start", encl, self, encl.start <= self.start); 60.361 - check("start <= pos", encl, self, self.start <= self.pos); 60.362 - if (!(self.tag == JCTree.TYPEARRAY 60.363 - && (encl.tag == JCTree.VARDEF || encl.tag == JCTree.TYPEARRAY))) { 60.364 - check("encl.pos <= start || end <= encl.pos", 60.365 - encl, self, encl.pos <= self.start || self.end <= encl.pos); 60.366 - } 60.367 - check("pos <= end", encl, self, self.pos <= self.end); 60.368 - if (!(self.tag == JCTree.TYPEARRAY && encl.tag == JCTree.TYPEARRAY)) { 60.369 - check("end <= encl.end", encl, self, self.end <= encl.end); 60.370 - } 60.371 - } 60.372 - } 60.373 - 60.374 - Info prevEncl = encl; 60.375 - encl = self; 60.376 - tree.accept(this); 60.377 - encl = prevEncl; 60.378 - } 60.379 - 60.380 - @Override 60.381 - public void visitVarDef(JCVariableDecl tree) { 60.382 - // enum member declarations are desugared in the parser and have 60.383 - // ill-defined semantics for tree positions, so for now, we 60.384 - // skip the synthesized bits and just check parts which came from 60.385 - // the original source text 60.386 - if ((tree.mods.flags & Flags.ENUM) != 0) { 60.387 - scan(tree.mods); 60.388 - if (tree.init != null) { 60.389 - if (tree.init.getTag() == JCTree.NEWCLASS) { 60.390 - JCNewClass init = (JCNewClass) tree.init; 60.391 - if (init.args != null && init.args.nonEmpty()) { 60.392 - scan(init.args); 60.393 - } 60.394 - if (init.def != null && init.def.defs != null) { 60.395 - scan(init.def.defs); 60.396 - } 60.397 - } 60.398 - } 60.399 - } else 60.400 - super.visitVarDef(tree); 60.401 - } 60.402 - 60.403 - boolean check(Info encl, Info self) { 60.404 - if (excludeTags.size() > 0) { 60.405 - if (encl != null && excludeTags.contains(tagNames.get(encl.tag)) 60.406 - || excludeTags.contains(tagNames.get(self.tag))) 60.407 - return false; 60.408 - } 60.409 - return tags.size() == 0 || tags.contains(tagNames.get(self.tag)); 60.410 - } 60.411 - 60.412 - void check(String label, Info encl, Info self, boolean ok) { 60.413 - if (!ok) { 60.414 - if (gui) { 60.415 - if (viewer == null) 60.416 - viewer = new Viewer(); 60.417 - viewer.addEntry(sourcefile, label, encl, self); 60.418 - } 60.419 - 60.420 - String s = self.tree.toString(); 60.421 - String msg = sourcefile.getName() + ": " + label + ": " + 60.422 - "encl:" + encl + " this:" + self + "\n" + 60.423 - s.substring(0, Math.min(80, s.length())).replaceAll("[\r\n]+", " "); 60.424 - error(msg); 60.425 - } 60.426 - } 60.427 - 60.428 - JavaFileObject sourcefile; 60.429 - Map<JCTree, Integer> endPosTable; 60.430 - Info encl; 60.431 - 60.432 - } 60.433 - 60.434 - /** 60.435 - * Utility class providing easy access to position and other info for a tree node. 60.436 - */ 60.437 - private class Info { 60.438 - Info() { 60.439 - tree = null; 60.440 - tag = JCTree.ERRONEOUS; 60.441 - start = 0; 60.442 - pos = 0; 60.443 - end = Integer.MAX_VALUE; 60.444 - } 60.445 - 60.446 - Info(JCTree tree, Map<JCTree, Integer> endPosTable) { 60.447 - this.tree = tree; 60.448 - tag = tree.getTag(); 60.449 - start = TreeInfo.getStartPos(tree); 60.450 - pos = tree.pos; 60.451 - end = TreeInfo.getEndPos(tree, endPosTable); 60.452 - } 60.453 - 60.454 - @Override 60.455 - public String toString() { 60.456 - return tagNames.get(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]"; 60.457 - } 60.458 - 60.459 - final JCTree tree; 60.460 - final int tag; 60.461 - final int start; 60.462 - final int pos; 60.463 - final int end; 60.464 - } 60.465 - 60.466 - /** 60.467 - * Names for tree tags. 60.468 - * javac does not provide an API to convert tag values to strings, so this class uses 60.469 - * reflection to determine names of public static final int values in JCTree. 60.470 - */ 60.471 - private static class TagNames { 60.472 - String get(int tag) { 60.473 - if (map == null) { 60.474 - map = new HashMap<Integer, String>(); 60.475 - Class c = JCTree.class; 60.476 - for (Field f : c.getDeclaredFields()) { 60.477 - if (f.getType().equals(int.class)) { 60.478 - int mods = f.getModifiers(); 60.479 - if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { 60.480 - try { 60.481 - map.put(f.getInt(null), f.getName()); 60.482 - } catch (IllegalAccessException e) { 60.483 - } 60.484 - } 60.485 - } 60.486 - } 60.487 - } 60.488 - String name = map.get(tag); 60.489 - return (name == null) ? "??" : name; 60.490 - } 60.491 - 60.492 - private Map<Integer, String> map; 60.493 - } 60.494 - 60.495 - /** 60.496 - * Thrown when errors are found parsing a java file. 60.497 - */ 60.498 - private static class ParseException extends Exception { 60.499 - ParseException(String msg) { 60.500 - super(msg); 60.501 - } 60.502 - } 60.503 - 60.504 - /** 60.505 - * DiagnosticListener to report diagnostics and count any errors that occur. 60.506 - */ 60.507 - private static class Reporter implements DiagnosticListener<JavaFileObject> { 60.508 - Reporter(PrintWriter out) { 60.509 - this.out = out; 60.510 - } 60.511 - 60.512 - public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 60.513 - out.println(diagnostic); 60.514 - switch (diagnostic.getKind()) { 60.515 - case ERROR: 60.516 - errors++; 60.517 - } 60.518 - } 60.519 - int errors; 60.520 - PrintWriter out; 60.521 - } 60.522 - 60.523 - /** 60.524 - * GUI viewer for issues found by TreePosTester. The viewer provides a drop 60.525 - * down list for selecting error conditions, a header area providing details 60.526 - * about an error, and a text area with the ranges of text highlighted as 60.527 - * appropriate. 60.528 - */ 60.529 - private class Viewer extends JFrame { 60.530 - /** 60.531 - * Create a viewer. 60.532 - */ 60.533 - Viewer() { 60.534 - initGUI(); 60.535 - } 60.536 - 60.537 - /** 60.538 - * Add another entry to the list of errors. 60.539 - * @param file The file containing the error 60.540 - * @param check The condition that was being tested, and which failed 60.541 - * @param encl the enclosing tree node 60.542 - * @param self the tree node containing the error 60.543 - */ 60.544 - void addEntry(JavaFileObject file, String check, Info encl, Info self) { 60.545 - Entry e = new Entry(file, check, encl, self); 60.546 - DefaultComboBoxModel m = (DefaultComboBoxModel) entries.getModel(); 60.547 - m.addElement(e); 60.548 - if (m.getSize() == 1) 60.549 - entries.setSelectedItem(e); 60.550 - } 60.551 - 60.552 - /** 60.553 - * Initialize the GUI window. 60.554 - */ 60.555 - private void initGUI() { 60.556 - JPanel head = new JPanel(new GridBagLayout()); 60.557 - GridBagConstraints lc = new GridBagConstraints(); 60.558 - GridBagConstraints fc = new GridBagConstraints(); 60.559 - fc.anchor = GridBagConstraints.WEST; 60.560 - fc.fill = GridBagConstraints.HORIZONTAL; 60.561 - fc.gridwidth = GridBagConstraints.REMAINDER; 60.562 - 60.563 - entries = new JComboBox(); 60.564 - entries.addActionListener(new ActionListener() { 60.565 - public void actionPerformed(ActionEvent e) { 60.566 - showEntry((Entry) entries.getSelectedItem()); 60.567 - } 60.568 - }); 60.569 - fc.insets.bottom = 10; 60.570 - head.add(entries, fc); 60.571 - fc.insets.bottom = 0; 60.572 - head.add(new JLabel("check:"), lc); 60.573 - head.add(checkField = createTextField(80), fc); 60.574 - fc.fill = GridBagConstraints.NONE; 60.575 - head.add(setBackground(new JLabel("encl:"), enclColor), lc); 60.576 - head.add(enclPanel = new InfoPanel(), fc); 60.577 - head.add(setBackground(new JLabel("self:"), selfColor), lc); 60.578 - head.add(selfPanel = new InfoPanel(), fc); 60.579 - add(head, BorderLayout.NORTH); 60.580 - 60.581 - body = new JTextArea(); 60.582 - body.setFont(Font.decode(Font.MONOSPACED)); 60.583 - body.addCaretListener(new CaretListener() { 60.584 - public void caretUpdate(CaretEvent e) { 60.585 - int dot = e.getDot(); 60.586 - int mark = e.getMark(); 60.587 - if (dot == mark) 60.588 - statusText.setText("dot: " + dot); 60.589 - else 60.590 - statusText.setText("dot: " + dot + ", mark:" + mark); 60.591 - } 60.592 - }); 60.593 - JScrollPane p = new JScrollPane(body, 60.594 - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 60.595 - JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 60.596 - p.setPreferredSize(new Dimension(640, 480)); 60.597 - add(p, BorderLayout.CENTER); 60.598 - 60.599 - statusText = createTextField(80); 60.600 - add(statusText, BorderLayout.SOUTH); 60.601 - 60.602 - pack(); 60.603 - setLocationRelativeTo(null); // centered on screen 60.604 - setVisible(true); 60.605 - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 60.606 - } 60.607 - 60.608 - /** Show an entry that has been selected. */ 60.609 - private void showEntry(Entry e) { 60.610 - try { 60.611 - // update simple fields 60.612 - setTitle(e.file.getName()); 60.613 - checkField.setText(e.check); 60.614 - enclPanel.setInfo(e.encl); 60.615 - selfPanel.setInfo(e.self); 60.616 - // show file text with highlights 60.617 - body.setText(e.file.getCharContent(true).toString()); 60.618 - Highlighter highlighter = body.getHighlighter(); 60.619 - highlighter.removeAllHighlights(); 60.620 - addHighlight(highlighter, e.encl, enclColor); 60.621 - addHighlight(highlighter, e.self, selfColor); 60.622 - scroll(body, getMinPos(enclPanel.info, selfPanel.info)); 60.623 - } catch (IOException ex) { 60.624 - body.setText("Cannot read " + e.file.getName() + ": " + e); 60.625 - } 60.626 - } 60.627 - 60.628 - /** Create a test field. */ 60.629 - private JTextField createTextField(int width) { 60.630 - JTextField f = new JTextField(width); 60.631 - f.setEditable(false); 60.632 - f.setBorder(null); 60.633 - return f; 60.634 - } 60.635 - 60.636 - /** Add a highlighted region based on the positions in an Info object. */ 60.637 - private void addHighlight(Highlighter h, Info info, Color c) { 60.638 - int start = info.start; 60.639 - int end = info.end; 60.640 - if (start == -1 && end == -1) 60.641 - return; 60.642 - if (start == -1) 60.643 - start = end; 60.644 - if (end == -1) 60.645 - end = start; 60.646 - try { 60.647 - h.addHighlight(info.start, info.end, 60.648 - new DefaultHighlighter.DefaultHighlightPainter(c)); 60.649 - if (info.pos != -1) { 60.650 - Color c2 = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(.4f * 255)); // 40% 60.651 - h.addHighlight(info.pos, info.pos + 1, 60.652 - new DefaultHighlighter.DefaultHighlightPainter(c2)); 60.653 - } 60.654 - } catch (BadLocationException e) { 60.655 - e.printStackTrace(); 60.656 - } 60.657 - } 60.658 - 60.659 - /** Get the minimum valid position in a set of info objects. */ 60.660 - private int getMinPos(Info... values) { 60.661 - int i = Integer.MAX_VALUE; 60.662 - for (Info info: values) { 60.663 - if (info.start >= 0) i = Math.min(i, info.start); 60.664 - if (info.pos >= 0) i = Math.min(i, info.pos); 60.665 - if (info.end >= 0) i = Math.min(i, info.end); 60.666 - } 60.667 - return (i == Integer.MAX_VALUE) ? 0 : i; 60.668 - } 60.669 - 60.670 - /** Set the background on a component. */ 60.671 - private JComponent setBackground(JComponent comp, Color c) { 60.672 - comp.setOpaque(true); 60.673 - comp.setBackground(c); 60.674 - return comp; 60.675 - } 60.676 - 60.677 - /** Scroll a text area to display a given position near the middle of the visible area. */ 60.678 - private void scroll(final JTextArea t, final int pos) { 60.679 - // Using invokeLater appears to give text a chance to sort itself out 60.680 - // before the scroll happens; otherwise scrollRectToVisible doesn't work. 60.681 - // Maybe there's a better way to sync with the text... 60.682 - EventQueue.invokeLater(new Runnable() { 60.683 - public void run() { 60.684 - try { 60.685 - Rectangle r = t.modelToView(pos); 60.686 - JScrollPane p = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, t); 60.687 - r.y = Math.max(0, r.y - p.getHeight() * 2 / 5); 60.688 - r.height += p.getHeight() * 4 / 5; 60.689 - t.scrollRectToVisible(r); 60.690 - } catch (BadLocationException ignore) { 60.691 - } 60.692 - } 60.693 - }); 60.694 - } 60.695 - 60.696 - private JComboBox entries; 60.697 - private JTextField checkField; 60.698 - private InfoPanel enclPanel; 60.699 - private InfoPanel selfPanel; 60.700 - private JTextArea body; 60.701 - private JTextField statusText; 60.702 - 60.703 - private Color selfColor = new Color(0.f, 1.f, 0.f, 0.2f); // 20% green 60.704 - private Color enclColor = new Color(1.f, 0.f, 0.f, 0.2f); // 20% red 60.705 - 60.706 - /** Panel to display an Info object. */ 60.707 - private class InfoPanel extends JPanel { 60.708 - InfoPanel() { 60.709 - add(tagName = createTextField(20)); 60.710 - add(new JLabel("start:")); 60.711 - add(addListener(start = createTextField(6))); 60.712 - add(new JLabel("pos:")); 60.713 - add(addListener(pos = createTextField(6))); 60.714 - add(new JLabel("end:")); 60.715 - add(addListener(end = createTextField(6))); 60.716 - } 60.717 - 60.718 - void setInfo(Info info) { 60.719 - this.info = info; 60.720 - tagName.setText(tagNames.get(info.tag)); 60.721 - start.setText(String.valueOf(info.start)); 60.722 - pos.setText(String.valueOf(info.pos)); 60.723 - end.setText(String.valueOf(info.end)); 60.724 - } 60.725 - 60.726 - JTextField addListener(final JTextField f) { 60.727 - f.addMouseListener(new MouseAdapter() { 60.728 - @Override 60.729 - public void mouseClicked(MouseEvent e) { 60.730 - body.setCaretPosition(Integer.valueOf(f.getText())); 60.731 - body.getCaret().setVisible(true); 60.732 - } 60.733 - }); 60.734 - return f; 60.735 - } 60.736 - 60.737 - Info info; 60.738 - JTextField tagName; 60.739 - JTextField start; 60.740 - JTextField pos; 60.741 - JTextField end; 60.742 - } 60.743 - 60.744 - /** Object to record information about an error to be displayed. */ 60.745 - private class Entry { 60.746 - Entry(JavaFileObject file, String check, Info encl, Info self) { 60.747 - this.file = file; 60.748 - this.check = check; 60.749 - this.encl = encl; 60.750 - this.self= self; 60.751 - } 60.752 - 60.753 - @Override 60.754 - public String toString() { 60.755 - return file.getName() + " " + check + " " + getMinPos(encl, self); 60.756 - } 60.757 - 60.758 - final JavaFileObject file; 60.759 - final String check; 60.760 - final Info encl; 60.761 - final Info self; 60.762 - } 60.763 - } 60.764 -} 60.765 -
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/test/tools/javah/T6893943.java Tue Mar 09 15:29:45 2010 -0800 61.3 @@ -0,0 +1,75 @@ 61.4 +/* 61.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 61.7 + * 61.8 + * This code is free software; you can redistribute it and/or modify it 61.9 + * under the terms of the GNU General Public License version 2 only, as 61.10 + * published by the Free Software Foundation. 61.11 + * 61.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 61.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 61.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 61.15 + * version 2 for more details (a copy is included in the LICENSE file that 61.16 + * accompanied this code). 61.17 + * 61.18 + * You should have received a copy of the GNU General Public License version 61.19 + * 2 along with this work; if not, write to the Free Software Foundation, 61.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 61.21 + * 61.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 61.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 61.24 + * have any questions. 61.25 + */ 61.26 + 61.27 +/* 61.28 + * @test 61.29 + * @bug 6893943 61.30 + * @summary exit code from javah with no args is 0 61.31 + */ 61.32 + 61.33 +import java.io.*; 61.34 +import java.util.*; 61.35 + 61.36 +public class T6893943 { 61.37 + public static void main(String... args) throws Exception { 61.38 + new T6893943().run(); 61.39 + } 61.40 + 61.41 + void run() throws Exception { 61.42 + testSimpleAPI(); 61.43 + testCommand(); 61.44 + } 61.45 + 61.46 + void testSimpleAPI() throws Exception { 61.47 + PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.err)); 61.48 + int rc = com.sun.tools.javah.Main.run(new String[] { }, pw); 61.49 + expect("testSimpleAPI", rc, 1); 61.50 + } 61.51 + 61.52 + void testCommand() throws Exception { 61.53 + File javaHome = new File(System.getProperty("java.home")); 61.54 + if (javaHome.getName().equals("jre")) 61.55 + javaHome = javaHome.getParentFile(); 61.56 + 61.57 + List<String> command = new ArrayList<String>(); 61.58 + command.add(new File(new File(javaHome, "bin"), "javah").getPath()); 61.59 + command.add("-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path")); 61.60 + //System.err.println("command: " + command); 61.61 + 61.62 + ProcessBuilder pb = new ProcessBuilder(command); 61.63 + pb.redirectErrorStream(true); 61.64 + Process p = pb.start(); 61.65 + p.getOutputStream().close(); 61.66 + String line; 61.67 + BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); 61.68 + while ((line = in.readLine()) != null) 61.69 + System.err.println("javah: " + line); 61.70 + int rc = p.waitFor(); 61.71 + expect("testCommand", rc, 1); 61.72 + } 61.73 + 61.74 + void expect(String name, int actual, int expect) throws Exception { 61.75 + if (actual != expect) 61.76 + throw new Exception(name + ": unexpected exit: " + actual + ", expected: " + expect); 61.77 + } 61.78 +}