This commit is contained in:
Lana Steuck 2010-03-09 15:29:45 -08:00
commit a5884c7b3d
61 changed files with 912 additions and 156 deletions

View File

@ -457,8 +457,10 @@ public class Apt extends ListBuffer<Env<AttrContext>> {
throw new UsageMessageNeededException();
try {
for(AnnotationProcessorFactory apFactory: factoryToAnnotation.keySet()) {
AnnotationProcessor processor = apFactory.getProcessorFor(factoryToAnnotation.get(apFactory),
for(Map.Entry<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> entry :
factoryToAnnotation.entrySet()) {
AnnotationProcessorFactory apFactory = entry.getKey();
AnnotationProcessor processor = apFactory.getProcessorFor(entry.getValue(),
trivAPE);
if (processor != null)
processors.add(processor);

View File

@ -82,7 +82,7 @@ public class CommandLine {
st.commentChar('#');
st.quoteChar('"');
st.quoteChar('\'');
while (st.nextToken() != st.TT_EOF) {
while (st.nextToken() != StreamTokenizer.TT_EOF) {
args.append(st.sval);
}
r.close();

View File

@ -270,7 +270,7 @@ class AnnotationProxyMaker {
* The toString, hashCode, and equals methods foward to the underlying
* type.
*/
private static class MirroredTypeExceptionProxy extends ExceptionProxy {
private static final class MirroredTypeExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = 6662035281599933545L;
private MirroredTypeException ex;
@ -312,7 +312,7 @@ class AnnotationProxyMaker {
* The toString, hashCode, and equals methods foward to the underlying
* types.
*/
private static class MirroredTypesExceptionProxy extends ExceptionProxy {
private static final class MirroredTypesExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = -6670822532616693951L;
private MirroredTypesException ex;

View File

@ -58,7 +58,7 @@ public abstract class DeclarationImpl implements Declaration {
protected final AptEnv env;
public final Symbol sym;
protected static DeclarationFilter identityFilter =
protected static final DeclarationFilter identityFilter =
new DeclarationFilter();

View File

@ -71,6 +71,6 @@ public abstract class TypeMirrorImpl implements TypeMirror {
* {@inheritDoc}
*/
public int hashCode() {
return env.jctypes.hashCode(type);
return Types.hashCode(type);
}
}

View File

@ -40,7 +40,7 @@ import java.util.Iterator;
*/
public class ConstantPool {
public class InvalidIndex extends ConstantPoolException {
public static class InvalidIndex extends ConstantPoolException {
private static final long serialVersionUID = -4350294289300939730L;
InvalidIndex(int index) {
super(index);
@ -53,7 +53,7 @@ public class ConstantPool {
}
}
public class UnexpectedEntry extends ConstantPoolException {
public static class UnexpectedEntry extends ConstantPoolException {
private static final long serialVersionUID = 6986335935377933211L;
UnexpectedEntry(int index, int expected_tag, int found_tag) {
super(index);
@ -71,7 +71,7 @@ public class ConstantPool {
public final int found_tag;
}
public class InvalidEntry extends ConstantPoolException {
public static class InvalidEntry extends ConstantPoolException {
private static final long serialVersionUID = 1000087545585204447L;
InvalidEntry(int index, int tag) {
super(index);
@ -87,7 +87,7 @@ public class ConstantPool {
public final int tag;
}
public class EntryNotFound extends ConstantPoolException {
public static class EntryNotFound extends ConstantPoolException {
private static final long serialVersionUID = 2885537606468581850L;
EntryNotFound(Object value) {
super(-1);
@ -694,7 +694,7 @@ public class ConstantPool {
public int byteLength() {
class SizeOutputStream extends OutputStream {
@Override
public void write(int b) throws IOException {
public void write(int b) {
size++;
}
int size;

View File

@ -31,23 +31,21 @@ import com.sun.tools.doclets.formats.html.*;
public class Standard {
public static final HtmlDoclet htmlDoclet = new HtmlDoclet();
public static int optionLength(String option) {
return htmlDoclet.optionLength(option);
return HtmlDoclet.optionLength(option);
}
public static boolean start(RootDoc root) {
return htmlDoclet.start(root);
return HtmlDoclet.start(root);
}
public static boolean validOptions(String[][] options,
DocErrorReporter reporter) {
return htmlDoclet.validOptions(options, reporter);
return HtmlDoclet.validOptions(options, reporter);
}
public static LanguageVersion languageVersion() {
return htmlDoclet.languageVersion();
return HtmlDoclet.languageVersion();
}
}

View File

@ -64,7 +64,7 @@ class Launcher {
fileChooser.setSelectedFile(new File(fileName));
}
}
if (fileChooser.showOpenDialog(null) == fileChooser.APPROVE_OPTION) {
if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
String fileName = fileChooser.getSelectedFile().getPath();
prefs.put("recent.file", fileName);
javac.run(System.in, null, null, "-d", "/tmp", fileName);

View File

@ -137,7 +137,7 @@ public final class JavacTool implements JavaCompiler {
}
private static boolean match(OptionKind clientKind, OptionKind optionKind) {
return (clientKind == (optionKind == OptionKind.HIDDEN ? optionKind.EXTENDED : optionKind));
return (clientKind == (optionKind == OptionKind.HIDDEN ? OptionKind.EXTENDED : optionKind));
}
public JavacFileManager getStandardFileManager(

View File

@ -198,7 +198,12 @@ public class Lint
/**
* Warn about Sun proprietary API that may be removed in a future release.
*/
SUNAPI("sunapi", true);
SUNAPI("sunapi", true),
/**
* Warn about issues relating to use of statics
*/
STATIC("static");
LintCategory(String option) {
this(option, false);

View File

@ -162,7 +162,7 @@ public abstract class Symbol implements Element {
* the default package; otherwise, the owner symbol is returned
*/
public Symbol location() {
if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK)) {
if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK && owner.kind != TYP)) {
return null;
}
return owner;

View File

@ -2504,7 +2504,7 @@ public class Types {
}
@Override
public int hashCode() {
return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
return 127 * Types.hashCode(t1) + Types.hashCode(t2);
}
@Override
public boolean equals(Object obj) {
@ -3375,7 +3375,7 @@ public class Types {
this.t = t;
}
public int hashCode() {
return Types.this.hashCode(t);
return Types.hashCode(t);
}
public boolean equals(Object obj) {
return (obj instanceof SingletonType) &&

View File

@ -2020,6 +2020,10 @@ public class Attr extends JCTree.Visitor {
tree.pos(), site, sym.name, true);
}
}
} else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && sym.name != names._class) {
// If the qualified item is not a type and the selected item is static, report
// a warning. Make allowance for the class of an array type e.g. Object[].class)
chk.warnStatic(tree, "static.not.qualified.by.type", Kinds.kindName(sym.kind), sym.owner);
}
// If we are selecting an instance member via a `super', ...
@ -2636,6 +2640,7 @@ public class Attr extends JCTree.Visitor {
if (tree.bounds.tail.nonEmpty()) {
log.error(tree.bounds.tail.head.pos(),
"type.var.may.not.be.followed.by.other.bounds");
log.unrecoverableError = true;
tree.bounds = List.of(tree.bounds.head);
a.bound = bs.head;
}

View File

@ -189,6 +189,11 @@ public class Check {
sunApiHandler.report(pos, msg, args);
}
public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
if (lint.isEnabled(LintCategory.STATIC))
log.warning(pos, msg, args);
}
/**
* Report any deferred diagnostics.
*/

View File

@ -270,6 +270,7 @@ public class Enter extends JCTree.Visitor {
return ts.toList();
}
@Override
public void visitTopLevel(JCCompilationUnit tree) {
JavaFileObject prev = log.useSource(tree.sourcefile);
boolean addEnv = false;
@ -289,13 +290,13 @@ public class Enter extends JCTree.Visitor {
tree.packge = syms.unnamedPackage;
}
tree.packge.complete(); // Find all classes in package.
Env<AttrContext> env = topLevelEnv(tree);
Env<AttrContext> topEnv = topLevelEnv(tree);
// Save environment of package-info.java file.
if (isPkgInfo) {
Env<AttrContext> env0 = typeEnvs.get(tree.packge);
if (env0 == null) {
typeEnvs.put(tree.packge, env);
typeEnvs.put(tree.packge, topEnv);
} else {
JCCompilationUnit tree0 = env0.toplevel;
if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
@ -306,7 +307,7 @@ public class Enter extends JCTree.Visitor {
if (addEnv || (tree0.packageAnnotations.isEmpty() &&
tree.docComments != null &&
tree.docComments.get(tree) != null)) {
typeEnvs.put(tree.packge, env);
typeEnvs.put(tree.packge, topEnv);
}
}
}
@ -322,14 +323,15 @@ public class Enter extends JCTree.Visitor {
c.members_field = new Scope(c);
tree.packge.package_info = c;
}
classEnter(tree.defs, env);
classEnter(tree.defs, topEnv);
if (addEnv) {
todo.append(env);
todo.append(topEnv);
}
log.useSource(prev);
result = null;
}
@Override
public void visitClassDef(JCClassDecl tree) {
Symbol owner = env.info.scope.owner;
Scope enclScope = enterScope(env);
@ -435,6 +437,7 @@ public class Enter extends JCTree.Visitor {
* Enter a symbol for type parameter in local scope, after checking that it
* is unique.
*/
@Override
public void visitTypeParameter(JCTypeParameter tree) {
TypeVar a = (tree.type != null)
? (TypeVar)tree.type
@ -448,6 +451,7 @@ public class Enter extends JCTree.Visitor {
/** Default class enter visitor method: do nothing.
*/
@Override
public void visitTree(JCTree tree) {
result = null;
}
@ -489,10 +493,8 @@ public class Enter extends JCTree.Visitor {
for (JCCompilationUnit tree : trees) {
if (tree.starImportScope.elems == null) {
JavaFileObject prev = log.useSource(tree.sourcefile);
Env<AttrContext> env = typeEnvs.get(tree);
if (env == null)
env = topLevelEnv(tree);
memberEnter.memberEnter(tree, env);
Env<AttrContext> topEnv = topLevelEnv(tree);
memberEnter.memberEnter(tree, topEnv);
log.useSource(prev);
}
}

View File

@ -607,10 +607,12 @@ public class TransTypes extends TreeTranslator {
public void visitNewArray(JCNewArray tree) {
tree.elemtype = translate(tree.elemtype, null);
translate(tree.dims, syms.intType);
tree.elems = translate(tree.elems,
(tree.type == null) ? null
: erasure(types.elemtype(tree.type)));
tree.type = erasure(tree.type);
if (tree.type != null) {
tree.elems = translate(tree.elems, erasure(types.elemtype(tree.type)));
tree.type = erasure(tree.type);
} else {
tree.elems = translate(tree.elems, null);
}
result = tree;
}

View File

@ -260,7 +260,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
archive = openArchive(directory);
} catch (IOException ex) {
log.error("error.reading.file",
directory, ex.getLocalizedMessage());
directory, getMessage(ex));
return;
}
}
@ -489,7 +489,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
archive = new MissingArchive(zipFileName);
} catch (IOException ex) {
if (zipFileName.exists())
log.error("error.reading.file", zipFileName, ex.getLocalizedMessage());
log.error("error.reading.file", zipFileName, getMessage(ex));
archive = new MissingArchive(zipFileName);
}
@ -838,4 +838,23 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
throw new IllegalArgumentException("Invalid relative path: " + file);
}
/**
* Get a detail message from an IOException.
* Most, but not all, instances of IOException provide a non-null result
* for getLocalizedMessage(). But some instances return null: in these
* cases, fallover to getMessage(), and if even that is null, return the
* name of the exception itself.
* @param e an IOException
* @return a string to include in a compiler diagnostic
*/
public static String getMessage(IOException e) {
String s = e.getLocalizedMessage();
if (s != null)
return s;
s = e.getMessage();
if (s != null)
return s;
return e.toString();
}
}

View File

@ -320,7 +320,7 @@ public class Paths {
addFile(f, warn);
}
} catch (IOException e) {
log.error("error.reading.file", jarFile, e.getLocalizedMessage());
log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e));
}
}
}

View File

@ -1135,7 +1135,7 @@ public class ClassReader implements Completer {
self.name = simpleBinaryName(self.flatname, c.flatname) ;
self.owner = m != null ? m : c;
if (self.name.isEmpty())
self.fullname = null;
self.fullname = names.empty;
else
self.fullname = ClassSymbol.formFullName(self.name, self.owner);

View File

@ -808,8 +808,8 @@ public class Gen extends JCTree.Visitor {
code.resolve(secondJumps);
CondItem second = genCond(tree.falsepart, CRT_FLOW_TARGET);
CondItem result = items.makeCondItem(second.opcode,
code.mergeChains(trueJumps, second.trueJumps),
code.mergeChains(falseJumps, second.falseJumps));
Code.mergeChains(trueJumps, second.trueJumps),
Code.mergeChains(falseJumps, second.falseJumps));
if (markBranches) result.tree = tree.falsepart;
return result;
} else {
@ -1322,7 +1322,7 @@ public class Gen extends JCTree.Visitor {
if (useJsrLocally) {
if (tree.finalizer != null) {
Code.State jsrState = code.state.dup();
jsrState.push(code.jsrReturnValue);
jsrState.push(Code.jsrReturnValue);
tryEnv.info.cont =
new Chain(code.emitJump(jsr),
tryEnv.info.cont,
@ -1375,7 +1375,7 @@ public class Gen extends JCTree.Visitor {
genFinalizer(env);
if (hasFinalizer || l.tail.nonEmpty()) {
code.statBegin(TreeInfo.endPos(env.tree));
exitChain = code.mergeChains(exitChain,
exitChain = Code.mergeChains(exitChain,
code.branch(goto_));
}
endFinalizerGap(env);
@ -1963,7 +1963,7 @@ public class Gen extends JCTree.Visitor {
result = items.
makeCondItem(rcond.opcode,
rcond.trueJumps,
code.mergeChains(falseJumps,
Code.mergeChains(falseJumps,
rcond.falseJumps));
} else {
result = lcond;
@ -1976,7 +1976,7 @@ public class Gen extends JCTree.Visitor {
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
result = items.
makeCondItem(rcond.opcode,
code.mergeChains(trueJumps, rcond.trueJumps),
Code.mergeChains(trueJumps, rcond.trueJumps),
rcond.falseJumps);
} else {
result = lcond;

View File

@ -792,25 +792,25 @@ public class Items {
}
Chain jumpTrue() {
if (tree == null) return code.mergeChains(trueJumps, code.branch(opcode));
if (tree == null) return Code.mergeChains(trueJumps, code.branch(opcode));
// we should proceed further in -Xjcov mode only
int startpc = code.curPc();
Chain c = code.mergeChains(trueJumps, code.branch(opcode));
Chain c = Code.mergeChains(trueJumps, code.branch(opcode));
code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc());
return c;
}
Chain jumpFalse() {
if (tree == null) return code.mergeChains(falseJumps, code.branch(code.negate(opcode)));
if (tree == null) return Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
// we should proceed further in -Xjcov mode only
int startpc = code.curPc();
Chain c = code.mergeChains(falseJumps, code.branch(code.negate(opcode)));
Chain c = Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc());
return c;
}
CondItem negate() {
CondItem c = new CondItem(code.negate(opcode), falseJumps, trueJumps);
CondItem c = new CondItem(Code.negate(opcode), falseJumps, trueJumps);
c.tree = tree;
return c;
}

View File

@ -82,7 +82,7 @@ public class CommandLine {
st.commentChar('#');
st.quoteChar('"');
st.quoteChar('\'');
while (st.nextToken() != st.TT_EOF) {
while (st.nextToken() != StreamTokenizer.TT_EOF) {
args.append(st.sval);
}
r.close();

View File

@ -549,12 +549,6 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
return log.nwarnings;
}
/** Whether or not any parse errors have occurred.
*/
public boolean parseErrors() {
return parseErrors;
}
/** Try to open input stream with given name.
* Report an error if this fails.
* @param filename The file name of the input stream to be opened.
@ -564,7 +558,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
inputFiles.add(filename);
return filename.getCharContent(false);
} catch (IOException e) {
log.error("error.reading.file", filename, e.getLocalizedMessage());
log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
return null;
}
}
@ -588,7 +582,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
int initialErrorCount = log.nerrors;
Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo);
tree = parser.parseCompilationUnit();
parseErrors |= (log.nerrors > initialErrorCount);
log.unrecoverableError |= (log.nerrors > initialErrorCount);
if (verbose) {
printVerbose("parsing.done", Long.toString(elapsed(msec)));
}
@ -723,7 +717,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
try {
tree = parse(filename, filename.getCharContent(false));
} catch (IOException e) {
log.error("error.reading.file", filename, e);
log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
} finally {
log.useSource(prev);
@ -768,9 +762,6 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
private long start_msec = 0;
public long elapsed_msec = 0;
/** Track whether any errors occurred while parsing source text. */
private boolean parseErrors = false;
public void compile(List<JavaFileObject> sourceFileObject)
throws Throwable {
compile(sourceFileObject, List.<String>nil(), null);
@ -1114,7 +1105,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
return env;
if (verboseCompilePolicy)
log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
Log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
if (verbose)
printVerbose("checking.attribution", env.enclClass.sym);

View File

@ -26,6 +26,8 @@
package com.sun.tools.javac.model;
import com.sun.tools.javac.util.*;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.lang.annotation.*;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
@ -268,10 +270,10 @@ public class AnnotationProxyMaker {
* The toString, hashCode, and equals methods foward to the underlying
* type.
*/
private static class MirroredTypeExceptionProxy extends ExceptionProxy {
private static final class MirroredTypeExceptionProxy extends ExceptionProxy {
static final long serialVersionUID = 269;
private transient final TypeMirror type;
private transient TypeMirror type;
private final String typeString;
MirroredTypeExceptionProxy(TypeMirror t) {
@ -296,6 +298,13 @@ public class AnnotationProxyMaker {
protected RuntimeException generateException() {
return new MirroredTypeException(type);
}
// Explicitly set all transient fields.
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
type = null;
}
}
@ -304,10 +313,10 @@ public class AnnotationProxyMaker {
* The toString, hashCode, and equals methods foward to the underlying
* types.
*/
private static class MirroredTypesExceptionProxy extends ExceptionProxy {
private static final class MirroredTypesExceptionProxy extends ExceptionProxy {
static final long serialVersionUID = 269;
private transient final List<TypeMirror> types;
private transient List<TypeMirror> types;
private final String typeStrings;
MirroredTypesExceptionProxy(List<TypeMirror> ts) {
@ -333,5 +342,12 @@ public class AnnotationProxyMaker {
protected RuntimeException generateException() {
return new MirroredTypesException(types);
}
// Explicitly set all transient fields.
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
types = null;
}
}
}

View File

@ -1561,7 +1561,10 @@ public class JavacParser implements Parser {
JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
if (newClass.def != null) {
assert newClass.def.mods.annotations.isEmpty();
newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
if (newAnnotations.nonEmpty()) {
newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
}
}
return newClass;
} else {
@ -3016,6 +3019,18 @@ public class JavacParser implements Parser {
return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
}
/**
* Return the lesser of two positions, making allowance for either one
* being unset.
*/
static int earlier(int pos1, int pos2) {
if (pos1 == Position.NOPOS)
return pos2;
if (pos2 == Position.NOPOS)
return pos1;
return (pos1 < pos2 ? pos1 : pos2);
}
/** Return operation tag of binary operator represented by token,
* -1 if token is not a binary operator.
*/

View File

@ -690,10 +690,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
ProcessorState ps = psi.next();
Set<String> matchedNames = new HashSet<String>();
Set<TypeElement> typeElements = new LinkedHashSet<TypeElement>();
for (String unmatchedAnnotationName : unmatchedAnnotations.keySet()) {
for (Map.Entry<String, TypeElement> entry: unmatchedAnnotations.entrySet()) {
String unmatchedAnnotationName = entry.getKey();
if (ps.annotationSupported(unmatchedAnnotationName) ) {
matchedNames.add(unmatchedAnnotationName);
TypeElement te = unmatchedAnnotations.get(unmatchedAnnotationName);
TypeElement te = entry.getValue();
if (te != null)
typeElements.add(te);
}
@ -790,16 +792,13 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
List<JCCompilationUnit> roots,
List<ClassSymbol> classSymbols,
Iterable<? extends PackageSymbol> pckSymbols)
throws IOException {
throws IOException {
log = Log.instance(context);
// Writer for -XprintRounds and -XprintProcessorInfo data
PrintWriter xout = context.get(Log.outKey);
TaskListener taskListener = context.get(TaskListener.class);
AnnotationCollector collector = new AnnotationCollector();
JavaCompiler compiler = JavaCompiler.instance(context);
compiler.todo.clear(); // free the compiler's resources
@ -878,7 +877,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
roots = cleanTrees(roots).appendList(parsedFiles);
// Check for errors after parsing
if (compiler.parseErrors()) {
if (log.unrecoverableError) {
errorStatus = true;
break runAround;
} else {
@ -912,7 +911,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
roots = runLastRound(xout, roundNumber, errorStatus, compiler, roots, taskListener);
// Set error status for any files compiled and generated in
// the last round
if (compiler.parseErrors())
if (log.unrecoverableError)
errorStatus = true;
compiler.close(false);
@ -1218,45 +1217,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return false;
}
private class AnnotationCollector extends TreeScanner {
List<JCTree> path = List.nil();
static final boolean verbose = false;
List<JCAnnotation> annotations = List.nil();
public List<JCAnnotation> findAnnotations(List<? extends JCTree> nodes) {
annotations = List.nil();
scan(nodes);
List<JCAnnotation> found = annotations;
annotations = List.nil();
return found.reverse();
}
public void scan(JCTree node) {
if (node == null)
return;
Symbol sym = TreeInfo.symbolFor(node);
if (sym != null)
path = path.prepend(node);
super.scan(node);
if (sym != null)
path = path.tail;
}
public void visitAnnotation(JCAnnotation node) {
annotations = annotations.prepend(node);
if (verbose) {
StringBuilder sb = new StringBuilder();
for (JCTree tree : path.reverse()) {
System.err.print(sb);
System.err.println(TreeInfo.symbolFor(tree));
sb.append(" ");
}
System.err.print(sb);
System.err.println(node);
}
}
}
private static <T extends JCTree> List<T> cleanTrees(List<T> nodes) {
for (T node : nodes)
treeCleaner.scan(node);

View File

@ -720,6 +720,9 @@ compiler.warn.big.major.version=\
{0}: major version {1} is newer than {2}, the highest major version supported by this compiler.\n\
It is recommended that the compiler be upgraded.
compiler.warn.static.not.qualified.by.type=\
[static] static {0} should be qualified by type name, {1}, instead of by an expression
# Warnings related to annotation processing
compiler.warn.proc.package.does.not.exist=\
package {0} does not exist

View File

@ -201,7 +201,7 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
private String selectFormat(JCDiagnostic d) {
DiagnosticSource source = d.getDiagnosticSource();
String format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT);
if (source != null) {
if (source != null && source != DiagnosticSource.NO_SOURCE) {
if (d.getIntPosition() != Position.NOPOS) {
format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_POS_FORMAT);
} else if (source.getFile() != null &&

View File

@ -192,6 +192,12 @@ public class Log extends AbstractLog {
*/
public int nwarnings = 0;
/**
* Whether or not an unrecoverable error has been seen.
* Unrecoverable errors prevent subsequent annotation processing.
*/
public boolean unrecoverableError;
/** A set of all errors generated so far. This is used to avoid printing an
* error message more than once. For each error, a pair consisting of the
* source file name and source code position of the error is added to the set.

View File

@ -34,7 +34,6 @@ import com.sun.javadoc.*;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.Context;
@ -73,10 +72,6 @@ public class DocEnv {
/** Referenced directly in RootDocImpl. */
JavadocClassReader reader;
/** The compiler's attribution phase (needed to evaluate
* constant initializers). */
Attr attr;
/** Javadoc's own version of the compiler's enter phase. */
JavadocEnter enter;
@ -91,8 +86,6 @@ public class DocEnv {
/** Access filter (public, protected, ...). */
ModifierFilter showAccess;
private ClassDocImpl runtimeException;
/** True if we are using a sentence BreakIterator. */
boolean breakiterator;
@ -129,7 +122,6 @@ public class DocEnv {
syms = Symtab.instance(context);
reader = JavadocClassReader.instance0(context);
enter = JavadocEnter.instance0(context);
attr = Attr.instance(context);
names = Names.instance(context);
externalizableSym = reader.enterClass(names.fromString("java.io.Externalizable"));
chk = Check.instance(context);

View File

@ -349,12 +349,12 @@ class SeeTagImpl extends TagImpl implements SeeTag, LayoutCharacters {
// (int i, String s) ==> [0] = "int", [1] = String
// (int[][], String[]) ==> [0] = "int[][]" // [1] = "String[]"
class ParameterParseMachine {
final int START = 0;
final int TYPE = 1;
final int NAME = 2;
final int TNSPACE = 3; // space between type and name
final int ARRAYDECORATION = 4;
final int ARRAYSPACE = 5;
static final int START = 0;
static final int TYPE = 1;
static final int NAME = 2;
static final int TNSPACE = 3; // space between type and name
static final int ARRAYDECORATION = 4;
static final int ARRAYSPACE = 5;
String parameters;

View File

@ -255,9 +255,11 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
}
this.classes = new ArrayList<String>();
for (String classname: classes) {
classname.getClass(); // null-check
this.classes.add(classname);
if (classes != null) {
for (String classname: classes) {
classname.getClass(); // null-check
this.classes.add(classname);
}
}
}
@ -316,6 +318,12 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
int run(String[] args) {
try {
handleOptions(args);
if (classes == null || classes.size() == 0) {
if (help || version || fullVersion)
return 0;
else
return 1;
}
boolean ok = run();
return ok ? 0 : 1;
} catch (BadArgs e) {
@ -347,8 +355,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
fileManager = getDefaultFileManager(diagnosticListener, log);
Iterator<String> iter = args.iterator();
if (!iter.hasNext())
help = true;
boolean noArgs = !iter.hasNext();
while (iter.hasNext()) {
String arg = iter.next();
@ -365,7 +372,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
}
if ((classes == null || classes.size() == 0) &&
!(help || version || fullVersion)) {
!(noArgs || help || version || fullVersion)) {
throw new BadArgs("err.no.classes.specified");
}

View File

@ -0,0 +1,9 @@
T4880220.java:20:27: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
T4880220.java:21:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
- compiler.err.warnings.and.werror
1 error
6 warnings

View File

@ -0,0 +1,43 @@
/*
* @test /nodynamiccopyright/
* @bug 4880220
* @summary Add a warning when accessing a static method via an reference
*
* @compile/ref=T4880220.empty.out T4880220.java
* @compile/ref=T4880220.warn.out -XDrawDiagnostics -Xlint:static T4880220.java
* @compile/ref=T4880220.warn.out -XDrawDiagnostics -Xlint:all T4880220.java
* @compile/ref=T4880220.empty.out -XDrawDiagnostics -Xlint:all,-static T4880220.java
* @compile/ref=T4880220.error.out/fail -XDrawDiagnostics -Werror -Xlint:all T4880220.java
*/
public class T4880220 {
void m1() {
int good_1 = C.m();
int good_2 = C.f;
int good_3 = C.x;
C c = new C();
int bad_inst_1 = c.m();
int bad_inst_2 = c.f;
int bad_inst_3 = c.x;
int bad_expr_1 = c().m();
int bad_expr_2 = c().f;
int bad_expr_3 = c().x;
}
void m2() {
Class<?> good_1 = C.class;
Class<?> good_2 = C[].class;
}
C c() {
return new C();
}
static class C {
static int m() { return 0; }
static int f;
static final int x = 3;
}
}

View File

@ -0,0 +1,7 @@
T4880220.java:20:27: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
T4880220.java:21:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
6 warnings

View File

@ -0,0 +1,38 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @summary Unchecked method call on a method declared inside anonymous inner causes javac to crash
* @compile -Xlint:unchecked T6881645.java
*/
class T6881645 {
Object o = new Object() {
<Z> void m (Class<Z> x) {}
void test() {
m((Class)null);
}
};
}

View File

@ -30,6 +30,8 @@
* @compile ThrowsIntersection_1.java
*/
package ThrowsIntersection_1;
class Ex1 extends Exception {}
class Ex2 extends Exception {}

View File

@ -30,6 +30,8 @@
* @compile ThrowsIntersection_2.java
*/
package ThrowsIntersection_2;
class Ex1 extends Exception {}
class Ex2 extends Exception {}
class Ex3 extends Exception {}

View File

@ -30,6 +30,8 @@
* @run compile/fail ThrowsIntersection_3.java
*/
package ThrowsIntersection_3;
class Ex1 extends Exception {}
class Ex2 extends Exception {}

View File

@ -30,6 +30,8 @@
* @run compile/fail ThrowsIntersection_4.java
*/
package ThrowsIntersection_4;
// Note: This is the test that actually failed for 4042259. The others are for completeness.
class Ex1 extends Exception {}

View File

@ -30,7 +30,7 @@
* @compile/fail Constant.java
*/
package test.tools.javac.annotation.Constant;
package Constant;
@T(a = X.x)
@interface T {

View File

@ -34,7 +34,10 @@ import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.parser.*; // XXX
import com.sun.tools.javac.util.*; // XXX
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.charset.Charset;
import java.util.Arrays;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
@ -43,6 +46,10 @@ import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.*;
import static javax.tools.StandardLocation.CLASS_PATH;
import static javax.tools.StandardLocation.SOURCE_PATH;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
public class TestJavacTaskScanner extends ToolTester {
final JavacTaskImpl task;
@ -56,6 +63,7 @@ public class TestJavacTaskScanner extends ToolTester {
TestJavacTaskScanner(File file) {
final Iterable<? extends JavaFileObject> compilationUnits =
fm.getJavaFileObjects(new File[] {file});
StandardJavaFileManager fm = getLocalFileManager(tool, null, null);
task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits);
task.getContext().put(Scanner.Factory.scannerFactoryKey,
new MyScanner.Factory(task.getContext(), this));
@ -83,7 +91,7 @@ public class TestJavacTaskScanner extends ToolTester {
System.out.println("#parseTypeElements: " + numParseTypeElements);
System.out.println("#allMembers: " + numAllMembers);
check(numTokens, "#Tokens", 891);
check(numTokens, "#Tokens", 1222);
check(numParseTypeElements, "#parseTypeElements", 136);
check(numAllMembers, "#allMembers", 67);
}
@ -117,6 +125,47 @@ public class TestJavacTaskScanner extends ToolTester {
numAllMembers++;
}
}
/* Similar to ToolTester.getFileManager, except that this version also ensures
* javac classes will be available on the classpath. The javac classes are assumed
* to be on the classpath used to run this test (this is true when using jtreg).
* The classes are found by obtaining the URL for a sample javac class, using
* getClassLoader().getResource(), and then deconstructing the URL to find the
* underlying directory or jar file to place on the classpath.
*/
public StandardJavaFileManager getLocalFileManager(JavaCompiler tool,
DiagnosticListener<JavaFileObject> dl,
Charset encoding) {
File javac_classes;
try {
final String javacMainClass = "com/sun/tools/javac/Main.class";
URL url = getClass().getClassLoader().getResource(javacMainClass);
if (url == null)
throw new Error("can't locate javac classes");
URI uri = url.toURI();
String scheme = uri.getScheme();
String ssp = uri.getSchemeSpecificPart();
if (scheme.equals("jar")) {
javac_classes = new File(new URI(ssp.substring(0, ssp.indexOf("!/"))));
} else if (scheme.equals("file")) {
javac_classes = new File(ssp.substring(0, ssp.indexOf(javacMainClass)));
} else
throw new Error("unknown URL: " + url);
} catch (URISyntaxException e) {
throw new Error(e);
}
System.err.println("javac_classes: " + javac_classes);
StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, encoding);
try {
fm.setLocation(SOURCE_PATH, Arrays.asList(test_src));
fm.setLocation(CLASS_PATH, Arrays.asList(test_classes, javac_classes));
fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes));
} catch (IOException e) {
throw new AssertionError(e);
}
return fm;
}
}
class MyScanner extends Scanner {

View File

@ -0,0 +1,101 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6930108
* @summary IllegalArgumentException in AbstractDiagnosticFormatter for tools/javac/api/TestJavacTaskScanner.java
* @library ./lib
* @build ToolTester
* @run main TestResolveError
*/
import java.io.*;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.*;
import com.sun.tools.javac.api.JavacTaskImpl;
/*
* This is a cut down version of TestJavacTaskScanner, which as originally written
* caused an IllegalArgumentException in AbstractDiagnosticFormatter as a result
* of calling task.parseType with a name whose resolution depended on the setting
* of the bootclasspath.
* This test has the same call, task.parseType("List<String>", clazz), but checks
* that the error is handled in a reasonable way by javac.
*/
public class TestResolveError extends ToolTester {
public static void main(String... args) throws Exception {
new TestResolveError().run();
}
void run() throws Exception {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
File file = new File(test_src, "TestResolveError.java");
final Iterable<? extends JavaFileObject> compilationUnits =
fm.getJavaFileObjects(new File[] {file});
task = (JavacTaskImpl)tool.getTask(pw, fm, null, null, null, compilationUnits);
elements = task.getElements();
types = task.getTypes();
Iterable<? extends TypeElement> toplevels;
try {
toplevels = task.enter(task.parse());
} catch (IOException ex) {
throw new AssertionError(ex);
}
for (TypeElement clazz : toplevels) {
System.out.format("Testing %s:%n%n", clazz.getSimpleName());
// this should not cause any exception from the compiler,
// such as IllegalArgumentException
testParseType(clazz);
}
pw.close();
String out = sw.toString();
System.out.println(out);
if (out.contains("com.sun.tools.javac.util"))
throw new Exception("Unexpected output from compiler");
}
void testParseType(TypeElement clazz) {
DeclaredType type = (DeclaredType)task.parseType("List<String>", clazz);
for (Element member : elements.getAllMembers((TypeElement)type.asElement())) {
TypeMirror mt = types.asMemberOf(type, member);
System.out.format("%s : %s -> %s%n", member.getSimpleName(), member.asType(), mt);
}
}
JavacTaskImpl task;
Elements elements;
Types types;
}

View File

@ -30,7 +30,7 @@
* @compile Casting.java
*/
package test.tools.javac.generics.Casting;
package Casting;
class Test {}

View File

@ -30,7 +30,7 @@
* @compile Casting3.java
*/
package test.tools.javac.generics.Casting3;
package Casting3;
class A<T extends A<T>> {
<U extends A<U>> void f() {

View File

@ -30,7 +30,7 @@
* @compile -Werror -Xlint:unchecked Casting4.java
*/
package test.tools.javac.generics.Casting4;
package Casting4;
class Casting4 {
<M> Integer f(Comparable<M> c) {

View File

@ -30,7 +30,7 @@
* @compile InnerInterface1.java
*/
package test.tools.javac.generics.InnerInterface1;
package InnerInterface1;
interface Iterator<E> {
}

View File

@ -30,7 +30,7 @@
* @compile InnerInterface2.java
*/
package test.tools.javac.generics.InnerInterface2;
package InnerInterface2;
class Builder<Community> {

View File

@ -30,7 +30,7 @@
* @compile/fail Multibound1.java
*/
package test.tools.javac.generics.Multibound1;
package Multibound1;
interface A {}
interface B {}

View File

@ -30,7 +30,7 @@
* @compile MultipleInheritance.java
*/
package test.tools.javac.generics.MultipleInheritance;
package MultipleInheritance;
import java.util.*;

View File

@ -27,22 +27,22 @@
* @summary generics: type inference failure due to a bug in ClassSymbol.isLess
* @author gafter
*
* @compile NameOrder.java
* @compile NameOrder.java
*/
package test.tools.javac.generics.NameOrder;
package NameOrder;
interface a {}
interface b {}
interface c {}
class A implements a, b {}
class B implements c, a {}
class AB implements a, b {}
class CA implements c, a {}
// this is how to trigger a symptom:
abstract class C {
abstract class X {
<T> T f(T t1, T t2) { return null; }
void g() {
a x = f( new A(), new B() );
a x = f( new AB(), new CA() );
}
}

View File

@ -30,7 +30,7 @@
* @compile PermuteBound.java
*/
package test.tools.javac.generics.PermuteBound;
package PermuteBound;
class C<X, Y> {}

View File

@ -30,7 +30,7 @@
* @compile/fail PrimitiveVariant.java
*/
package test.tools.javac.generics.PrimitiveVariant;
package PrimitiveVariant;
interface I {
double m();

View File

@ -0,0 +1,40 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import java.util.Set;
@SupportedAnnotationTypes("*")
public class DummyProcessor extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
return true;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6511613
* @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified
*
* @build DummyProcessor
* @compile/fail clss41701.java
* @compile/fail -processor DummyProcessor clss41701.java
*/
import java.io.PrintStream;
interface clss41701i {
void run();
}
class clss41701a<A extends clss41701i,
B extends clss41701i,
C extends A&B> {
}

View File

@ -0,0 +1,186 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6449781
* @summary Test that reported names of anonymous classes are non-null.
* @author Joseph D. Darcy
* @build TestAnonSourceNames
* @compile/fail -processor TestAnonSourceNames TestAnonClassNames.java
* @build TestAnonClassNames
* @run main TestAnonClassNames
*/
/*
* This test operates in phases to test retrieving the qualified name
* of anonymous classes from type elements modeling the anonymous
* class. The type elements are generated using both source files and
* class files as the basis of constructing the elements.
*
* Source files will be tested by the @compile line which runs
* TestAnonSourceNames as an annotation processor over this file.
* This compile line is expected to fail until 6930507 is fixed. Once
* bug 6930507 is fixed, the "@compile/fail -processor ..." and
* following "@build..." steps can be replaced with a single "@compile
* -processor ..." directive.
*
* Class files are tested by the @run command on this type. This
* class gets the names of classes with different nesting kinds,
* including anonymous classes, and then invokes the compiler with an
* annotation processor having the class files names as inputs. The
* compiler is invoked via the javax.tools mechanism.
*/
import java.lang.annotation.*;
import javax.lang.model.element.*;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
import javax.tools.*;
import java.util.*;
import static java.lang.annotation.RetentionPolicy.*;
import static javax.lang.model.element.NestingKind.*;
import static javax.lang.model.util.ElementFilter.*;
import static javax.tools.Diagnostic.Kind.*;
import static javax.tools.StandardLocation.*;
@Nesting(TOP_LEVEL)
public class TestAnonClassNames {
@Nesting(MEMBER)
static class MemberClass1{}
@Nesting(MEMBER)
class MemberClass2{}
@Nesting(MEMBER)
class Win$$AtVegas { } // Class with funny name.
public static void main(String... argv) {
@Nesting(LOCAL)
class LocalClass{};
Object o = new @Nesting(ANONYMOUS) Object() { // An anonymous annotated class
public String toString() {
return "I have no name!";
}
};
Class<?>[] classes = {
MemberClass1.class,
MemberClass2.class,
LocalClass.class,
Win$$AtVegas.class,
o.getClass(),
TestAnonClassNames.class,
};
for(Class<?> clazz : classes) {
String name = clazz.getName();
System.out.format("%s is %s%n",
clazz.getName(),
clazz.getAnnotation(Nesting.class).value());
testClassName(name);
}
}
/**
* Perform annotation processing on the class file name and verify
* the existence of different flavors of class names when the
* input classes are modeled as elements.
*/
static void testClassName(String className) {
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
List<String> classNames = new ArrayList<>();
classNames.add(className);
List<String> options = new ArrayList<>();
options.add("-proc:only");
options.add("-classpath");
options.add(System.getProperty("test.classes"));
JavaCompiler.CompilationTask compileTask =
javaCompiler.getTask(null, // Output
null, // File manager
null, // Diagnostics
options,
classNames,
null); // Sources
List<Processor> processors = new ArrayList<>();
processors.add(new ClassNameProber());
compileTask.setProcessors(processors);
Boolean goodResult = compileTask.call();
if (!goodResult) {
throw new RuntimeException("Errors found during compile.");
}
}
}
@Retention(RUNTIME)
@interface Nesting {
NestingKind value();
}
/**
* Probe at the various kinds of names of a type element.
*/
@SupportedAnnotationTypes("*")
class ClassNameProber extends AbstractProcessor {
public ClassNameProber(){super();}
private boolean classesFound=false;
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
if (!roundEnv.processingOver()) {
for(TypeElement typeElt : typesIn(roundEnv.getRootElements())) {
classesFound = true;
// Verify different names are non-null; an NPE will
// result in failed compile status being reported.
NestingKind nestingKind = typeElt.getNestingKind();
System.out.printf("\tSimple name: ''%s''\tQualified Name: ''%s''\tKind ''%s''\tNesting ''%s''%n",
typeElt.getSimpleName().toString(),
typeElt.getQualifiedName().toString(),
typeElt.getKind().toString(),
nestingKind.toString());
if (typeElt.getAnnotation(Nesting.class).value() != nestingKind) {
throw new RuntimeException("Mismatch of expected and reported nesting kind.");
}
}
}
if (!classesFound) {
throw new RuntimeException("Error: no classes processed.");
}
return true;
}
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.io.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
import java.util.*;
import com.sun.source.tree.*;
import com.sun.source.util.*;
import static javax.tools.Diagnostic.Kind.*;
/**
* Using the tree API, retrieve element representations of anonymous
* classes and verify their names are as specified.
*/
@SupportedAnnotationTypes("*")
public class TestAnonSourceNames extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
if (!roundEnv.processingOver()) {
Trees trees = Trees.instance(processingEnv);
for(Element rootElement : roundEnv.getRootElements()) {
TreePath treePath = trees.getPath(rootElement);
(new ClassTreeScanner(trees)).
scan(trees.getTree(rootElement),
treePath.getCompilationUnit());
}
}
return true;
}
class ClassTreeScanner extends TreeScanner<Void, CompilationUnitTree> {
private Trees trees;
public ClassTreeScanner(Trees trees) {
super();
this.trees = trees;
}
@Override
public Void visitClass(ClassTree node, CompilationUnitTree cu) {
Element element = trees.getElement(trees.getPath(cu, node));
if (element == null) {
processingEnv.getMessager().printMessage(ERROR,
"No element retreived for node named ''" +
node.getSimpleName() + "''.");
} else {
System.out.println("\nVisiting class ``" + element.getSimpleName() +
"'' of kind " + element.getKind());
if (element instanceof TypeElement) {
TypeElement typeElement = (TypeElement) element;
String s = typeElement.getQualifiedName().toString();
System.out.println("\tqualified name:" + s);
} else {
throw new RuntimeException("TypeElement not gotten from ClassTree.");
}
}
return super.visitClass(node, cu);
}
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* This file is not a regular test, but is processed by ./TreePosTest.java,
* which verifies the position info in the javac tree.
* To run the test standalone, compile TreePosTest, then run TreePosTest
* on this file.
* @bug 6931927
* @summary position issues with synthesized anonymous class
*/
class TestAnnotatedAnonClass {
void m() {
Object o = new @Deprecated Object() { };
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6893943
* @summary exit code from javah with no args is 0
*/
import java.io.*;
import java.util.*;
public class T6893943 {
public static void main(String... args) throws Exception {
new T6893943().run();
}
void run() throws Exception {
testSimpleAPI();
testCommand();
}
void testSimpleAPI() throws Exception {
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.err));
int rc = com.sun.tools.javah.Main.run(new String[] { }, pw);
expect("testSimpleAPI", rc, 1);
}
void testCommand() throws Exception {
File javaHome = new File(System.getProperty("java.home"));
if (javaHome.getName().equals("jre"))
javaHome = javaHome.getParentFile();
List<String> command = new ArrayList<String>();
command.add(new File(new File(javaHome, "bin"), "javah").getPath());
command.add("-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"));
//System.err.println("command: " + command);
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process p = pb.start();
p.getOutputStream().close();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null)
System.err.println("javah: " + line);
int rc = p.waitFor();
expect("testCommand", rc, 1);
}
void expect(String name, int actual, int expect) throws Exception {
if (actual != expect)
throw new Exception(name + ": unexpected exit: " + actual + ", expected: " + expect);
}
}