mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 12:04:39 +02:00
Merge
This commit is contained in:
commit
ae572de526
198 changed files with 8507 additions and 102 deletions
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2006-2009 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
|
||||
|
@ -44,7 +44,27 @@ if [ "$LANGTOOLS_USE_BOOTCLASSPATH" != "no" ]; then
|
|||
bcp="$mylib/#PROGRAM#.jar":$cp
|
||||
fi
|
||||
|
||||
# javac currently assumes that assertions are enabled in the launcher
|
||||
# tools currently assumes that assertions are enabled in the launcher
|
||||
ea=-ea:com.sun.tools
|
||||
|
||||
"#TARGET_JAVA#" ${bcp:+-Xbootclasspath/p:"$bcp"} ${ea} -jar "${mydir}"/../lib/#PROGRAM#.jar "$@"
|
||||
# Any parameters starting with -J are passed to the JVM.
|
||||
# All other parameters become parameters of #PROGRAM#.
|
||||
|
||||
# Separate out -J* options for the JVM
|
||||
# Note jdk as possible default to run jtreg
|
||||
# Unset IFS and use newline as arg separator to preserve spaces in args
|
||||
DUALCASE=1 # for MKS: make case statement case-sensitive (6709498)
|
||||
saveIFS="$IFS"
|
||||
nl='
|
||||
'
|
||||
for i in "$@" ; do
|
||||
IFS=
|
||||
case $i in
|
||||
-J* ) javaOpts=$javaOpts$nl`echo $i | sed -e 's/^-J//'` ;;
|
||||
* ) toolOpts=$toolOpts$nl$i ;;
|
||||
esac
|
||||
IFS="$saveIFS"
|
||||
done
|
||||
unset DUALCASE
|
||||
|
||||
eval "#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mydir}"/../lib/#PROGRAM#.jar ${toolOpts}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2008-2009 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.source.tree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A tree node for an annotated type
|
||||
*
|
||||
* For example:
|
||||
* <pre>
|
||||
* {@code @}<em>annotationType String</em>
|
||||
* {@code @}<em>annotationType</em> ( <em>arguments</em> ) <em>Date</em>
|
||||
* </pre>
|
||||
*
|
||||
* @see "JSR 308: Annotations on Java Types"
|
||||
*
|
||||
* @author Mahmood Ali
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface AnnotatedTypeTree extends ExpressionTree {
|
||||
List<? extends AnnotationTree> getAnnotations();
|
||||
ExpressionTree getUnderlyingType();
|
||||
}
|
|
@ -53,6 +53,7 @@ public interface MethodTree extends Tree {
|
|||
Tree getReturnType();
|
||||
List<? extends TypeParameterTree> getTypeParameters();
|
||||
List<? extends VariableTree> getParameters();
|
||||
List<? extends AnnotationTree> getReceiverAnnotations();
|
||||
List<? extends ExpressionTree> getThrows();
|
||||
BlockTree getBody();
|
||||
Tree getDefaultValue(); // for annotation types
|
||||
|
|
|
@ -45,6 +45,9 @@ public interface Tree {
|
|||
* Enumerates all kinds of trees.
|
||||
*/
|
||||
public enum Kind {
|
||||
|
||||
ANNOTATED_TYPE(AnnotatedTypeTree.class),
|
||||
|
||||
/**
|
||||
* Used for instances of {@link AnnotationTree}.
|
||||
*/
|
||||
|
|
|
@ -57,6 +57,7 @@ package com.sun.source.tree;
|
|||
* @since 1.6
|
||||
*/
|
||||
public interface TreeVisitor<R,P> {
|
||||
R visitAnnotatedType(AnnotatedTypeTree node, P p);
|
||||
R visitAnnotation(AnnotationTree node, P p);
|
||||
R visitMethodInvocation(MethodInvocationTree node, P p);
|
||||
R visitAssert(AssertTree node, P p);
|
||||
|
|
|
@ -47,4 +47,5 @@ import javax.lang.model.element.Name;
|
|||
public interface TypeParameterTree extends Tree {
|
||||
Name getName();
|
||||
List<? extends Tree> getBounds();
|
||||
List<? extends AnnotationTree> getAnnotations();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright 2009 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.source.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
|
||||
import com.sun.source.tree.ClassTree;
|
||||
|
||||
/**
|
||||
* This class is an abstract annotation processor designed to be a
|
||||
* convenient superclass for concrete "type processors", processors that
|
||||
* require the type information in the processed source.
|
||||
*
|
||||
* <p>Type processing occurs in one round after the tool (e.g. java compiler)
|
||||
* analyzes the source (all sources taken as input to the tool and sources
|
||||
* generated by other annotation processors).
|
||||
*
|
||||
* <p>The tool infrastructure will interact with classes extending this abstract
|
||||
* class as follows:
|
||||
*
|
||||
* <ol>
|
||||
* [1-3: Identical to {@link Processor} life cycle]
|
||||
*
|
||||
* <li>If an existing {@code Processor} object is not being used, to
|
||||
* create an instance of a processor the tool calls the no-arg
|
||||
* constructor of the processor class.
|
||||
*
|
||||
* <li>Next, the tool calls the {@link #init init} method with
|
||||
* an appropriate {@code ProcessingEnvironment}.
|
||||
*
|
||||
* <li>Afterwards, the tool calls {@link #getSupportedAnnotationTypes
|
||||
* getSupportedAnnotationTypes}, {@link #getSupportedOptions
|
||||
* getSupportedOptions}, and {@link #getSupportedSourceVersion
|
||||
* getSupportedSourceVersion}. These methods are only called once per
|
||||
* run, not on each round.
|
||||
*
|
||||
* [4-5Unique to {@code AbstractTypeProcessor} subclasses]
|
||||
*
|
||||
* <li>For each class containing a supported annotation, the tool calls
|
||||
* {@link #typeProcess(TypeElement, TreePath) typeProcess} method on the
|
||||
* {@code Processor}. The class is guaranteed to be type-checked Java code
|
||||
* and all the tree type and symbol information is resolved.
|
||||
*
|
||||
* <li>Finally, the tools calls the
|
||||
* {@link #typeProcessingOver() typeProcessingOver} method
|
||||
* on the {@code Processor}.
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <p>The tool is permitted to ask type processors to process a class once
|
||||
* it is analyzed before the rest of classes are analyzed. The tool is also
|
||||
* permitted to stop type processing immediately if any errors are raised,
|
||||
* without invoking {@code typeProcessingOver}
|
||||
*
|
||||
* <p>A subclass may override any of the methods in this class, as long as the
|
||||
* general {@link javax.annotation.processing.Processor Processor}
|
||||
* contract is obeyed, with one notable exception.
|
||||
* {@link #process(Set, RoundEnvironment)} may not be overridden, as it
|
||||
* is called during the regular annotation phase before classes are analyzed.
|
||||
*
|
||||
* @author Mahmood Ali
|
||||
* @since 1.7
|
||||
*/
|
||||
public abstract class AbstractTypeProcessor extends AbstractProcessor {
|
||||
private final Set<Name> elements = new HashSet<Name>();
|
||||
private boolean hasInvokedTypeProcessingOver = false;
|
||||
private JavacProcessingEnvironment env;
|
||||
private final AttributionTaskListener listener = new AttributionTaskListener();
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
protected AbstractTypeProcessor() { }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void init(ProcessingEnvironment env) {
|
||||
super.init(env);
|
||||
this.env = (JavacProcessingEnvironment)env;
|
||||
prepareContext(this.env.getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of this method is obsolete in type processors. The method is
|
||||
* called during regular annotation processing phase only.
|
||||
*/
|
||||
@Override
|
||||
public final boolean process(Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundEnv) {
|
||||
for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) {
|
||||
elements.add(elem.getQualifiedName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a fully analyzed class that contains a supported annotation
|
||||
* (look {@link #getSupportedAnnotationTypes()}).
|
||||
*
|
||||
* <p>The passed class is always a valid type-checked Java code.
|
||||
*
|
||||
* @param element element of the analyzed class
|
||||
* @param tree the tree path to the element, with the leaf being a
|
||||
* {@link ClassTree}
|
||||
*/
|
||||
public abstract void typeProcess(TypeElement element, TreePath tree);
|
||||
|
||||
/**
|
||||
* A method to be called once all the classes are processed and no error
|
||||
* is reported.
|
||||
*
|
||||
* <p>Subclasses may override this method to do any aggregate analysis
|
||||
* (e.g. generate report, persistence) or resource deallocation.
|
||||
*
|
||||
* <p>If an error (a Java error or a processor error) is reported, this
|
||||
* method is not guaranteed to be invoked.
|
||||
*/
|
||||
public void typeProcessingOver() { }
|
||||
|
||||
/**
|
||||
* adds a listener for attribution.
|
||||
*/
|
||||
private void prepareContext(Context context) {
|
||||
TaskListener otherListener = context.get(TaskListener.class);
|
||||
if (otherListener == null) {
|
||||
context.put(TaskListener.class, listener);
|
||||
} else {
|
||||
// handle cases of multiple listeners
|
||||
context.put(TaskListener.class, (TaskListener)null);
|
||||
TaskListeners listeners = new TaskListeners();
|
||||
listeners.add(otherListener);
|
||||
listeners.add(listener);
|
||||
context.put(TaskListener.class, listeners);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A task listener that invokes the processor whenever a class is fully
|
||||
* analyzed.
|
||||
*/
|
||||
private final class AttributionTaskListener implements TaskListener {
|
||||
|
||||
@Override
|
||||
public void finished(TaskEvent e) {
|
||||
Log log = Log.instance(env.getContext());
|
||||
|
||||
if (!hasInvokedTypeProcessingOver && elements.isEmpty() && log.nerrors == 0) {
|
||||
typeProcessingOver();
|
||||
hasInvokedTypeProcessingOver = true;
|
||||
}
|
||||
|
||||
if (e.getKind() != TaskEvent.Kind.ANALYZE)
|
||||
return;
|
||||
|
||||
if (e.getTypeElement() == null)
|
||||
throw new AssertionError("event task without a type element");
|
||||
if (e.getCompilationUnit() == null)
|
||||
throw new AssertionError("even task without compilation unit");
|
||||
|
||||
if (!elements.remove(e.getTypeElement().getQualifiedName()))
|
||||
return;
|
||||
|
||||
if (log.nerrors != 0)
|
||||
return;
|
||||
|
||||
TypeElement elem = e.getTypeElement();
|
||||
TreePath p = Trees.instance(env).getPath(elem);
|
||||
|
||||
typeProcess(elem, p);
|
||||
|
||||
if (!hasInvokedTypeProcessingOver && elements.isEmpty() && log.nerrors == 0) {
|
||||
typeProcessingOver();
|
||||
hasInvokedTypeProcessingOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void started(TaskEvent e) { }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A task listener multiplexer.
|
||||
*/
|
||||
private static class TaskListeners implements TaskListener {
|
||||
private final List<TaskListener> listeners = new ArrayList<TaskListener>();
|
||||
|
||||
public void add(TaskListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void remove(TaskListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished(TaskEvent e) {
|
||||
for (TaskListener listener : listeners)
|
||||
listener.finished(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void started(TaskEvent e) {
|
||||
for (TaskListener listener : listeners)
|
||||
listener.started(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -244,6 +244,10 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
|
|||
return defaultAction(node, p);
|
||||
}
|
||||
|
||||
public R visitAnnotatedType(AnnotatedTypeTree node, P p) {
|
||||
return defaultAction(node, p);
|
||||
}
|
||||
|
||||
public R visitErroneous(ErroneousTree node, P p) {
|
||||
return defaultAction(node, p);
|
||||
}
|
||||
|
|
|
@ -120,19 +120,20 @@ public class TreePath implements Iterable<Tree> {
|
|||
public Iterator<Tree> iterator() {
|
||||
return new Iterator<Tree>() {
|
||||
public boolean hasNext() {
|
||||
return curr.parent != null;
|
||||
return next != null;
|
||||
}
|
||||
|
||||
public Tree next() {
|
||||
curr = curr.parent;
|
||||
return curr.leaf;
|
||||
Tree t = next.leaf;
|
||||
next = next.parent;
|
||||
return t;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private TreePath curr;
|
||||
private TreePath next = TreePath.this;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
|||
r = scanAndReduce(node.getReturnType(), p, r);
|
||||
r = scanAndReduce(node.getTypeParameters(), p, r);
|
||||
r = scanAndReduce(node.getParameters(), p, r);
|
||||
r = scanAndReduce(node.getReceiverAnnotations(), p, r);
|
||||
r = scanAndReduce(node.getThrows(), p, r);
|
||||
r = scanAndReduce(node.getBody(), p, r);
|
||||
return r;
|
||||
|
@ -354,7 +355,9 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
|||
}
|
||||
|
||||
public R visitTypeParameter(TypeParameterTree node, P p) {
|
||||
return scan(node.getBounds(), p);
|
||||
R r = scan(node.getAnnotations(), p);
|
||||
r = scanAndReduce(node.getBounds(), p, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public R visitWildcard(WildcardTree node, P p) {
|
||||
|
@ -371,6 +374,12 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
|||
return r;
|
||||
}
|
||||
|
||||
public R visitAnnotatedType(AnnotatedTypeTree node, P p) {
|
||||
R r = scan(node.getAnnotations(), p);
|
||||
r = scanAndReduce(node.getUnderlyingType(), p, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public R visitOther(Tree node, P p) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import javax.lang.model.element.TypeElement;
|
|||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.ErrorType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
|
||||
import com.sun.source.tree.ClassTree;
|
||||
|
@ -182,7 +183,20 @@ public abstract class Trees {
|
|||
/**
|
||||
* Gets the original type from the ErrorType object.
|
||||
* @param errorType The errorType for which we want to get the original type.
|
||||
* @returns javax.lang.model.type.TypeMirror corresponding to the original type, replaced by the ErrorType.
|
||||
* @return javax.lang.model.type.TypeMirror corresponding to the original type, replaced by the ErrorType.
|
||||
*/
|
||||
public abstract TypeMirror getOriginalType(ErrorType errorType);
|
||||
|
||||
/**
|
||||
* Prints a message of the specified kind at the location of the
|
||||
* tree within the provided compilation unit
|
||||
*
|
||||
* @param kind the kind of message
|
||||
* @param msg the message, or an empty string if none
|
||||
* @param t the tree to use as a position hint
|
||||
* @param root the compilation unit that contains tree
|
||||
*/
|
||||
public abstract void printMessage(Diagnostic.Kind kind, CharSequence msg,
|
||||
com.sun.source.tree.Tree t,
|
||||
com.sun.source.tree.CompilationUnitTree root);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ public abstract class Attribute {
|
|||
public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
|
||||
public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
|
||||
public static final String RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations";
|
||||
public static final String RuntimeVisibleTypeAnnotations = "RuntimeVisibleTypeAnnotations";
|
||||
public static final String RuntimeInvisibleTypeAnnotations = "RuntimeInvisibleTypeAnnotations";
|
||||
public static final String Signature = "Signature";
|
||||
public static final String SourceDebugExtension = "SourceDebugExtension";
|
||||
public static final String SourceFile = "SourceFile";
|
||||
|
@ -131,6 +133,8 @@ public abstract class Attribute {
|
|||
standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeVisibleTypeAnnotations, RuntimeVisibleTypeAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeInvisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations_attribute.class);
|
||||
standardAttributes.put(Signature, Signature_attribute.class);
|
||||
standardAttributes.put(SourceID, SourceID_attribute.class);
|
||||
}
|
||||
|
@ -184,6 +188,8 @@ public abstract class Attribute {
|
|||
R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
|
||||
R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
|
||||
R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p);
|
||||
R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p);
|
||||
R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p);
|
||||
R visitSignature(Signature_attribute attr, P p);
|
||||
R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p);
|
||||
R visitSourceFile(SourceFile_attribute attr, P p);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
@ -477,6 +478,16 @@ public class ClassWriter {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
|
||||
annotationWriter.write(attr.annotations, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
|
||||
annotationWriter.write(attr.annotations, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
|
||||
out.writeByte(attr.parameter_annotations.length);
|
||||
for (Annotation[] annos: attr.parameter_annotations)
|
||||
|
@ -636,6 +647,12 @@ public class ClassWriter {
|
|||
write(anno, out);
|
||||
}
|
||||
|
||||
public void write(ExtendedAnnotation[] annos, ClassOutputStream out) {
|
||||
out.writeShort(annos.length);
|
||||
for (ExtendedAnnotation anno: annos)
|
||||
write(anno, out);
|
||||
}
|
||||
|
||||
public void write(Annotation anno, ClassOutputStream out) {
|
||||
out.writeShort(anno.type_index);
|
||||
out.writeShort(anno.element_value_pairs.length);
|
||||
|
@ -643,6 +660,11 @@ public class ClassWriter {
|
|||
write(p, out);
|
||||
}
|
||||
|
||||
public void write(ExtendedAnnotation anno, ClassOutputStream out) {
|
||||
write(anno.annotation, out);
|
||||
write(anno.position, out);
|
||||
}
|
||||
|
||||
public void write(element_value_pair pair, ClassOutputStream out) {
|
||||
out.writeShort(pair.element_name_index);
|
||||
write(pair.value, out);
|
||||
|
@ -680,5 +702,95 @@ public class ClassWriter {
|
|||
write(v, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void write(ExtendedAnnotation.Position p, ClassOutputStream out) {
|
||||
out.writeByte(p.type.targetTypeValue());
|
||||
switch (p.type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
out.writeShort(p.offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
int table_length = p.lvarOffset.length;
|
||||
out.writeShort(table_length);
|
||||
for (int i = 0; i < table_length; ++i) {
|
||||
out.writeShort(1); // for table length
|
||||
out.writeShort(p.lvarOffset[i]);
|
||||
out.writeShort(p.lvarLength[i]);
|
||||
out.writeShort(p.lvarIndex[i]);
|
||||
}
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
out.writeByte(p.parameter_index);
|
||||
break;
|
||||
// type parameters bounds
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
out.writeByte(p.parameter_index);
|
||||
out.writeByte(p.bound_index);
|
||||
break;
|
||||
// wildcards
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
write(p.wildcard_position, out);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
out.writeByte(p.type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
out.writeByte(p.type_index);
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
out.writeShort(p.offset);
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
out.writeByte(p.parameter_index);
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
out.writeShort(p.offset);
|
||||
out.writeByte(p.type_index);
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("unknown type: " + p);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (p.type.hasLocation()) {
|
||||
out.writeShort(p.location.size());
|
||||
for (int i : p.location)
|
||||
out.writeByte((byte)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,614 @@
|
|||
/*
|
||||
* Copyright 2009 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.sun.tools.classfile.ExtendedAnnotation.TargetAttribute.*;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, section 4.1
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ExtendedAnnotation {
|
||||
ExtendedAnnotation(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
|
||||
annotation = new Annotation(cr);
|
||||
position = read_position(cr);
|
||||
}
|
||||
|
||||
public ExtendedAnnotation(ConstantPool constant_pool,
|
||||
Annotation annotation, Position position) {
|
||||
this.annotation = annotation;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int n = annotation.length();
|
||||
n += position_length(position);
|
||||
return n;
|
||||
}
|
||||
|
||||
public final Annotation annotation;
|
||||
public final Position position;
|
||||
|
||||
private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
|
||||
// Copied from ClassReader
|
||||
int tag = (byte)cr.readUnsignedByte(); // cast to introduce signedness
|
||||
if (!TargetType.isValidTargetTypeValue(tag))
|
||||
throw new Annotation.InvalidAnnotation("invalid type annotation target type value: " + tag);
|
||||
|
||||
TargetType type = TargetType.fromTargetTypeValue(tag);
|
||||
|
||||
Position position = new Position();
|
||||
position.type = type;
|
||||
|
||||
switch (type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
position.offset = cr.readUnsignedShort();
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
int table_length = cr.readUnsignedShort();
|
||||
position.lvarOffset = new int[table_length];
|
||||
position.lvarLength = new int[table_length];
|
||||
position.lvarIndex = new int[table_length];
|
||||
for (int i = 0; i < table_length; ++i) {
|
||||
position.lvarOffset[i] = cr.readUnsignedShort();
|
||||
position.lvarLength[i] = cr.readUnsignedShort();
|
||||
position.lvarIndex[i] = cr.readUnsignedShort();
|
||||
}
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// type parameter bounds
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
position.bound_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// wildcards
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
position.wildcard_position = read_position(cr);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
position.type_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
position.type_index = cr.readUnsignedByte();
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
case CLASS_LITERAL_GENERIC_OR_ARRAY:
|
||||
position.offset = cr.readUnsignedShort();
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
position.offset = cr.readUnsignedShort();
|
||||
position.type_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Cannot be here");
|
||||
}
|
||||
|
||||
if (type.hasLocation()) {
|
||||
int len = cr.readUnsignedShort();
|
||||
List<Integer> loc = new ArrayList<Integer>(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
loc.add(cr.readUnsignedByte());
|
||||
position.location = loc;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
private static int position_length(Position pos) {
|
||||
int n = 0;
|
||||
n += 1; // target_type
|
||||
switch (pos.type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
n += 2;
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
n += 2; // table_length;
|
||||
int table_length = pos.lvarOffset.length;
|
||||
n += 2 * table_length; // offset
|
||||
n += 2 * table_length; // length;
|
||||
n += 2 * table_length; // index
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
n += 1; // parameter_index;
|
||||
break;
|
||||
// type parameter bounds
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
n += 1; // parameter_index
|
||||
n += 1; // bound_index
|
||||
break;
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
n += position_length(pos.wildcard_position);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
n += 1; // type_index
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
n += 1; // type_index
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
case CLASS_LITERAL_GENERIC_OR_ARRAY:
|
||||
n += 1; // offset
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
n += 1; // parameter_index
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
n += 2; // offset
|
||||
n += 1; // type index
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if (pos.type.hasLocation()) {
|
||||
n += 2; // length
|
||||
n += 1 * pos.location.size(); // actual array size
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// Code duplicated from com.sun.tools.javac.code.TypeAnnotations.Position
|
||||
public static class Position {
|
||||
|
||||
public TargetType type = TargetType.UNKNOWN;
|
||||
|
||||
// For generic/array types.
|
||||
public List<Integer> location = new ArrayList<Integer>();
|
||||
|
||||
// Tree position.
|
||||
public int pos = -1;
|
||||
|
||||
// For typecasts, type tests, new (and locals, as start_pc).
|
||||
public int offset = -1;
|
||||
|
||||
// For locals.
|
||||
public int[] lvarOffset = new int[] { -1 };
|
||||
public int[] lvarLength = new int[] { -1 };
|
||||
public int[] lvarIndex = new int[] { -1 };
|
||||
|
||||
// For type parameter bound
|
||||
public int bound_index = -1;
|
||||
|
||||
// For type parameter and method parameter
|
||||
public int parameter_index = -1;
|
||||
|
||||
// For class extends, implements, and throws classes
|
||||
public int type_index = -2;
|
||||
|
||||
// For wildcards
|
||||
public Position wildcard_position = null;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('[');
|
||||
sb.append(type);
|
||||
|
||||
switch (type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
sb.append(", {");
|
||||
for (int i = 0; i < lvarOffset.length; ++i) {
|
||||
if (i != 0) sb.append("; ");
|
||||
sb.append(", start_pc = ");
|
||||
sb.append(lvarOffset[i]);
|
||||
sb.append(", length = ");
|
||||
sb.append(lvarLength[i]);
|
||||
sb.append(", index = ");
|
||||
sb.append(lvarIndex[i]);
|
||||
}
|
||||
sb.append("}");
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// type parameters bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
sb.append(", bound_index = ");
|
||||
sb.append(bound_index);
|
||||
break;
|
||||
// wildcard
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
sb.append(", wild_card = ");
|
||||
sb.append(wildcard_position);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("unknown type: " + type);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (type.hasLocation()) {
|
||||
sb.append(", location = (");
|
||||
sb.append(location);
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
sb.append(", pos = ");
|
||||
sb.append(pos);
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// Code duplicated from com.sun.tools.javac.comp.TargetType
|
||||
public enum TargetType {
|
||||
|
||||
/** For annotations on typecasts. */
|
||||
TYPECAST(0x00),
|
||||
|
||||
/** For annotations on a type argument or nested array of a typecast. */
|
||||
TYPECAST_GENERIC_OR_ARRAY(0x01, HasLocation),
|
||||
|
||||
/** For annotations on type tests. */
|
||||
INSTANCEOF(0x02),
|
||||
|
||||
/** For annotations on a type argument or nested array of a type test. */
|
||||
INSTANCEOF_GENERIC_OR_ARRAY(0x03, HasLocation),
|
||||
|
||||
/** For annotations on object creation expressions. */
|
||||
NEW(0x04),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of an object creation
|
||||
* expression.
|
||||
*/
|
||||
NEW_GENERIC_OR_ARRAY(0x05, HasLocation),
|
||||
|
||||
|
||||
/** For annotations on the method receiver. */
|
||||
METHOD_RECEIVER(0x06),
|
||||
|
||||
// invalid location
|
||||
// METHOD_RECEIVER_GENERIC_OR_ARRAY(0x07, HasLocation),
|
||||
|
||||
/** For annotations on local variables. */
|
||||
LOCAL_VARIABLE(0x08),
|
||||
|
||||
/** For annotations on a type argument or nested array of a local. */
|
||||
LOCAL_VARIABLE_GENERIC_OR_ARRAY(0x09, HasLocation),
|
||||
|
||||
// already handled by regular annotations
|
||||
// METHOD_RETURN(0x0A),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of a method return
|
||||
* type.
|
||||
*/
|
||||
METHOD_RETURN_GENERIC_OR_ARRAY(0x0B, HasLocation),
|
||||
|
||||
// already handled by regular annotations
|
||||
// METHOD_PARAMETER(0x0C),
|
||||
|
||||
/** For annotations on a type argument or nested array of a method parameter. */
|
||||
METHOD_PARAMETER_GENERIC_OR_ARRAY(0x0D, HasLocation),
|
||||
|
||||
// already handled by regular annotations
|
||||
// FIELD(0x0E),
|
||||
|
||||
/** For annotations on a type argument or nested array of a field. */
|
||||
FIELD_GENERIC_OR_ARRAY(0x0F, HasLocation),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a class. */
|
||||
CLASS_TYPE_PARAMETER_BOUND(0x10, HasBound, HasParameter),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of a bound of a type
|
||||
* parameter of a class.
|
||||
*/
|
||||
CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x11, HasBound, HasLocation, HasParameter),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a method. */
|
||||
METHOD_TYPE_PARAMETER_BOUND(0x12, HasBound, HasParameter),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of a bound of a type
|
||||
* parameter of a method.
|
||||
*/
|
||||
METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x13, HasBound, HasLocation, HasParameter),
|
||||
|
||||
/** For annotations on the type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS(0x14),
|
||||
|
||||
/** For annotations on the inner type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS_GENERIC_OR_ARRAY(0x15, HasLocation),
|
||||
|
||||
/** For annotations on a throws clause in a method declaration. */
|
||||
THROWS(0x16),
|
||||
|
||||
// invalid location
|
||||
// THROWS_GENERIC_OR_ARRAY(0x17, HasLocation),
|
||||
|
||||
/** For annotations in type arguments of object creation expressions. */
|
||||
NEW_TYPE_ARGUMENT(0x18),
|
||||
NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x19, HasLocation),
|
||||
|
||||
METHOD_TYPE_ARGUMENT(0x1A),
|
||||
METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x1B, HasLocation),
|
||||
|
||||
WILDCARD_BOUND(0x1C, HasBound),
|
||||
WILDCARD_BOUND_GENERIC_OR_ARRAY(0x1D, HasBound, HasLocation),
|
||||
|
||||
CLASS_LITERAL(0x1E),
|
||||
CLASS_LITERAL_GENERIC_OR_ARRAY(0x1F, HasLocation),
|
||||
|
||||
METHOD_TYPE_PARAMETER(0x20, HasParameter),
|
||||
|
||||
// invalid location
|
||||
// METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x21, HasLocation, HasParameter),
|
||||
|
||||
CLASS_TYPE_PARAMETER(0x22, HasParameter),
|
||||
|
||||
// invalid location
|
||||
// CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x23, HasLocation, HasParameter),
|
||||
|
||||
/** For annotations with an unknown target. */
|
||||
UNKNOWN(-1);
|
||||
|
||||
static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
|
||||
|
||||
private final int targetTypeValue;
|
||||
private Set<TargetAttribute> flags;
|
||||
|
||||
TargetType(int targetTypeValue, TargetAttribute... attrs) {
|
||||
if (targetTypeValue < Byte.MIN_VALUE
|
||||
|| targetTypeValue > Byte.MAX_VALUE)
|
||||
throw new AssertionError("attribute type value needs to be a byte: " + targetTypeValue);
|
||||
this.targetTypeValue = (byte)targetTypeValue;
|
||||
this.flags = EnumSet.noneOf(TargetAttribute.class);
|
||||
for (TargetAttribute attr : attrs)
|
||||
this.flags.add(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target is an inner type of a generic or array type.
|
||||
*
|
||||
* @return true if this TargetType represents an annotation on an inner
|
||||
* type, false otherwise
|
||||
*/
|
||||
public boolean hasLocation() {
|
||||
return flags.contains(HasLocation);
|
||||
}
|
||||
|
||||
public TargetType getGenericComplement() {
|
||||
if (hasLocation())
|
||||
return this;
|
||||
else
|
||||
return fromTargetTypeValue(targetTypeValue() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target has a parameter index.
|
||||
*
|
||||
* @return true if this TargetType has a parameter index,
|
||||
* false otherwise
|
||||
*/
|
||||
public boolean hasParameter() {
|
||||
return flags.contains(HasParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target is a type parameter bound.
|
||||
*
|
||||
* @return true if this TargetType represents an type parameter bound
|
||||
* annotation, false otherwise
|
||||
*/
|
||||
public boolean hasBound() {
|
||||
return flags.contains(HasBound);
|
||||
}
|
||||
|
||||
public int targetTypeValue() {
|
||||
return this.targetTypeValue;
|
||||
}
|
||||
|
||||
private static TargetType[] targets = null;
|
||||
|
||||
private static TargetType[] buildTargets() {
|
||||
TargetType[] targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
|
||||
TargetType[] alltargets = values();
|
||||
for (TargetType target : alltargets)
|
||||
if (target.targetTypeValue >= 0)
|
||||
targets[target.targetTypeValue] = target;
|
||||
for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i)
|
||||
if (targets[i] == null)
|
||||
targets[i] = UNKNOWN;
|
||||
return targets;
|
||||
}
|
||||
|
||||
public static boolean isValidTargetTypeValue(int tag) {
|
||||
if (targets == null)
|
||||
targets = buildTargets();
|
||||
|
||||
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
|
||||
return true;
|
||||
|
||||
return (tag >= 0 && tag < targets.length);
|
||||
}
|
||||
|
||||
public static TargetType fromTargetTypeValue(int tag) {
|
||||
if (targets == null)
|
||||
targets = buildTargets();
|
||||
|
||||
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
|
||||
return UNKNOWN;
|
||||
|
||||
if (tag < 0 || tag >= targets.length)
|
||||
throw new IllegalArgumentException("Unknown TargetType: " + tag);
|
||||
return targets[tag];
|
||||
}
|
||||
}
|
||||
|
||||
static enum TargetAttribute {
|
||||
HasLocation, HasParameter, HasBound;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, section 4.1
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RuntimeInvisibleTypeAnnotations_attribute extends RuntimeTypeAnnotations_attribute {
|
||||
RuntimeInvisibleTypeAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(cr, name_index, length);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleTypeAnnotations_attribute(ConstantPool cp, ExtendedAnnotation[] annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeInvisibleTypeAnnotations), annotations);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleTypeAnnotations_attribute(int name_index, ExtendedAnnotation[] annotations) {
|
||||
super(name_index, annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeInvisibleTypeAnnotations(this, p);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, section 4
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public abstract class RuntimeTypeAnnotations_attribute extends Attribute {
|
||||
protected RuntimeTypeAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(name_index, length);
|
||||
int num_annotations = cr.readUnsignedShort();
|
||||
annotations = new ExtendedAnnotation[num_annotations];
|
||||
for (int i = 0; i < annotations.length; i++)
|
||||
annotations[i] = new ExtendedAnnotation(cr);
|
||||
}
|
||||
|
||||
protected RuntimeTypeAnnotations_attribute(int name_index, ExtendedAnnotation[] annotations) {
|
||||
super(name_index, length(annotations));
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
private static int length(ExtendedAnnotation[] annos) {
|
||||
int n = 2;
|
||||
for (ExtendedAnnotation anno: annos)
|
||||
n += anno.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public final ExtendedAnnotation[] annotations;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, section 4.1
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RuntimeVisibleTypeAnnotations_attribute extends RuntimeTypeAnnotations_attribute {
|
||||
RuntimeVisibleTypeAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(cr, name_index, length);
|
||||
}
|
||||
|
||||
public RuntimeVisibleTypeAnnotations_attribute(ConstantPool cp, ExtendedAnnotation[] annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeVisibleTypeAnnotations), annotations);
|
||||
}
|
||||
|
||||
public RuntimeVisibleTypeAnnotations_attribute(int name_index, ExtendedAnnotation[] annotations) {
|
||||
super(name_index, annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeVisibleTypeAnnotations(this, p);
|
||||
}
|
||||
}
|
|
@ -133,6 +133,7 @@ public class JavacTaskImpl extends JavacTask {
|
|||
public Boolean call() {
|
||||
if (!used.getAndSet(true)) {
|
||||
beginContext();
|
||||
notYetEntered = new HashMap<JavaFileObject, JCCompilationUnit>();
|
||||
try {
|
||||
compilerMain.setFatalErrors(true);
|
||||
result = compilerMain.compile(args, context, fileObjects, processors);
|
||||
|
@ -143,6 +144,7 @@ public class JavacTaskImpl extends JavacTask {
|
|||
args = null;
|
||||
context = null;
|
||||
fileObjects = null;
|
||||
notYetEntered = null;
|
||||
return result == 0;
|
||||
} else {
|
||||
throw new IllegalStateException("multiple calls to method 'call'");
|
||||
|
|
|
@ -35,6 +35,7 @@ import javax.lang.model.element.ExecutableElement;
|
|||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
|
@ -54,6 +55,7 @@ import com.sun.tools.javac.comp.Env;
|
|||
import com.sun.tools.javac.comp.MemberEnter;
|
||||
import com.sun.tools.javac.comp.Resolve;
|
||||
import com.sun.tools.javac.model.JavacElements;
|
||||
import com.sun.tools.javac.processing.JavacMessager;
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
|
@ -61,6 +63,7 @@ import com.sun.tools.javac.tree.TreeCopier;
|
|||
import com.sun.tools.javac.tree.TreeInfo;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.JCDiagnostic;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Pair;
|
||||
|
@ -336,4 +339,54 @@ public class JavacTrees extends Trees {
|
|||
|
||||
return com.sun.tools.javac.code.Type.noType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message of the specified kind at the location of the
|
||||
* tree within the provided compilation unit
|
||||
*
|
||||
* @param kind the kind of message
|
||||
* @param msg the message, or an empty string if none
|
||||
* @param t the tree to use as a position hint
|
||||
* @param root the compilation unit that contains tree
|
||||
*/
|
||||
public void printMessage(Diagnostic.Kind kind, CharSequence msg,
|
||||
com.sun.source.tree.Tree t,
|
||||
com.sun.source.tree.CompilationUnitTree root) {
|
||||
JavaFileObject oldSource = null;
|
||||
JavaFileObject newSource = null;
|
||||
JCDiagnostic.DiagnosticPosition pos = null;
|
||||
|
||||
newSource = root.getSourceFile();
|
||||
if (newSource != null) {
|
||||
oldSource = log.useSource(newSource);
|
||||
pos = ((JCTree) t).pos();
|
||||
}
|
||||
|
||||
try {
|
||||
switch (kind) {
|
||||
case ERROR:
|
||||
boolean prev = log.multipleErrors;
|
||||
try {
|
||||
log.error(pos, "proc.messager", msg.toString());
|
||||
} finally {
|
||||
log.multipleErrors = prev;
|
||||
}
|
||||
break;
|
||||
|
||||
case WARNING:
|
||||
log.warning(pos, "proc.messager", msg.toString());
|
||||
break;
|
||||
|
||||
case MANDATORY_WARNING:
|
||||
log.mandatoryWarning(pos, "proc.messager", msg.toString());
|
||||
break;
|
||||
|
||||
default:
|
||||
log.note(pos, "proc.messager", msg.toString());
|
||||
}
|
||||
} finally {
|
||||
if (oldSource != null)
|
||||
log.useSource(oldSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,6 +204,21 @@ public abstract class Attribute implements AnnotationValue {
|
|||
}
|
||||
}
|
||||
|
||||
public static class TypeCompound extends Compound {
|
||||
public TypeAnnotationPosition position;
|
||||
public TypeCompound(Compound compound,
|
||||
TypeAnnotationPosition position) {
|
||||
this(compound.type, compound.values, position);
|
||||
}
|
||||
public TypeCompound(Type type,
|
||||
List<Pair<MethodSymbol, Attribute>> values,
|
||||
TypeAnnotationPosition position) {
|
||||
super(type, values);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** The value for an annotation element of an array type.
|
||||
*/
|
||||
public static class Array extends Attribute {
|
||||
|
|
|
@ -153,6 +153,9 @@ public enum Source {
|
|||
public boolean enforceMandatoryWarnings() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowTypeAnnotations() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public static SourceVersion toSourceVersion(Source source) {
|
||||
switch(source) {
|
||||
case JDK1_2:
|
||||
|
|
|
@ -100,6 +100,17 @@ public abstract class Symbol implements Element {
|
|||
*/
|
||||
public Type type;
|
||||
|
||||
/** The type annotations targeted to a tree directly owned by this symbol
|
||||
*/
|
||||
// type annotations are stored here for two purposes:
|
||||
// - convenient location to store annotations for generation after erasure
|
||||
// - a private interface for accessing type annotations parsed from
|
||||
// classfiles
|
||||
// the field is populated for the following declaration only
|
||||
// class, field, variable and type parameters
|
||||
//
|
||||
public List<Attribute.TypeCompound> typeAnnotations;
|
||||
|
||||
/** The owner of this symbol.
|
||||
*/
|
||||
public Symbol owner;
|
||||
|
@ -122,6 +133,7 @@ public abstract class Symbol implements Element {
|
|||
this.completer = null;
|
||||
this.erasure_field = null;
|
||||
this.attributes_field = List.nil();
|
||||
this.typeAnnotations = List.nil();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright 2008-2009 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import static com.sun.tools.javac.code.TargetType.TargetAttribute.*;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Describes the type of program element an extended annotation (or extended
|
||||
* compound attribute) targets.
|
||||
*
|
||||
* By comparison, a Tree.Kind has enum values for all elements in the AST, and
|
||||
* it does not provide enough resolution for type arguments (i.e., whether an
|
||||
* annotation targets a type argument in a local variable, method return type,
|
||||
* or a typecast).
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public enum TargetType {
|
||||
|
||||
//
|
||||
// Some target types are commented out, because Java doesn't permit such
|
||||
// targets. They are included here to confirm that their omission is
|
||||
// intentional omission not an accidental omission.
|
||||
//
|
||||
|
||||
/** For annotations on typecasts. */
|
||||
TYPECAST(0x00, IsLocal),
|
||||
|
||||
/** For annotations on a type argument or nested array of a typecast. */
|
||||
TYPECAST_GENERIC_OR_ARRAY(0x01, HasLocation, IsLocal),
|
||||
|
||||
/** For annotations on type tests. */
|
||||
INSTANCEOF(0x02, IsLocal),
|
||||
|
||||
/** For annotations on a type argument or nested array of a type test. */
|
||||
INSTANCEOF_GENERIC_OR_ARRAY(0x03, HasLocation, IsLocal),
|
||||
|
||||
/** For annotations on object creation expressions. */
|
||||
NEW(0x04, IsLocal),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of an object creation
|
||||
* expression.
|
||||
*/
|
||||
NEW_GENERIC_OR_ARRAY(0x05, HasLocation, IsLocal),
|
||||
|
||||
|
||||
/** For annotations on the method receiver. */
|
||||
METHOD_RECEIVER(0x06),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated METHOD_RECEIVER_GENERIC_OR_ARRAY(0x07, HasLocation),
|
||||
|
||||
/** For annotations on local variables. */
|
||||
LOCAL_VARIABLE(0x08, IsLocal),
|
||||
|
||||
/** For annotations on a type argument or nested array of a local. */
|
||||
LOCAL_VARIABLE_GENERIC_OR_ARRAY(0x09, HasLocation, IsLocal),
|
||||
|
||||
// handled by regular annotations
|
||||
//@Deprecated METHOD_RETURN(0x0A),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of a method return
|
||||
* type.
|
||||
*/
|
||||
METHOD_RETURN_GENERIC_OR_ARRAY(0x0B, HasLocation),
|
||||
|
||||
// handled by regular annotations
|
||||
//@Deprecated METHOD_PARAMETER(0x0C),
|
||||
|
||||
/** For annotations on a type argument or nested array of a method parameter. */
|
||||
METHOD_PARAMETER_GENERIC_OR_ARRAY(0x0D, HasLocation),
|
||||
|
||||
// handled by regular annotations
|
||||
//@Deprecated FIELD(0x0E),
|
||||
|
||||
/** For annotations on a type argument or nested array of a field. */
|
||||
FIELD_GENERIC_OR_ARRAY(0x0F, HasLocation),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a class. */
|
||||
CLASS_TYPE_PARAMETER_BOUND(0x10, HasBound, HasParameter),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of a bound of a type
|
||||
* parameter of a class.
|
||||
*/
|
||||
CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x11, HasBound, HasLocation, HasParameter),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a method. */
|
||||
METHOD_TYPE_PARAMETER_BOUND(0x12, HasBound, HasParameter),
|
||||
|
||||
/**
|
||||
* For annotations on a type argument or nested array of a bound of a type
|
||||
* parameter of a method.
|
||||
*/
|
||||
METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x13, HasBound, HasLocation, HasParameter),
|
||||
|
||||
/** For annotations on the type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS(0x14),
|
||||
|
||||
/** For annotations on the inner type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS_GENERIC_OR_ARRAY(0x15, HasLocation),
|
||||
|
||||
/** For annotations on a throws clause in a method declaration. */
|
||||
THROWS(0x16),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated THROWS_GENERIC_OR_ARRAY(0x17, HasLocation),
|
||||
|
||||
/** For annotations in type arguments of object creation expressions. */
|
||||
NEW_TYPE_ARGUMENT(0x18, IsLocal),
|
||||
NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x19, HasLocation, IsLocal),
|
||||
|
||||
METHOD_TYPE_ARGUMENT(0x1A, IsLocal),
|
||||
METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x1B, HasLocation, IsLocal),
|
||||
|
||||
WILDCARD_BOUND(0x1C, HasBound),
|
||||
WILDCARD_BOUND_GENERIC_OR_ARRAY(0x1D, HasBound, HasLocation),
|
||||
|
||||
CLASS_LITERAL(0x1E, IsLocal),
|
||||
CLASS_LITERAL_GENERIC_OR_ARRAY(0x1F, HasLocation, IsLocal),
|
||||
|
||||
METHOD_TYPE_PARAMETER(0x20, HasParameter),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x21, HasLocation, HasParameter),
|
||||
|
||||
CLASS_TYPE_PARAMETER(0x22, HasParameter),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x23, HasLocation, HasParameter),
|
||||
|
||||
/** For annotations with an unknown target. */
|
||||
UNKNOWN(-1);
|
||||
|
||||
static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
|
||||
|
||||
private final int targetTypeValue;
|
||||
private Set<TargetAttribute> flags;
|
||||
|
||||
TargetType(int targetTypeValue, TargetAttribute... attributes) {
|
||||
if (targetTypeValue < Byte.MIN_VALUE
|
||||
|| targetTypeValue > Byte.MAX_VALUE)
|
||||
throw new AssertionError("attribute type value needs to be a byte: " + targetTypeValue);
|
||||
this.targetTypeValue = (byte)targetTypeValue;
|
||||
flags = EnumSet.noneOf(TargetAttribute.class);
|
||||
for (TargetAttribute attr : attributes)
|
||||
flags.add(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target is an inner type of a generic or array type.
|
||||
*
|
||||
* @return true if this TargetType represents an annotation on an inner
|
||||
* type, false otherwise
|
||||
*/
|
||||
public boolean hasLocation() {
|
||||
return flags.contains(HasLocation);
|
||||
}
|
||||
|
||||
public TargetType getGenericComplement() {
|
||||
if (hasLocation())
|
||||
return this;
|
||||
else
|
||||
return fromTargetTypeValue(targetTypeValue() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target has a parameter index.
|
||||
*
|
||||
* @return true if this TargetType has a parameter index,
|
||||
* false otherwise
|
||||
*/
|
||||
public boolean hasParameter() {
|
||||
return flags.contains(HasParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target is a type parameter bound.
|
||||
*
|
||||
* @return true if this TargetType represents an type parameter bound
|
||||
* annotation, false otherwise
|
||||
*/
|
||||
public boolean hasBound() {
|
||||
return flags.contains(HasBound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this TargetType represents an annotation whose
|
||||
* target is exclusively a tree in a method body
|
||||
*
|
||||
* Note: wildcard bound targets could target a local tree and a class
|
||||
* member declaration signature tree
|
||||
*/
|
||||
public boolean isLocal() {
|
||||
return flags.contains(IsLocal);
|
||||
}
|
||||
|
||||
public int targetTypeValue() {
|
||||
return this.targetTypeValue;
|
||||
}
|
||||
|
||||
private static TargetType[] targets = null;
|
||||
|
||||
private static TargetType[] buildTargets() {
|
||||
TargetType[] targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
|
||||
TargetType[] alltargets = values();
|
||||
for (TargetType target : alltargets) {
|
||||
if (target.targetTypeValue >= 0)
|
||||
targets[target.targetTypeValue] = target;
|
||||
}
|
||||
for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
|
||||
if (targets[i] == null)
|
||||
targets[i] = UNKNOWN;
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
public static boolean isValidTargetTypeValue(int tag) {
|
||||
if (targets == null)
|
||||
targets = buildTargets();
|
||||
|
||||
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
|
||||
return true;
|
||||
|
||||
return (tag >= 0 && tag < targets.length);
|
||||
}
|
||||
|
||||
public static TargetType fromTargetTypeValue(int tag) {
|
||||
if (targets == null)
|
||||
targets = buildTargets();
|
||||
|
||||
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
|
||||
return UNKNOWN;
|
||||
|
||||
if (tag < 0 || tag >= targets.length)
|
||||
throw new IllegalArgumentException("Unknown TargetType: " + tag);
|
||||
return targets[tag];
|
||||
}
|
||||
|
||||
static enum TargetAttribute {
|
||||
HasLocation, HasParameter, HasBound, IsLocal;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
/** A type annotation position.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class TypeAnnotationPosition {
|
||||
|
||||
public TargetType type = TargetType.UNKNOWN;
|
||||
|
||||
// For generic/array types.
|
||||
public List<Integer> location = List.nil();
|
||||
|
||||
// Tree position.
|
||||
public int pos = -1;
|
||||
|
||||
// For typecasts, type tests, new (and locals, as start_pc).
|
||||
public boolean isValidOffset = false;
|
||||
public int offset = -1;
|
||||
|
||||
// For locals. arrays same length
|
||||
public int[] lvarOffset = new int[] { -1 };
|
||||
public int[] lvarLength = new int[] { -1 };
|
||||
public int[] lvarIndex = new int[] { -1 };
|
||||
|
||||
// For type parameter bound
|
||||
public int bound_index = -1;
|
||||
|
||||
// For type parameter and method parameter
|
||||
public int parameter_index = -1;
|
||||
|
||||
// For class extends, implements, and throws classes
|
||||
public int type_index = -2;
|
||||
|
||||
// For wildcards
|
||||
public TypeAnnotationPosition wildcard_position = null;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('[');
|
||||
sb.append(type);
|
||||
|
||||
switch (type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
sb.append(", {");
|
||||
for (int i = 0; i < lvarOffset.length; ++i) {
|
||||
if (i != 0) sb.append("; ");
|
||||
sb.append(", start_pc = ");
|
||||
sb.append(lvarOffset[i]);
|
||||
sb.append(", length = ");
|
||||
sb.append(lvarLength[i]);
|
||||
sb.append(", index = ");
|
||||
sb.append(lvarIndex[i]);
|
||||
}
|
||||
sb.append("}");
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// type parameters bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
sb.append(", bound_index = ");
|
||||
sb.append(bound_index);
|
||||
break;
|
||||
// wildcard
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
sb.append(", wild_card = ");
|
||||
sb.append(wildcard_position);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
// throw new AssertionError("unknown type: " + type);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (type.hasLocation()) {
|
||||
sb.append(", location = (");
|
||||
sb.append(location);
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
sb.append(", pos = ");
|
||||
sb.append(pos);
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the target tree of the annotation has been optimized
|
||||
* away from classfile or not.
|
||||
* @return true if the target has not been optimized away
|
||||
*/
|
||||
public boolean emitToClassfile() {
|
||||
if (type == TargetType.WILDCARD_BOUND
|
||||
|| type == TargetType.WILDCARD_BOUND_GENERIC_OR_ARRAY)
|
||||
return wildcard_position.isValidOffset;
|
||||
else
|
||||
return !type.isLocal() || isValidOffset;
|
||||
}
|
||||
}
|
|
@ -700,7 +700,6 @@ public class Attr extends JCTree.Visitor {
|
|||
localEnv.info.scope.leave();
|
||||
result = tree.type = m.type;
|
||||
chk.validateAnnotations(tree.mods.annotations, m);
|
||||
|
||||
}
|
||||
finally {
|
||||
chk.setLint(prevLint);
|
||||
|
@ -2516,10 +2515,11 @@ public class Attr extends JCTree.Visitor {
|
|||
Type clazzOuter = clazztype.getEnclosingType();
|
||||
if (clazzOuter.tag == CLASS) {
|
||||
Type site;
|
||||
if (tree.clazz.getTag() == JCTree.IDENT) {
|
||||
JCExpression clazz = TreeInfo.typeIn(tree.clazz);
|
||||
if (clazz.getTag() == JCTree.IDENT) {
|
||||
site = env.enclClass.sym.type;
|
||||
} else if (tree.clazz.getTag() == JCTree.SELECT) {
|
||||
site = ((JCFieldAccess) tree.clazz).selected.type;
|
||||
} else if (clazz.getTag() == JCTree.SELECT) {
|
||||
site = ((JCFieldAccess) clazz).selected.type;
|
||||
} else throw new AssertionError(""+tree);
|
||||
if (clazzOuter.tag == CLASS && site != clazzOuter) {
|
||||
if (site.tag == CLASS)
|
||||
|
@ -2628,6 +2628,10 @@ public class Attr extends JCTree.Visitor {
|
|||
result = tree.type = syms.errType;
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
result = tree.type = attribType(tree.getUnderlyingType(), env);
|
||||
}
|
||||
|
||||
public void visitErroneous(JCErroneous tree) {
|
||||
if (tree.errs != null)
|
||||
for (JCTree err : tree.errs)
|
||||
|
@ -2816,6 +2820,9 @@ public class Attr extends JCTree.Visitor {
|
|||
(c.flags() & ABSTRACT) == 0) {
|
||||
checkSerialVersionUID(tree, c);
|
||||
}
|
||||
|
||||
// Check type annotations applicability rules
|
||||
validateTypeAnnotations(tree);
|
||||
}
|
||||
// where
|
||||
/** check if a class is a subtype of Serializable, if that is available. */
|
||||
|
@ -2858,4 +2865,33 @@ public class Attr extends JCTree.Visitor {
|
|||
private Type capture(Type type) {
|
||||
return types.capture(type);
|
||||
}
|
||||
|
||||
private void validateTypeAnnotations(JCTree tree) {
|
||||
tree.accept(typeAnnotationsValidator);
|
||||
}
|
||||
//where
|
||||
private final JCTree.Visitor typeAnnotationsValidator =
|
||||
new TreeScanner() {
|
||||
public void visitAnnotation(JCAnnotation tree) {
|
||||
if (tree instanceof JCTypeAnnotation) {
|
||||
chk.validateTypeAnnotation((JCTypeAnnotation)tree, false);
|
||||
}
|
||||
super.visitAnnotation(tree);
|
||||
}
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
chk.validateTypeAnnotations(tree.annotations, true);
|
||||
// don't call super. skip type annotations
|
||||
scan(tree.bounds);
|
||||
}
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
// need to check static methods
|
||||
if ((tree.sym.flags() & Flags.STATIC) != 0) {
|
||||
for (JCTypeAnnotation a : tree.receiverAnnotations) {
|
||||
if (chk.isTypeAnnotation(a, false))
|
||||
log.error(a.pos(), "annotation.type.not.applicable");
|
||||
}
|
||||
}
|
||||
super.visitMethodDef(tree);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -916,6 +916,10 @@ public class Check {
|
|||
}
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
tree.underlyingType.accept(this);
|
||||
}
|
||||
|
||||
/** Default visitor method: do nothing.
|
||||
*/
|
||||
public void visitTree(JCTree tree) {
|
||||
|
@ -1806,6 +1810,14 @@ public class Check {
|
|||
validateAnnotation(a, s);
|
||||
}
|
||||
|
||||
/** Check the type annotations
|
||||
*/
|
||||
public void validateTypeAnnotations(List<JCTypeAnnotation> annotations, boolean isTypeParameter) {
|
||||
if (skipAnnotations) return;
|
||||
for (JCTypeAnnotation a : annotations)
|
||||
validateTypeAnnotation(a, isTypeParameter);
|
||||
}
|
||||
|
||||
/** Check an annotation of a symbol.
|
||||
*/
|
||||
public void validateAnnotation(JCAnnotation a, Symbol s) {
|
||||
|
@ -1820,6 +1832,15 @@ public class Check {
|
|||
}
|
||||
}
|
||||
|
||||
public void validateTypeAnnotation(JCTypeAnnotation a, boolean isTypeParameter) {
|
||||
if (a.type == null)
|
||||
throw new AssertionError("annotation tree hasn't been attributed yet: " + a);
|
||||
validateAnnotation(a);
|
||||
|
||||
if (!isTypeAnnotation(a, isTypeParameter))
|
||||
log.error(a.pos(), "annotation.type.not.applicable");
|
||||
}
|
||||
|
||||
/** Is s a method symbol that overrides a method in a superclass? */
|
||||
boolean isOverrider(Symbol s) {
|
||||
if (s.kind != MTH || s.isStatic())
|
||||
|
@ -1838,6 +1859,25 @@ public class Check {
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Is the annotation applicable to type annotations */
|
||||
boolean isTypeAnnotation(JCTypeAnnotation a, boolean isTypeParameter) {
|
||||
Attribute.Compound atTarget =
|
||||
a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
|
||||
if (atTarget == null) return true;
|
||||
Attribute atValue = atTarget.member(names.value);
|
||||
if (!(atValue instanceof Attribute.Array)) return true; // error recovery
|
||||
Attribute.Array arr = (Attribute.Array) atValue;
|
||||
for (Attribute app : arr.values) {
|
||||
if (!(app instanceof Attribute.Enum)) return true; // recovery
|
||||
Attribute.Enum e = (Attribute.Enum) app;
|
||||
if (!isTypeParameter && e.value.name == names.TYPE_USE)
|
||||
return true;
|
||||
else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Is the annotation applicable to the symbol? */
|
||||
boolean annotationApplicable(JCAnnotation a, Symbol s) {
|
||||
Attribute.Compound atTarget =
|
||||
|
@ -1874,6 +1914,13 @@ public class Check {
|
|||
}
|
||||
else if (e.value.name == names.PACKAGE)
|
||||
{ if (s.kind == PCK) return true; }
|
||||
else if (e.value.name == names.TYPE_USE)
|
||||
{ if (s.kind == TYP ||
|
||||
s.kind == VAR ||
|
||||
(s.kind == MTH && !s.isConstructor() &&
|
||||
s.type.getReturnType().tag != VOID))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return true; // recovery
|
||||
}
|
||||
|
|
|
@ -1245,6 +1245,11 @@ public class Flow extends TreeScanner {
|
|||
}
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
// annotations don't get scanned
|
||||
tree.underlyingType.accept(this);
|
||||
}
|
||||
|
||||
public void visitIdent(JCIdent tree) {
|
||||
if (tree.sym.kind == VAR)
|
||||
checkInit(tree.pos(), (VarSymbol)tree.sym);
|
||||
|
@ -1254,7 +1259,8 @@ public class Flow extends TreeScanner {
|
|||
super.visitTypeCast(tree);
|
||||
if (!tree.type.isErroneous()
|
||||
&& lint.isEnabled(Lint.LintCategory.CAST)
|
||||
&& types.isSameType(tree.expr.type, tree.clazz.type)) {
|
||||
&& types.isSameType(tree.expr.type, tree.clazz.type)
|
||||
&& !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
|
||||
log.warning(tree.pos(), "redundant.cast", tree.expr.type);
|
||||
}
|
||||
}
|
||||
|
@ -1263,6 +1269,23 @@ public class Flow extends TreeScanner {
|
|||
// Do nothing for TopLevel since each class is visited individually
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* utility methods for ignoring type-annotated casts lint checking
|
||||
*************************************************************************/
|
||||
private static final boolean ignoreAnnotatedCasts = true;
|
||||
private static class AnnotationFinder extends TreeScanner {
|
||||
public boolean foundTypeAnno = false;
|
||||
public void visitAnnotation(JCAnnotation tree) {
|
||||
foundTypeAnno = foundTypeAnno || (tree instanceof JCTypeAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsTypeAnnotation(JCTree e) {
|
||||
AnnotationFinder finder = new AnnotationFinder();
|
||||
finder.scan(e);
|
||||
return finder.foundTypeAnno;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
|
|
|
@ -1979,7 +1979,6 @@ public class Lower extends TreeTranslator {
|
|||
c.members_field = new Scope(c);
|
||||
c.flags_field = flags;
|
||||
c.attributes_field = tree.packge.attributes_field;
|
||||
tree.packge.attributes_field = List.nil();
|
||||
ClassType ctype = (ClassType) c.type;
|
||||
ctype.supertype_field = syms.objectType;
|
||||
ctype.interfaces_field = List.nil();
|
||||
|
@ -2369,6 +2368,11 @@ public class Lower extends TreeTranslator {
|
|||
result = tree;
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
tree.underlyingType = translate(tree.underlyingType);
|
||||
result = tree.underlyingType;
|
||||
}
|
||||
|
||||
public void visitTypeCast(JCTypeCast tree) {
|
||||
tree.clazz = translate(tree.clazz);
|
||||
if (tree.type.isPrimitive() != tree.expr.type.isPrimitive())
|
||||
|
|
|
@ -99,8 +99,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
types = Types.instance(context);
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
target = Target.instance(context);
|
||||
skipAnnotations =
|
||||
Options.instance(context).get("skipAnnotations") != null;
|
||||
Options options = Options.instance(context);
|
||||
skipAnnotations = options.get("skipAnnotations") != null;
|
||||
}
|
||||
|
||||
/** A queue for classes whose members still need to be entered into the
|
||||
|
@ -906,6 +906,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
if (hasDeprecatedAnnotation(tree.mods.annotations))
|
||||
c.flags_field |= DEPRECATED;
|
||||
annotateLater(tree.mods.annotations, baseEnv, c);
|
||||
// class type parameters use baseEnv but everything uses env
|
||||
for (JCTypeParameter tp : tree.typarams)
|
||||
tp.accept(new TypeAnnotate(baseEnv));
|
||||
tree.accept(new TypeAnnotate(env));
|
||||
|
||||
chk.checkNonCyclic(tree.pos(), c.type);
|
||||
|
||||
|
@ -988,6 +992,100 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
}
|
||||
}
|
||||
|
||||
// A sub-phase that "compiles" annotations in annotated types.
|
||||
private class TypeAnnotate extends TreeScanner {
|
||||
private Env<AttrContext> env;
|
||||
public TypeAnnotate(Env<AttrContext> env) { this.env = env; }
|
||||
|
||||
private void enterTypeAnnotations(List<JCTypeAnnotation> annotations) {
|
||||
Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
|
||||
if (!skipAnnotations)
|
||||
for (List<JCTypeAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
|
||||
JCTypeAnnotation a = al.head;
|
||||
Attribute.Compound c = annotate.enterAnnotation(a,
|
||||
syms.annotationType,
|
||||
env);
|
||||
if (c == null) continue;
|
||||
Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, a.annotation_position);
|
||||
a.attribute_field = tc;
|
||||
// Note: @Deprecated has no effect on local variables and parameters
|
||||
if (!annotated.add(a.type.tsym))
|
||||
log.error(a.pos, "duplicate.annotation");
|
||||
}
|
||||
}
|
||||
|
||||
// each class (including enclosed inner classes) should be visited
|
||||
// separately through MemberEnter.complete(Symbol)
|
||||
// this flag is used to prevent from visiting inner classes.
|
||||
private boolean isEnclosingClass = false;
|
||||
@Override
|
||||
public void visitClassDef(final JCClassDecl tree) {
|
||||
if (isEnclosingClass)
|
||||
return;
|
||||
isEnclosingClass = true;
|
||||
scan(tree.mods);
|
||||
// type parameter need to be visited with a separate env
|
||||
// scan(tree.typarams);
|
||||
scan(tree.extending);
|
||||
scan(tree.implementing);
|
||||
scan(tree.defs);
|
||||
}
|
||||
|
||||
private void annotate(final JCTree tree, final List<JCTypeAnnotation> annotations) {
|
||||
annotate.later(new Annotate.Annotator() {
|
||||
public String toString() {
|
||||
return "annotate " + annotations + " onto " + tree;
|
||||
}
|
||||
public void enterAnnotation() {
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
enterTypeAnnotations(annotations);
|
||||
|
||||
// enrich type parameter symbols... easier for annotation processors
|
||||
if (tree instanceof JCTypeParameter) {
|
||||
JCTypeParameter typeparam = (JCTypeParameter)tree;
|
||||
ListBuffer<Attribute.Compound> buf = ListBuffer.lb();
|
||||
for (JCTypeAnnotation anno : annotations)
|
||||
buf.add(anno.attribute_field);
|
||||
typeparam.type.tsym.attributes_field = buf.toList();
|
||||
}
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAnnotatedType(final JCAnnotatedType tree) {
|
||||
annotate(tree, tree.annotations);
|
||||
super.visitAnnotatedType(tree);
|
||||
}
|
||||
@Override
|
||||
public void visitTypeParameter(final JCTypeParameter tree) {
|
||||
annotate(tree, tree.annotations);
|
||||
super.visitTypeParameter(tree);
|
||||
}
|
||||
@Override
|
||||
public void visitNewArray(final JCNewArray tree) {
|
||||
annotate(tree, tree.annotations);
|
||||
for (List<JCTypeAnnotation> dimAnnos : tree.dimAnnotations)
|
||||
annotate(tree, dimAnnos);
|
||||
super.visitNewArray(tree);
|
||||
}
|
||||
@Override
|
||||
public void visitApply(JCMethodInvocation tree) {
|
||||
super.visitApply(tree);
|
||||
scan(tree.typeargs);
|
||||
}
|
||||
@Override
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
annotate(tree, tree.receiverAnnotations);
|
||||
super.visitMethodDef(tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
|
||||
Scope typaramScope = new Scope(tree.sym);
|
||||
if (tree.typarams != null)
|
||||
|
|
|
@ -27,6 +27,8 @@ package com.sun.tools.javac.comp;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.element.ElementKind;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
|
@ -59,6 +61,8 @@ public class TransTypes extends TreeTranslator {
|
|||
return instance;
|
||||
}
|
||||
|
||||
private boolean debugJSR308;
|
||||
|
||||
private Names names;
|
||||
private Log log;
|
||||
private Symtab syms;
|
||||
|
@ -88,6 +92,7 @@ public class TransTypes extends TreeTranslator {
|
|||
types = Types.instance(context);
|
||||
make = TreeMaker.instance(context);
|
||||
resolve = Resolve.instance(context);
|
||||
debugJSR308 = Options.instance(context).get("TA:trans") != null;
|
||||
}
|
||||
|
||||
/** A hashtable mapping bridge methods to the methods they override after
|
||||
|
@ -435,12 +440,15 @@ public class TransTypes extends TreeTranslator {
|
|||
}
|
||||
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
new TypeAnnotationPositions().scan(tree);
|
||||
new TypeAnnotationLift().scan(tree);
|
||||
translateClass(tree.sym);
|
||||
result = tree;
|
||||
}
|
||||
|
||||
JCMethodDecl currentMethod = null;
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
tree.sym.typeAnnotations = tree.sym.typeAnnotations;
|
||||
JCMethodDecl previousMethod = currentMethod;
|
||||
try {
|
||||
currentMethod = tree;
|
||||
|
@ -726,8 +734,8 @@ public class TransTypes extends TreeTranslator {
|
|||
/** Visitor method for parameterized types.
|
||||
*/
|
||||
public void visitTypeApply(JCTypeApply tree) {
|
||||
// Delete all type parameters.
|
||||
result = translate(tree.clazz, null);
|
||||
JCTree clazz = translate(tree.clazz, null);
|
||||
result = clazz;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -793,4 +801,342 @@ public class TransTypes extends TreeTranslator {
|
|||
pt = null;
|
||||
return translate(cdef, null);
|
||||
}
|
||||
|
||||
private class TypeAnnotationPositions extends TreeScanner {
|
||||
|
||||
private ListBuffer<JCTree> frames = ListBuffer.lb();
|
||||
private void push(JCTree t) { frames = frames.prepend(t); }
|
||||
private JCTree pop() { return frames.next(); }
|
||||
private JCTree peek() { return frames.first(); }
|
||||
private JCTree peek2() { return frames.toList().tail.head; }
|
||||
|
||||
@Override
|
||||
public void scan(JCTree tree) {
|
||||
push(tree);
|
||||
super.scan(tree);
|
||||
pop();
|
||||
}
|
||||
|
||||
private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame,
|
||||
List<JCTree> path, TypeAnnotationPosition p) {
|
||||
switch (frame.getKind()) {
|
||||
case TYPE_CAST:
|
||||
p.type = TargetType.TYPECAST;
|
||||
p.pos = frame.pos;
|
||||
return p;
|
||||
|
||||
case INSTANCE_OF:
|
||||
p.type = TargetType.INSTANCEOF;
|
||||
p.pos = frame.pos;
|
||||
return p;
|
||||
|
||||
case NEW_CLASS:
|
||||
p.type = TargetType.NEW;
|
||||
p.pos = frame.pos;
|
||||
return p;
|
||||
|
||||
case NEW_ARRAY:
|
||||
p.type = TargetType.NEW;
|
||||
p.pos = frame.pos;
|
||||
return p;
|
||||
|
||||
case CLASS:
|
||||
p.pos = frame.pos;
|
||||
if (((JCClassDecl)frame).extending == tree) {
|
||||
p.type = TargetType.CLASS_EXTENDS;
|
||||
p.type_index = -1;
|
||||
} else if (((JCClassDecl)frame).implementing.contains(tree)) {
|
||||
p.type = TargetType.CLASS_EXTENDS;
|
||||
p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
|
||||
} else if (((JCClassDecl)frame).typarams.contains(tree)) {
|
||||
p.type = TargetType.CLASS_TYPE_PARAMETER;
|
||||
p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
|
||||
} else
|
||||
throw new AssertionError();
|
||||
return p;
|
||||
|
||||
case METHOD: {
|
||||
JCMethodDecl frameMethod = (JCMethodDecl)frame;
|
||||
p.pos = frame.pos;
|
||||
if (frameMethod.receiverAnnotations.contains(tree))
|
||||
p.type = TargetType.METHOD_RECEIVER;
|
||||
else if (frameMethod.thrown.contains(tree)) {
|
||||
p.type = TargetType.THROWS;
|
||||
p.type_index = frameMethod.thrown.indexOf(tree);
|
||||
} else if (((JCMethodDecl)frame).restype == tree) {
|
||||
p.type = TargetType.METHOD_RETURN_GENERIC_OR_ARRAY;
|
||||
} else if (frameMethod.typarams.contains(tree)) {
|
||||
p.type = TargetType.METHOD_TYPE_PARAMETER;
|
||||
p.parameter_index = frameMethod.typarams.indexOf(tree);
|
||||
} else
|
||||
throw new AssertionError();
|
||||
return p;
|
||||
}
|
||||
case MEMBER_SELECT: {
|
||||
JCFieldAccess fieldFrame = (JCFieldAccess)frame;
|
||||
if (fieldFrame.name == names._class) {
|
||||
p.type = TargetType.CLASS_LITERAL;
|
||||
if (fieldFrame.selected instanceof JCAnnotatedType) {
|
||||
p.pos = TreeInfo.typeIn(fieldFrame).pos;
|
||||
} else if (fieldFrame.selected instanceof JCArrayTypeTree) {
|
||||
p.pos = fieldFrame.selected.pos;
|
||||
}
|
||||
} else
|
||||
throw new AssertionError();
|
||||
return p;
|
||||
}
|
||||
case PARAMETERIZED_TYPE: {
|
||||
TypeAnnotationPosition nextP;
|
||||
if (((JCTypeApply)frame).clazz == tree)
|
||||
nextP = p; // generic: RAW; noop
|
||||
else if (((JCTypeApply)frame).arguments.contains(tree))
|
||||
p.location = p.location.prepend(
|
||||
((JCTypeApply)frame).arguments.indexOf(tree));
|
||||
else
|
||||
throw new AssertionError();
|
||||
|
||||
List<JCTree> newPath = path.tail;
|
||||
return resolveFrame(newPath.head, newPath.tail.head, newPath, p);
|
||||
}
|
||||
|
||||
case ARRAY_TYPE: {
|
||||
p.location = p.location.prepend(0);
|
||||
List<JCTree> newPath = path.tail;
|
||||
return resolveFrame(newPath.head, newPath.tail.head, newPath, p);
|
||||
}
|
||||
|
||||
case TYPE_PARAMETER:
|
||||
if (path.tail.tail.head.getTag() == JCTree.CLASSDEF) {
|
||||
JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
|
||||
p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
|
||||
p.parameter_index = clazz.typarams.indexOf(path.tail.head);
|
||||
p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
|
||||
} else if (path.tail.tail.head.getTag() == JCTree.METHODDEF) {
|
||||
JCMethodDecl method = (JCMethodDecl)path.tail.tail.head;
|
||||
p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
|
||||
p.parameter_index = method.typarams.indexOf(path.tail.head);
|
||||
p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
|
||||
} else
|
||||
throw new AssertionError();
|
||||
p.pos = frame.pos;
|
||||
return p;
|
||||
|
||||
case VARIABLE:
|
||||
VarSymbol v = ((JCVariableDecl)frame).sym;
|
||||
p.pos = frame.pos;
|
||||
switch (v.getKind()) {
|
||||
case LOCAL_VARIABLE:
|
||||
p.type = TargetType.LOCAL_VARIABLE; break;
|
||||
case FIELD:
|
||||
p.type = TargetType.FIELD_GENERIC_OR_ARRAY; break;
|
||||
case PARAMETER:
|
||||
p.type = TargetType.METHOD_PARAMETER_GENERIC_OR_ARRAY;
|
||||
p.parameter_index = methodParamIndex(path, frame);
|
||||
break;
|
||||
default: throw new AssertionError();
|
||||
}
|
||||
return p;
|
||||
|
||||
case ANNOTATED_TYPE: {
|
||||
List<JCTree> newPath = path.tail;
|
||||
return resolveFrame(newPath.head, newPath.tail.head,
|
||||
newPath, p);
|
||||
}
|
||||
|
||||
case METHOD_INVOCATION: {
|
||||
JCMethodInvocation invocation = (JCMethodInvocation)frame;
|
||||
if (!invocation.typeargs.contains(tree))
|
||||
throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation);
|
||||
p.type = TargetType.METHOD_TYPE_ARGUMENT;
|
||||
p.pos = invocation.pos;
|
||||
p.type_index = invocation.typeargs.indexOf(tree);
|
||||
return p;
|
||||
}
|
||||
|
||||
case EXTENDS_WILDCARD:
|
||||
case SUPER_WILDCARD: {
|
||||
p.type = TargetType.WILDCARD_BOUND;
|
||||
List<JCTree> newPath = path.tail;
|
||||
|
||||
TypeAnnotationPosition wildcard =
|
||||
resolveFrame(newPath.head, newPath.tail.head, newPath,
|
||||
new TypeAnnotationPosition());
|
||||
if (!wildcard.location.isEmpty())
|
||||
wildcard.type = wildcard.type.getGenericComplement();
|
||||
p.wildcard_position = wildcard;
|
||||
p.pos = frame.pos;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitApply(JCMethodInvocation tree) {
|
||||
scan(tree.meth);
|
||||
scan(tree.typeargs);
|
||||
scan(tree.args);
|
||||
}
|
||||
|
||||
private void setTypeAnnotationPos(List<JCTypeAnnotation> annotations, TypeAnnotationPosition position) {
|
||||
for (JCTypeAnnotation anno : annotations) {
|
||||
anno.annotation_position = position;
|
||||
anno.attribute_field.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
findPosition(tree, tree, tree.annotations);
|
||||
int dimAnnosCount = tree.dimAnnotations.size();
|
||||
|
||||
// handle annotations associated with dimentions
|
||||
for (int i = 0; i < dimAnnosCount; ++i) {
|
||||
TypeAnnotationPosition p = new TypeAnnotationPosition();
|
||||
p.type = TargetType.NEW_GENERIC_OR_ARRAY;
|
||||
p.pos = tree.pos;
|
||||
p.location = p.location.append(i);
|
||||
setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
|
||||
}
|
||||
|
||||
// handle "free" annotations
|
||||
int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
|
||||
JCExpression elemType = tree.elemtype;
|
||||
while (elemType != null) {
|
||||
if (elemType.getTag() == JCTree.ANNOTATED_TYPE) {
|
||||
JCAnnotatedType at = (JCAnnotatedType)elemType;
|
||||
TypeAnnotationPosition p = new TypeAnnotationPosition();
|
||||
p.type = TargetType.NEW_GENERIC_OR_ARRAY;
|
||||
p.pos = tree.pos;
|
||||
p.location = p.location.append(i);
|
||||
setTypeAnnotationPos(at.annotations, p);
|
||||
elemType = at.underlyingType;
|
||||
} else if (elemType.getTag() == JCTree.TYPEARRAY) {
|
||||
++i;
|
||||
elemType = ((JCArrayTypeTree)elemType).elemtype;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
// find annotations locations of initializer elements
|
||||
scan(tree.elems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
findPosition(tree, peek2(), tree.annotations);
|
||||
super.visitAnnotatedType(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
TypeAnnotationPosition p = new TypeAnnotationPosition();
|
||||
p.type = TargetType.METHOD_RECEIVER;
|
||||
setTypeAnnotationPos(tree.receiverAnnotations, p);
|
||||
super.visitMethodDef(tree);
|
||||
}
|
||||
@Override
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
findPosition(tree, peek2(), tree.annotations);
|
||||
super.visitTypeParameter(tree);
|
||||
}
|
||||
|
||||
void findPosition(JCTree tree, JCTree frame, List<JCTypeAnnotation> annotations) {
|
||||
if (!annotations.isEmpty()) {
|
||||
TypeAnnotationPosition p =
|
||||
resolveFrame(tree, frame, frames.toList(),
|
||||
new TypeAnnotationPosition());
|
||||
if (!p.location.isEmpty())
|
||||
p.type = p.type.getGenericComplement();
|
||||
setTypeAnnotationPos(annotations, p);
|
||||
if (debugJSR308) {
|
||||
System.out.println("trans: " + tree);
|
||||
System.out.println(" target: " + p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int methodParamIndex(List<JCTree> path, JCTree param) {
|
||||
List<JCTree> curr = path;
|
||||
if (curr.head != param)
|
||||
curr = path.tail;
|
||||
JCMethodDecl method = (JCMethodDecl)curr.tail.head;
|
||||
return method.params.indexOf(param);
|
||||
}
|
||||
}
|
||||
|
||||
private class TypeAnnotationLift extends TreeScanner {
|
||||
List<Attribute.TypeCompound> recordedTypeAnnotations = List.nil();
|
||||
|
||||
boolean isInner = false;
|
||||
@Override
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
if (isInner) {
|
||||
// tree is an inner class tree. stop now.
|
||||
// TransTypes.visitClassDef makes an invocation for each class
|
||||
// seperately.
|
||||
return;
|
||||
}
|
||||
isInner = true;
|
||||
List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
|
||||
recordedTypeAnnotations = List.nil();
|
||||
try {
|
||||
super.visitClassDef(tree);
|
||||
} finally {
|
||||
tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
|
||||
recordedTypeAnnotations = prevTAs;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
|
||||
recordedTypeAnnotations = List.nil();
|
||||
try {
|
||||
super.visitMethodDef(tree);
|
||||
} finally {
|
||||
tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
|
||||
recordedTypeAnnotations = prevTAs;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
|
||||
recordedTypeAnnotations = List.nil();
|
||||
ElementKind kind = tree.sym.getKind();
|
||||
if (kind == ElementKind.LOCAL_VARIABLE && tree.mods.annotations.nonEmpty()) {
|
||||
// need to lift the annotations
|
||||
TypeAnnotationPosition position = new TypeAnnotationPosition();
|
||||
position.pos = tree.pos;
|
||||
position.type = TargetType.LOCAL_VARIABLE;
|
||||
for (Attribute.Compound attribute : tree.sym.attributes_field) {
|
||||
Attribute.TypeCompound tc =
|
||||
new Attribute.TypeCompound(attribute.type, attribute.values, position);
|
||||
recordedTypeAnnotations = recordedTypeAnnotations.append(tc);
|
||||
}
|
||||
}
|
||||
try {
|
||||
super.visitVarDef(tree);
|
||||
} finally {
|
||||
if (kind.isField() || kind == ElementKind.LOCAL_VARIABLE)
|
||||
tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
|
||||
recordedTypeAnnotations = kind.isField() ? prevTAs : prevTAs.appendList(recordedTypeAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitApply(JCMethodInvocation tree) {
|
||||
scan(tree.meth);
|
||||
scan(tree.typeargs);
|
||||
scan(tree.args);
|
||||
}
|
||||
|
||||
public void visitAnnotation(JCAnnotation tree) {
|
||||
if (tree instanceof JCTypeAnnotation)
|
||||
recordedTypeAnnotations = recordedTypeAnnotations.append(((JCTypeAnnotation)tree).attribute_field);
|
||||
super.visitAnnotation(tree);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ import com.sun.tools.javac.code.Symbol.*;
|
|||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.file.BaseFileObject;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Kinds.*;
|
||||
|
@ -187,6 +186,10 @@ public class ClassReader implements Completer {
|
|||
/** The minor version number of the class file being read. */
|
||||
int minorVersion;
|
||||
|
||||
/** Switch: debug output for JSR 308-related operations.
|
||||
*/
|
||||
boolean debugJSR308;
|
||||
|
||||
/** Get the ClassReader instance for this invocation. */
|
||||
public static ClassReader instance(Context context) {
|
||||
ClassReader instance = context.get(classReaderKey);
|
||||
|
@ -256,6 +259,7 @@ public class ClassReader implements Completer {
|
|||
: null;
|
||||
|
||||
typevars = new Scope(syms.noSymbol);
|
||||
debugJSR308 = options.get("TA:reader") != null;
|
||||
|
||||
initAttributeReaders();
|
||||
}
|
||||
|
@ -303,6 +307,12 @@ public class ClassReader implements Completer {
|
|||
return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
|
||||
}
|
||||
|
||||
/** Read a byte.
|
||||
*/
|
||||
byte nextByte() {
|
||||
return buf[bp++];
|
||||
}
|
||||
|
||||
/** Read an integer.
|
||||
*/
|
||||
int nextInt() {
|
||||
|
@ -1060,7 +1070,21 @@ public class ClassReader implements Completer {
|
|||
if (allowVarargs)
|
||||
sym.flags_field |= VARARGS;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// v51 attributes
|
||||
new AttributeReader(names.RuntimeVisibleTypeAnnotations, V51, CLASS_OR_MEMBER_ATTRIBUTE) {
|
||||
void read(Symbol sym, int attrLen) {
|
||||
attachTypeAnnotations(sym);
|
||||
}
|
||||
},
|
||||
|
||||
new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V51, CLASS_OR_MEMBER_ATTRIBUTE) {
|
||||
void read(Symbol sym, int attrLen) {
|
||||
attachTypeAnnotations(sym);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// The following attributes for a Code attribute are not currently handled
|
||||
// StackMapTable
|
||||
|
@ -1268,6 +1292,17 @@ public class ClassReader implements Completer {
|
|||
}
|
||||
}
|
||||
|
||||
void attachTypeAnnotations(final Symbol sym) {
|
||||
int numAttributes = nextChar();
|
||||
if (numAttributes != 0) {
|
||||
ListBuffer<TypeAnnotationProxy> proxies =
|
||||
ListBuffer.lb();
|
||||
for (int i = 0; i < numAttributes; i++)
|
||||
proxies.append(readTypeAnnotation());
|
||||
annotate.later(new TypeAnnotationCompleter(sym, proxies.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Attach the default value for an annotation element.
|
||||
*/
|
||||
void attachAnnotationDefault(final Symbol sym) {
|
||||
|
@ -1304,6 +1339,121 @@ public class ClassReader implements Completer {
|
|||
return new CompoundAnnotationProxy(t, pairs.toList());
|
||||
}
|
||||
|
||||
TypeAnnotationProxy readTypeAnnotation() {
|
||||
CompoundAnnotationProxy proxy = readCompoundAnnotation();
|
||||
TypeAnnotationPosition position = readPosition();
|
||||
|
||||
if (debugJSR308)
|
||||
System.out.println("TA: reading: " + proxy + " @ " + position
|
||||
+ " in " + log.currentSourceFile());
|
||||
|
||||
return new TypeAnnotationProxy(proxy, position);
|
||||
}
|
||||
|
||||
TypeAnnotationPosition readPosition() {
|
||||
byte tag = nextByte();
|
||||
|
||||
if (!TargetType.isValidTargetTypeValue(tag))
|
||||
throw this.badClassFile("bad.type.annotation.value", tag);
|
||||
|
||||
TypeAnnotationPosition position = new TypeAnnotationPosition();
|
||||
TargetType type = TargetType.fromTargetTypeValue(tag);
|
||||
|
||||
position.type = type;
|
||||
|
||||
switch (type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
position.offset = nextChar();
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
int table_length = nextChar();
|
||||
position.lvarOffset = new int[table_length];
|
||||
position.lvarLength = new int[table_length];
|
||||
position.lvarIndex = new int[table_length];
|
||||
|
||||
for (int i = 0; i < table_length; ++i) {
|
||||
position.lvarOffset[i] = nextChar();
|
||||
position.lvarLength[i] = nextChar();
|
||||
position.lvarIndex[i] = nextChar();
|
||||
}
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
position.parameter_index = nextByte();
|
||||
break;
|
||||
// type parameter bounds
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
position.parameter_index = nextByte();
|
||||
position.bound_index = nextByte();
|
||||
break;
|
||||
// wildcard
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
position.wildcard_position = readPosition();
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
position.type_index = nextByte();
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
position.type_index = nextByte();
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
case CLASS_LITERAL_GENERIC_OR_ARRAY:
|
||||
position.offset = nextChar();
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
position.parameter_index = nextByte();
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
position.offset = nextChar();
|
||||
position.type_index = nextByte();
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("unknown type: " + position);
|
||||
}
|
||||
|
||||
if (type.hasLocation()) {
|
||||
int len = nextChar();
|
||||
ListBuffer<Integer> loc = ListBuffer.lb();
|
||||
for (int i = 0; i < len; i++)
|
||||
loc = loc.append((int)nextByte());
|
||||
position.location = loc.toList();
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
Attribute readAttributeValue() {
|
||||
char c = (char) buf[bp++];
|
||||
switch (c) {
|
||||
|
@ -1408,6 +1558,18 @@ public class ClassReader implements Completer {
|
|||
}
|
||||
}
|
||||
|
||||
/** A temporary proxy representing a type annotation.
|
||||
*/
|
||||
static class TypeAnnotationProxy {
|
||||
final CompoundAnnotationProxy compound;
|
||||
final TypeAnnotationPosition position;
|
||||
public TypeAnnotationProxy(CompoundAnnotationProxy compound,
|
||||
TypeAnnotationPosition position) {
|
||||
this.compound = compound;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
class AnnotationDeproxy implements ProxyVisitor {
|
||||
private ClassSymbol requestingOwner = currentOwner.kind == MTH
|
||||
? currentOwner.enclClass() : (ClassSymbol)currentOwner;
|
||||
|
@ -1604,6 +1766,45 @@ public class ClassReader implements Completer {
|
|||
}
|
||||
}
|
||||
|
||||
class TypeAnnotationCompleter extends AnnotationCompleter {
|
||||
|
||||
List<TypeAnnotationProxy> proxies;
|
||||
|
||||
TypeAnnotationCompleter(Symbol sym,
|
||||
List<TypeAnnotationProxy> proxies) {
|
||||
super(sym, List.<CompoundAnnotationProxy>nil());
|
||||
this.proxies = proxies;
|
||||
}
|
||||
|
||||
List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
|
||||
ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
|
||||
for (TypeAnnotationProxy proxy: proxies) {
|
||||
Attribute.Compound compound = deproxyCompound(proxy.compound);
|
||||
Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
|
||||
buf.add(typeCompound);
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterAnnotation() {
|
||||
JavaFileObject previousClassFile = currentClassFile;
|
||||
try {
|
||||
currentClassFile = classFile;
|
||||
List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies);
|
||||
if (debugJSR308)
|
||||
System.out.println("TA: reading: adding " + newList
|
||||
+ " to symbol " + sym + " in " + log.currentSourceFile());
|
||||
sym.typeAnnotations = ((sym.typeAnnotations == null)
|
||||
? newList
|
||||
: newList.prependList(sym.typeAnnotations));
|
||||
|
||||
} finally {
|
||||
currentClassFile = previousClassFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Reading Symbols
|
||||
|
|
|
@ -37,7 +37,6 @@ import com.sun.tools.javac.code.*;
|
|||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import static com.sun.tools.javac.code.BoundKind.*;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
|
@ -62,6 +61,10 @@ public class ClassWriter extends ClassFile {
|
|||
|
||||
private final Options options;
|
||||
|
||||
/** Switch: debugging output for JSR 308-related operations.
|
||||
*/
|
||||
private boolean debugJSR308;
|
||||
|
||||
/** Switch: verbose output.
|
||||
*/
|
||||
private boolean verbose;
|
||||
|
@ -173,6 +176,7 @@ public class ClassWriter extends ClassFile {
|
|||
types = Types.instance(context);
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
|
||||
debugJSR308 = options.get("TA:writer") != null;
|
||||
verbose = options.get("-verbose") != null;
|
||||
scramble = options.get("-scramble") != null;
|
||||
scrambleAll = options.get("-scrambleAll") != null;
|
||||
|
@ -668,6 +672,7 @@ public class ClassWriter extends ClassFile {
|
|||
acount++;
|
||||
}
|
||||
acount += writeJavaAnnotations(sym.getAnnotationMirrors());
|
||||
acount += writeTypeAnnotations(sym.typeAnnotations);
|
||||
return acount;
|
||||
}
|
||||
|
||||
|
@ -762,6 +767,46 @@ public class ClassWriter extends ClassFile {
|
|||
return attrCount;
|
||||
}
|
||||
|
||||
int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos) {
|
||||
if (typeAnnos.isEmpty()) return 0;
|
||||
|
||||
ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb();
|
||||
ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb();
|
||||
|
||||
for (Attribute.TypeCompound tc : typeAnnos) {
|
||||
if (tc.position.type == TargetType.UNKNOWN
|
||||
|| !tc.position.emitToClassfile())
|
||||
continue;
|
||||
switch (getRetention(tc.type.tsym)) {
|
||||
case SOURCE: break;
|
||||
case CLASS: invisibles.append(tc); break;
|
||||
case RUNTIME: visibles.append(tc); break;
|
||||
default: ;// /* fail soft */ throw new AssertionError(vis);
|
||||
}
|
||||
}
|
||||
|
||||
int attrCount = 0;
|
||||
if (visibles.length() != 0) {
|
||||
int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations);
|
||||
databuf.appendChar(visibles.length());
|
||||
for (Attribute.TypeCompound p : visibles)
|
||||
writeTypeAnnotation(p);
|
||||
endAttr(attrIndex);
|
||||
attrCount++;
|
||||
}
|
||||
|
||||
if (invisibles.length() != 0) {
|
||||
int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations);
|
||||
databuf.appendChar(invisibles.length());
|
||||
for (Attribute.TypeCompound p : invisibles)
|
||||
writeTypeAnnotation(p);
|
||||
endAttr(attrIndex);
|
||||
attrCount++;
|
||||
}
|
||||
|
||||
return attrCount;
|
||||
}
|
||||
|
||||
/** A mirror of java.lang.annotation.RetentionPolicy. */
|
||||
enum RetentionPolicy {
|
||||
SOURCE,
|
||||
|
@ -862,6 +907,103 @@ public class ClassWriter extends ClassFile {
|
|||
}
|
||||
}
|
||||
|
||||
void writeTypeAnnotation(Attribute.TypeCompound c) {
|
||||
if (debugJSR308)
|
||||
System.out.println("TA: writing " + c + " at " + c.position
|
||||
+ " in " + log.currentSourceFile());
|
||||
writeCompoundAttribute(c);
|
||||
writePosition(c.position);
|
||||
}
|
||||
|
||||
void writePosition(TypeAnnotationPosition p) {
|
||||
databuf.appendByte(p.type.targetTypeValue());
|
||||
switch (p.type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
databuf.appendChar(p.offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
databuf.appendChar(p.lvarOffset.length); // for table length
|
||||
for (int i = 0; i < p.lvarOffset.length; ++i) {
|
||||
databuf.appendChar(p.lvarOffset[i]);
|
||||
databuf.appendChar(p.lvarLength[i]);
|
||||
databuf.appendChar(p.lvarIndex[i]);
|
||||
}
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
break;
|
||||
// type parameters bounds
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
databuf.appendByte(p.bound_index);
|
||||
break;
|
||||
// wildcards
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
writePosition(p.wildcard_position);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
databuf.appendByte(p.type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
databuf.appendByte(p.type_index);
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
case CLASS_LITERAL_GENERIC_OR_ARRAY:
|
||||
databuf.appendChar(p.offset);
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
databuf.appendChar(p.offset);
|
||||
databuf.appendByte(p.type_index);
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("unknown position: " + p);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (p.type.hasLocation()) {
|
||||
databuf.appendChar(p.location.size());
|
||||
for (int i : p.location)
|
||||
databuf.appendByte((byte)i);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Writing Objects
|
||||
**********************************************************************/
|
||||
|
@ -1569,6 +1711,7 @@ public class ClassWriter extends ClassFile {
|
|||
|
||||
acount += writeFlagAttrs(c.flags());
|
||||
acount += writeJavaAnnotations(c.getAnnotationMirrors());
|
||||
acount += writeTypeAnnotations(c.typeAnnotations);
|
||||
acount += writeEnclosingMethodAttribute(c);
|
||||
|
||||
poolbuf.appendInt(JAVA_MAGIC);
|
||||
|
|
|
@ -1912,12 +1912,29 @@ public class Code {
|
|||
if (length < Character.MAX_VALUE) {
|
||||
v.length = length;
|
||||
putVar(v);
|
||||
fillLocalVarPosition(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.defined.excl(adr);
|
||||
}
|
||||
|
||||
private void fillLocalVarPosition(LocalVar lv) {
|
||||
if (lv == null || lv.sym == null
|
||||
|| lv.sym.typeAnnotations == null)
|
||||
return;
|
||||
for (Attribute.TypeCompound ta : lv.sym.typeAnnotations) {
|
||||
TypeAnnotationPosition p = ta.position;
|
||||
while (p != null) {
|
||||
p.lvarOffset[0] = (int)lv.start_pc;
|
||||
p.lvarLength[0] = (int)lv.length;
|
||||
p.lvarIndex[0] = (int)lv.reg;
|
||||
p.isValidOffset = true;
|
||||
p = p.wildcard_position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Put a live variable range into the buffer to be output to the
|
||||
* class file.
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
package com.sun.tools.javac.jvm;
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.element.ElementKind;
|
||||
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
@ -939,7 +941,6 @@ public class Gen extends JCTree.Visitor {
|
|||
startpcCrt,
|
||||
code.curPc());
|
||||
|
||||
// End the scope of all local variables in variable info.
|
||||
code.endScopes(0);
|
||||
|
||||
// If we exceeded limits, panic
|
||||
|
@ -1439,7 +1440,6 @@ public class Gen extends JCTree.Visitor {
|
|||
// Resolve all breaks.
|
||||
code.resolve(exitChain);
|
||||
|
||||
// End the scopes of all try-local variables in variable info.
|
||||
code.endScopes(limit);
|
||||
}
|
||||
|
||||
|
@ -1672,6 +1672,7 @@ public class Gen extends JCTree.Visitor {
|
|||
*************************************************************************/
|
||||
|
||||
public void visitApply(JCMethodInvocation tree) {
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
// Generate code for method.
|
||||
Item m = genExpr(tree.meth, methodType);
|
||||
// Generate code for all arguments, where the expected types are
|
||||
|
@ -1707,10 +1708,48 @@ public class Gen extends JCTree.Visitor {
|
|||
result = items.makeStackItem(pt);
|
||||
}
|
||||
|
||||
private void setTypeAnnotationPositions(int treePos) {
|
||||
MethodSymbol meth = code.meth;
|
||||
|
||||
for (Attribute.TypeCompound ta : meth.typeAnnotations) {
|
||||
if (ta.position.pos == treePos) {
|
||||
ta.position.offset = code.cp;
|
||||
ta.position.lvarOffset[0] = code.cp;
|
||||
ta.position.isValidOffset = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (code.meth.getKind() != ElementKind.CONSTRUCTOR
|
||||
&& code.meth.getKind() != ElementKind.STATIC_INIT)
|
||||
return;
|
||||
|
||||
for (Attribute.TypeCompound ta : meth.owner.typeAnnotations) {
|
||||
if (ta.position.pos == treePos) {
|
||||
ta.position.offset = code.cp;
|
||||
ta.position.lvarOffset[0] = code.cp;
|
||||
ta.position.isValidOffset = true;
|
||||
}
|
||||
}
|
||||
|
||||
ClassSymbol clazz = meth.enclClass();
|
||||
for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
|
||||
if (!s.getKind().isField())
|
||||
continue;
|
||||
for (Attribute.TypeCompound ta : s.typeAnnotations) {
|
||||
if (ta.position.pos == treePos) {
|
||||
ta.position.offset = code.cp;
|
||||
ta.position.lvarOffset[0] = code.cp;
|
||||
ta.position.isValidOffset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visitNewClass(JCNewClass tree) {
|
||||
// Enclosing instances or anonymous classes should have been eliminated
|
||||
// by now.
|
||||
assert tree.encl == null && tree.def == null;
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
|
||||
code.emitop2(new_, makeRef(tree.pos(), tree.type));
|
||||
code.emitop0(dup);
|
||||
|
@ -1725,6 +1764,8 @@ public class Gen extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
|
||||
if (tree.elems != null) {
|
||||
Type elemtype = types.elemtype(tree.type);
|
||||
loadIntConst(tree.elems.length());
|
||||
|
@ -2053,6 +2094,7 @@ public class Gen extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
public void visitTypeCast(JCTypeCast tree) {
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
result = genExpr(tree.expr, tree.clazz.type).load();
|
||||
// Additional code is only needed if we cast to a reference type
|
||||
// which is not statically a supertype of the expression's type.
|
||||
|
@ -2069,6 +2111,8 @@ public class Gen extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
public void visitTypeTest(JCInstanceOf tree) {
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
|
||||
genExpr(tree.expr, tree.expr.type).load();
|
||||
code.emitop2(instanceof_, makeRef(tree.pos(), tree.clazz.type));
|
||||
result = items.makeStackItem(syms.booleanType);
|
||||
|
@ -2110,6 +2154,7 @@ public class Gen extends JCTree.Visitor {
|
|||
|
||||
if (tree.name == names._class) {
|
||||
assert target.hasClassLiterals();
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type));
|
||||
result = items.makeStackItem(pt);
|
||||
return;
|
||||
|
|
|
@ -477,7 +477,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||
public Todo todo;
|
||||
|
||||
/** Ordered list of compiler phases for each compilation unit. */
|
||||
protected enum CompileState {
|
||||
public enum CompileState {
|
||||
PARSE(1),
|
||||
ENTER(2),
|
||||
PROCESS(3),
|
||||
|
|
|
@ -75,6 +75,42 @@ public class JavacParser implements Parser {
|
|||
/** The name table. */
|
||||
private Names names;
|
||||
|
||||
// Because of javac's limited lookahead, some contexts are ambiguous in
|
||||
// the presence of type annotations even though they are not ambiguous
|
||||
// in the absence of type annotations. Consider this code:
|
||||
// void m(String [] m) { }
|
||||
// void m(String ... m) { }
|
||||
// After parsing "String", javac calls bracketsOpt which immediately
|
||||
// returns if the next character is not '['. Similarly, javac can see
|
||||
// if the next token is ... and in that case parse an ellipsis. But in
|
||||
// the presence of type annotations:
|
||||
// void m(String @A [] m) { }
|
||||
// void m(String @A ... m) { }
|
||||
// no finite lookahead is enough to determine whether to read array
|
||||
// levels or an ellipsis. Furthermore, if you call bracketsOpt, then
|
||||
// bracketsOpt first reads all the leading annotations and only then
|
||||
// discovers that it needs to fail. bracketsOpt needs a way to push
|
||||
// back the extra annotations that it read. (But, bracketsOpt should
|
||||
// not *always* be allowed to push back extra annotations that it finds
|
||||
// -- in most contexts, any such extra annotation is an error.
|
||||
// Another similar case occurs with arrays and receiver annotations:
|
||||
// String b() @Array [] @Receiver { }
|
||||
// String b() @Receiver { }
|
||||
//
|
||||
// The following two variables permit type annotations that have
|
||||
// already been read to be stored for later use. Alternate
|
||||
// implementations are possible but would cause much larger changes to
|
||||
// the parser.
|
||||
/** Type annotations that have already been read but have not yet been used. **/
|
||||
private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
|
||||
/**
|
||||
* If the parser notices extra annotations, then it either immediately
|
||||
* issues an error (if this variable is false) or places the extra
|
||||
* annotations in variable typeAnnotationsPushedBack (if this variable
|
||||
* is true).
|
||||
*/
|
||||
private boolean permitTypeAnnotationsPushBack = false;
|
||||
|
||||
/** Construct a parser from a given scanner, tree factory and log.
|
||||
*/
|
||||
protected JavacParser(ParserFactory fac,
|
||||
|
@ -95,13 +131,19 @@ public class JavacParser implements Parser {
|
|||
this.allowForeach = source.allowForeach();
|
||||
this.allowStaticImport = source.allowStaticImport();
|
||||
this.allowAnnotations = source.allowAnnotations();
|
||||
this.allowTypeAnnotations = source.allowTypeAnnotations();
|
||||
this.keepDocComments = keepDocComments;
|
||||
if (keepDocComments)
|
||||
docComments = new HashMap<JCTree,String>();
|
||||
this.keepLineMap = keepLineMap;
|
||||
this.errorTree = F.Erroneous();
|
||||
this.debugJSR308 = fac.options.get("TA:parser") != null;
|
||||
}
|
||||
|
||||
/** Switch: debug output for type-annotations operations
|
||||
*/
|
||||
boolean debugJSR308;
|
||||
|
||||
/** Switch: Should generics be recognized?
|
||||
*/
|
||||
boolean allowGenerics;
|
||||
|
@ -130,6 +172,10 @@ public class JavacParser implements Parser {
|
|||
*/
|
||||
boolean allowAnnotations;
|
||||
|
||||
/** Switch: should we recognize type annotations?
|
||||
*/
|
||||
boolean allowTypeAnnotations;
|
||||
|
||||
/** Switch: should we keep docComments?
|
||||
*/
|
||||
boolean keepDocComments;
|
||||
|
@ -558,7 +604,33 @@ public class JavacParser implements Parser {
|
|||
return term(EXPR);
|
||||
}
|
||||
|
||||
/**
|
||||
* parses (optional) type annotations followed by a type. If the
|
||||
* annotations are present before the type and are not consumed during array
|
||||
* parsing, this method returns a {@link JCAnnotatedType} consisting of
|
||||
* these annotations and the underlying type. Otherwise, it returns the
|
||||
* underlying type.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* Note that this method sets {@code mode} to {@code TYPE} first, before
|
||||
* parsing annotations.
|
||||
*/
|
||||
public JCExpression parseType() {
|
||||
List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
|
||||
return parseType(annotations);
|
||||
}
|
||||
|
||||
public JCExpression parseType(List<JCTypeAnnotation> annotations) {
|
||||
JCExpression result = unannotatedType();
|
||||
|
||||
if (!annotations.isEmpty())
|
||||
result = F.AnnotatedType(annotations, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public JCExpression unannotatedType() {
|
||||
return term(TYPE);
|
||||
}
|
||||
|
||||
|
@ -792,8 +864,8 @@ public class JavacParser implements Parser {
|
|||
* | [TypeArguments] THIS [Arguments]
|
||||
* | [TypeArguments] SUPER SuperSuffix
|
||||
* | NEW [TypeArguments] Creator
|
||||
* | Ident { "." Ident }
|
||||
* [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
|
||||
* | [Annotations] Ident { "." Ident }
|
||||
* [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
|
||||
* | Arguments
|
||||
* | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
|
||||
* ]
|
||||
|
@ -942,23 +1014,62 @@ public class JavacParser implements Parser {
|
|||
typeArgs = null;
|
||||
} else return illegal();
|
||||
break;
|
||||
case MONKEYS_AT:
|
||||
|
||||
// only annotated targetting class literals or cast types are valid
|
||||
List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
|
||||
if (typeAnnos.isEmpty()) {
|
||||
// else there would be no '@'
|
||||
throw new AssertionError("type annos is empty");
|
||||
}
|
||||
|
||||
JCExpression expr = term3();
|
||||
|
||||
// Type annotations: If term3 just parsed a non-type, expect a
|
||||
// class literal (and issue a syntax error if there is no class
|
||||
// literal). Otherwise, create a JCAnnotatedType.
|
||||
if ((mode & TYPE) == 0) {
|
||||
if (expr.getTag() != JCTree.SELECT)
|
||||
return illegal(typeAnnos.head.pos);
|
||||
JCFieldAccess sel = (JCFieldAccess)expr;
|
||||
if (sel.name != names._class)
|
||||
return illegal();
|
||||
else {
|
||||
sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
|
||||
t = expr;
|
||||
}
|
||||
} else {
|
||||
// type annotation targeting a cast
|
||||
t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
|
||||
}
|
||||
break;
|
||||
case IDENTIFIER: case ASSERT: case ENUM:
|
||||
if (typeArgs != null) return illegal();
|
||||
t = toP(F.at(S.pos()).Ident(ident()));
|
||||
loop: while (true) {
|
||||
pos = S.pos();
|
||||
final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
|
||||
|
||||
// need to report an error later if LBRACKET is for array
|
||||
// index access rather than array creation level
|
||||
if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
|
||||
return illegal(annos.head.pos);
|
||||
switch (S.token()) {
|
||||
case LBRACKET:
|
||||
S.nextToken();
|
||||
|
||||
if (S.token() == RBRACKET) {
|
||||
|
||||
S.nextToken();
|
||||
t = bracketsOpt(t);
|
||||
|
||||
t = bracketsOpt(t, annos);
|
||||
t = toP(F.at(pos).TypeArray(t));
|
||||
t = bracketsSuffix(t);
|
||||
} else {
|
||||
if ((mode & EXPR) != 0) {
|
||||
mode = EXPR;
|
||||
JCExpression t1 = term();
|
||||
if (!annos.isEmpty()) t = illegal(annos.head.pos);
|
||||
t = to(F.at(pos).Indexed(t, t1));
|
||||
}
|
||||
accept(RBRACKET);
|
||||
|
@ -1011,6 +1122,10 @@ public class JavacParser implements Parser {
|
|||
// typeArgs saved for next loop iteration.
|
||||
t = toP(F.at(pos).Select(t, ident()));
|
||||
break;
|
||||
case ELLIPSIS:
|
||||
assert this.permitTypeAnnotationsPushBack;
|
||||
typeAnnotationsPushedBack = annos;
|
||||
break loop;
|
||||
default:
|
||||
break loop;
|
||||
}
|
||||
|
@ -1049,14 +1164,18 @@ public class JavacParser implements Parser {
|
|||
if (typeArgs != null) illegal();
|
||||
while (true) {
|
||||
int pos1 = S.pos();
|
||||
|
||||
final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
|
||||
|
||||
if (S.token() == LBRACKET) {
|
||||
S.nextToken();
|
||||
|
||||
if ((mode & TYPE) != 0) {
|
||||
int oldmode = mode;
|
||||
mode = TYPE;
|
||||
if (S.token() == RBRACKET) {
|
||||
S.nextToken();
|
||||
t = bracketsOpt(t);
|
||||
t = bracketsOpt(t, annos);
|
||||
t = toP(F.at(pos1).TypeArray(t));
|
||||
return t;
|
||||
}
|
||||
|
@ -1091,6 +1210,12 @@ public class JavacParser implements Parser {
|
|||
typeArgs = null;
|
||||
}
|
||||
} else {
|
||||
if (!annos.isEmpty()) {
|
||||
if (permitTypeAnnotationsPushBack)
|
||||
typeAnnotationsPushedBack = annos;
|
||||
else
|
||||
return illegal(annos.head.pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1100,6 +1225,7 @@ public class JavacParser implements Parser {
|
|||
S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
|
||||
S.nextToken();
|
||||
}
|
||||
|
||||
return toP(t);
|
||||
}
|
||||
|
||||
|
@ -1232,22 +1358,24 @@ public class JavacParser implements Parser {
|
|||
}
|
||||
|
||||
/** TypeArgument = Type
|
||||
* | "?"
|
||||
* | "?" EXTENDS Type {"&" Type}
|
||||
* | "?" SUPER Type
|
||||
* | [Annotations] "?"
|
||||
* | [Annotations] "?" EXTENDS Type {"&" Type}
|
||||
* | [Annotations] "?" SUPER Type
|
||||
*/
|
||||
JCExpression typeArgument() {
|
||||
if (S.token() != QUES) return parseType();
|
||||
List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
|
||||
if (S.token() != QUES) return parseType(annotations);
|
||||
int pos = S.pos();
|
||||
S.nextToken();
|
||||
JCExpression result;
|
||||
if (S.token() == EXTENDS) {
|
||||
TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
|
||||
S.nextToken();
|
||||
return F.at(pos).Wildcard(t, parseType());
|
||||
result = F.at(pos).Wildcard(t, parseType());
|
||||
} else if (S.token() == SUPER) {
|
||||
TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
|
||||
S.nextToken();
|
||||
return F.at(pos).Wildcard(t, parseType());
|
||||
result = F.at(pos).Wildcard(t, parseType());
|
||||
} else if (S.token() == IDENTIFIER) {
|
||||
//error recovery
|
||||
reportSyntaxError(S.prevEndPos(), "expected3",
|
||||
|
@ -1255,11 +1383,14 @@ public class JavacParser implements Parser {
|
|||
TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
|
||||
JCExpression wc = toP(F.at(pos).Wildcard(t, null));
|
||||
JCIdent id = toP(F.at(S.pos()).Ident(ident()));
|
||||
return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
|
||||
result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
|
||||
} else {
|
||||
TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
|
||||
return toP(F.at(pos).Wildcard(t, null));
|
||||
result = toP(F.at(pos).Wildcard(t, null));
|
||||
}
|
||||
if (!annotations.isEmpty())
|
||||
result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
|
||||
return result;
|
||||
}
|
||||
|
||||
JCTypeApply typeArguments(JCExpression t) {
|
||||
|
@ -1268,21 +1399,47 @@ public class JavacParser implements Parser {
|
|||
return toP(F.at(pos).TypeApply(t, args));
|
||||
}
|
||||
|
||||
/** BracketsOpt = {"[" "]"}
|
||||
/**
|
||||
* BracketsOpt = { [Annotations] "[" "]" }
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* <code>annotations</code> is the list of annotations targeting
|
||||
* the expression <code>t</code>.
|
||||
*/
|
||||
private JCExpression bracketsOpt(JCExpression t) {
|
||||
private JCExpression bracketsOpt(JCExpression t,
|
||||
List<JCTypeAnnotation> annotations) {
|
||||
List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
|
||||
|
||||
if (S.token() == LBRACKET) {
|
||||
int pos = S.pos();
|
||||
S.nextToken();
|
||||
t = bracketsOptCont(t, pos);
|
||||
F.at(pos);
|
||||
|
||||
JCExpression orig = t;
|
||||
t = bracketsOptCont(t, pos, nextLevelAnnotations);
|
||||
} else if (!nextLevelAnnotations.isEmpty()) {
|
||||
if (permitTypeAnnotationsPushBack) {
|
||||
this.typeAnnotationsPushedBack = nextLevelAnnotations;
|
||||
} else
|
||||
return illegal(nextLevelAnnotations.head.pos);
|
||||
}
|
||||
|
||||
int apos = S.pos();
|
||||
if (!annotations.isEmpty())
|
||||
t = F.at(apos).AnnotatedType(annotations, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) {
|
||||
/** BracketsOpt = {"[" TypeAnnotations "]"}
|
||||
*/
|
||||
private JCExpression bracketsOpt(JCExpression t) {
|
||||
return bracketsOpt(t, List.<JCTypeAnnotation>nil());
|
||||
}
|
||||
|
||||
private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
|
||||
List<JCTypeAnnotation> annotations) {
|
||||
accept(RBRACKET);
|
||||
t = bracketsOpt(t);
|
||||
t = bracketsOpt(t, annotations);
|
||||
return toP(F.at(pos).TypeArray(t));
|
||||
}
|
||||
|
||||
|
@ -1316,18 +1473,29 @@ public class JavacParser implements Parser {
|
|||
return t;
|
||||
}
|
||||
|
||||
/** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
|
||||
/** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
|
||||
*/
|
||||
JCExpression creator(int newpos, List<JCExpression> typeArgs) {
|
||||
|
||||
List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
|
||||
|
||||
switch (S.token()) {
|
||||
case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
|
||||
case DOUBLE: case BOOLEAN:
|
||||
if (typeArgs == null)
|
||||
return arrayCreatorRest(newpos, basicType());
|
||||
if (typeArgs == null) {
|
||||
if (newAnnotations.isEmpty())
|
||||
return arrayCreatorRest(newpos, basicType());
|
||||
else
|
||||
return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
JCExpression t = qualident();
|
||||
// handle type annotations for non primitive arrays
|
||||
if (!newAnnotations.isEmpty())
|
||||
t = F.AnnotatedType(newAnnotations, t);
|
||||
|
||||
int oldmode = mode;
|
||||
mode = TYPE;
|
||||
if (S.token() == LT) {
|
||||
|
@ -1344,7 +1512,7 @@ public class JavacParser implements Parser {
|
|||
}
|
||||
}
|
||||
mode = oldmode;
|
||||
if (S.token() == LBRACKET) {
|
||||
if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
|
||||
JCExpression e = arrayCreatorRest(newpos, t);
|
||||
if (typeArgs != null) {
|
||||
int pos = newpos;
|
||||
|
@ -1360,7 +1528,12 @@ public class JavacParser implements Parser {
|
|||
}
|
||||
return e;
|
||||
} else if (S.token() == LPAREN) {
|
||||
return classCreatorRest(newpos, null, typeArgs, t);
|
||||
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);
|
||||
}
|
||||
return newClass;
|
||||
} else {
|
||||
reportSyntaxError(S.pos(), "expected2",
|
||||
LPAREN, LBRACKET);
|
||||
|
@ -1380,40 +1553,73 @@ public class JavacParser implements Parser {
|
|||
return classCreatorRest(newpos, encl, typeArgs, t);
|
||||
}
|
||||
|
||||
/** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer
|
||||
* | Expression "]" {"[" Expression "]"} BracketsOpt )
|
||||
/** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
|
||||
* | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
|
||||
*/
|
||||
JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
|
||||
|
||||
List<JCTypeAnnotation> topAnnos = List.nil();
|
||||
if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
|
||||
JCAnnotatedType atype = (JCAnnotatedType) elemtype;
|
||||
topAnnos = atype.annotations;
|
||||
elemtype = atype.underlyingType;
|
||||
}
|
||||
|
||||
List<JCTypeAnnotation> annos = typeAnnotationsOpt();
|
||||
|
||||
accept(LBRACKET);
|
||||
|
||||
if (S.token() == RBRACKET) {
|
||||
accept(RBRACKET);
|
||||
elemtype = bracketsOpt(elemtype);
|
||||
|
||||
elemtype = bracketsOpt(elemtype, annos);
|
||||
|
||||
if (S.token() == LBRACE) {
|
||||
return arrayInitializer(newpos, elemtype);
|
||||
JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
|
||||
|
||||
na.annotations = topAnnos;
|
||||
|
||||
return na;
|
||||
} else {
|
||||
return syntaxError(S.pos(), "array.dimension.missing");
|
||||
}
|
||||
} else {
|
||||
ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
|
||||
|
||||
// maintain array dimension type annotations
|
||||
ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
|
||||
dimAnnotations.append(annos);
|
||||
|
||||
dims.append(parseExpression());
|
||||
accept(RBRACKET);
|
||||
while (S.token() == LBRACKET) {
|
||||
while (S.token() == LBRACKET
|
||||
|| (S.token() == MONKEYS_AT)) {
|
||||
List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
|
||||
int pos = S.pos();
|
||||
S.nextToken();
|
||||
if (S.token() == RBRACKET) {
|
||||
elemtype = bracketsOptCont(elemtype, pos);
|
||||
elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
|
||||
} else {
|
||||
dims.append(parseExpression());
|
||||
accept(RBRACKET);
|
||||
if (S.token() == RBRACKET) { // no dimension
|
||||
elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
|
||||
} else {
|
||||
dimAnnotations.append(maybeDimAnnos);
|
||||
dims.append(parseExpression());
|
||||
accept(RBRACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
|
||||
|
||||
JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
|
||||
na.annotations = topAnnos;
|
||||
na.dimAnnotations = dimAnnotations.toList();
|
||||
return na;
|
||||
}
|
||||
}
|
||||
|
||||
/** ClassCreatorRest = Arguments [ClassBody]
|
||||
*/
|
||||
JCExpression classCreatorRest(int newpos,
|
||||
JCNewClass classCreatorRest(int newpos,
|
||||
JCExpression encl,
|
||||
List<JCExpression> typeArgs,
|
||||
JCExpression t)
|
||||
|
@ -1860,17 +2066,32 @@ public class JavacParser implements Parser {
|
|||
new ListBuffer<JCExpressionStatement>()).toList();
|
||||
}
|
||||
|
||||
enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
|
||||
|
||||
/** AnnotationsOpt = { '@' Annotation }
|
||||
*/
|
||||
List<JCAnnotation> annotationsOpt() {
|
||||
List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
|
||||
if (S.token() != MONKEYS_AT) return List.nil(); // optimization
|
||||
ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
|
||||
int prevmode = mode;
|
||||
while (S.token() == MONKEYS_AT) {
|
||||
int pos = S.pos();
|
||||
S.nextToken();
|
||||
buf.append(annotation(pos));
|
||||
buf.append(annotation(pos, kind));
|
||||
}
|
||||
return buf.toList();
|
||||
lastmode = mode;
|
||||
mode = prevmode;
|
||||
List<JCAnnotation> annotations = buf.toList();
|
||||
|
||||
if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
|
||||
System.out.println("TA: parsing " + annotations
|
||||
+ " in " + log.currentSourceFile());
|
||||
return annotations;
|
||||
}
|
||||
|
||||
List<JCTypeAnnotation> typeAnnotationsOpt() {
|
||||
List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
|
||||
return List.convert(JCTypeAnnotation.class, annotations);
|
||||
}
|
||||
|
||||
/** ModifiersOpt = { Modifier }
|
||||
|
@ -1915,7 +2136,7 @@ public class JavacParser implements Parser {
|
|||
if (flag == Flags.ANNOTATION) {
|
||||
checkAnnotations();
|
||||
if (S.token() != INTERFACE) {
|
||||
JCAnnotation ann = annotation(lastPos);
|
||||
JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
|
||||
// if first modifier is an annotation, set pos to annotation's.
|
||||
if (flags == 0 && annotations.isEmpty())
|
||||
pos = ann.pos;
|
||||
|
@ -1946,12 +2167,18 @@ public class JavacParser implements Parser {
|
|||
/** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ]
|
||||
* @param pos position of "@" token
|
||||
*/
|
||||
JCAnnotation annotation(int pos) {
|
||||
JCAnnotation annotation(int pos, AnnotationKind kind) {
|
||||
// accept(AT); // AT consumed by caller
|
||||
checkAnnotations();
|
||||
if (kind == AnnotationKind.TYPE_ANNO)
|
||||
checkTypeAnnotations();
|
||||
JCTree ident = qualident();
|
||||
List<JCExpression> fieldValues = annotationFieldValuesOpt();
|
||||
JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
|
||||
JCAnnotation ann;
|
||||
if (kind == AnnotationKind.DEFAULT_ANNO)
|
||||
ann = F.at(pos).Annotation(ident, fieldValues);
|
||||
else
|
||||
ann = F.at(pos).TypeAnnotation(ident, fieldValues);
|
||||
storeEnd(ann, S.prevEndPos());
|
||||
return ann;
|
||||
}
|
||||
|
@ -2003,7 +2230,7 @@ public class JavacParser implements Parser {
|
|||
case MONKEYS_AT:
|
||||
pos = S.pos();
|
||||
S.nextToken();
|
||||
return annotation(pos);
|
||||
return annotation(pos, AnnotationKind.DEFAULT_ANNO);
|
||||
case LBRACE:
|
||||
pos = S.pos();
|
||||
accept(LBRACE);
|
||||
|
@ -2357,7 +2584,7 @@ public class JavacParser implements Parser {
|
|||
S.resetDeprecatedFlag();
|
||||
}
|
||||
int pos = S.pos();
|
||||
List<JCAnnotation> annotations = annotationsOpt();
|
||||
List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
|
||||
JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
|
||||
List<JCExpression> typeArgs = typeArgumentsOpt();
|
||||
int identPos = S.pos();
|
||||
|
@ -2460,16 +2687,23 @@ public class JavacParser implements Parser {
|
|||
if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
|
||||
mods.pos = pos;
|
||||
}
|
||||
|
||||
List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
|
||||
|
||||
Token token = S.token();
|
||||
Name name = S.name();
|
||||
pos = S.pos();
|
||||
JCExpression type;
|
||||
boolean isVoid = S.token() == VOID;
|
||||
if (isVoid) {
|
||||
if (annosAfterParams.nonEmpty())
|
||||
illegal(annosAfterParams.head.pos);
|
||||
type = to(F.at(pos).TypeIdent(TypeTags.VOID));
|
||||
S.nextToken();
|
||||
} else {
|
||||
type = parseType();
|
||||
mods.annotations = mods.annotations.appendList(annosAfterParams);
|
||||
// method returns types are un-annotated types
|
||||
type = unannotatedType();
|
||||
}
|
||||
if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
|
||||
if (isInterface || name != className)
|
||||
|
@ -2505,15 +2739,15 @@ public class JavacParser implements Parser {
|
|||
}
|
||||
|
||||
/** MethodDeclaratorRest =
|
||||
* FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
|
||||
* FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
|
||||
* VoidMethodDeclaratorRest =
|
||||
* FormalParameters [Throws TypeList] ( MethodBody | ";")
|
||||
* FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
|
||||
* InterfaceMethodDeclaratorRest =
|
||||
* FormalParameters BracketsOpt [THROWS TypeList] ";"
|
||||
* FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
|
||||
* VoidInterfaceMethodDeclaratorRest =
|
||||
* FormalParameters [THROWS TypeList] ";"
|
||||
* FormalParameters [Annotations] [THROWS TypeList] ";"
|
||||
* ConstructorDeclaratorRest =
|
||||
* "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
|
||||
* "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
|
||||
*/
|
||||
JCTree methodDeclaratorRest(int pos,
|
||||
JCModifiers mods,
|
||||
|
@ -2523,7 +2757,22 @@ public class JavacParser implements Parser {
|
|||
boolean isInterface, boolean isVoid,
|
||||
String dc) {
|
||||
List<JCVariableDecl> params = formalParameters();
|
||||
if (!isVoid) type = bracketsOpt(type);
|
||||
|
||||
List<JCTypeAnnotation> receiverAnnotations;
|
||||
if (!isVoid) {
|
||||
// need to distinguish between receiver anno and array anno
|
||||
// look at typeAnnotationsPushedBack comment
|
||||
this.permitTypeAnnotationsPushBack = true;
|
||||
type = methodReturnArrayRest(type);
|
||||
this.permitTypeAnnotationsPushBack = false;
|
||||
if (typeAnnotationsPushedBack == null)
|
||||
receiverAnnotations = List.nil();
|
||||
else
|
||||
receiverAnnotations = typeAnnotationsPushedBack;
|
||||
typeAnnotationsPushedBack = null;
|
||||
} else
|
||||
receiverAnnotations = typeAnnotationsOpt();
|
||||
|
||||
List<JCExpression> thrown = List.nil();
|
||||
if (S.token() == THROWS) {
|
||||
S.nextToken();
|
||||
|
@ -2552,20 +2801,51 @@ public class JavacParser implements Parser {
|
|||
}
|
||||
JCMethodDecl result =
|
||||
toP(F.at(pos).MethodDef(mods, name, type, typarams,
|
||||
params, thrown,
|
||||
params, receiverAnnotations, thrown,
|
||||
body, defaultValue));
|
||||
attach(result, dc);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** QualidentList = Qualident {"," Qualident}
|
||||
/** Parses the array levels after the format parameters list, and append
|
||||
* them to the return type, while preseving the order of type annotations
|
||||
*/
|
||||
private JCExpression methodReturnArrayRest(JCExpression type) {
|
||||
if (type.getTag() != JCTree.TYPEARRAY)
|
||||
return bracketsOpt(type);
|
||||
|
||||
JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
|
||||
while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
|
||||
baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
|
||||
|
||||
if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
|
||||
JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
|
||||
at.underlyingType = bracketsOpt(at.underlyingType);
|
||||
} else {
|
||||
baseArray.elemtype = bracketsOpt(baseArray.elemtype);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
|
||||
*/
|
||||
List<JCExpression> qualidentList() {
|
||||
ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
|
||||
ts.append(qualident());
|
||||
|
||||
List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
|
||||
if (!typeAnnos.isEmpty())
|
||||
ts.append(F.AnnotatedType(typeAnnos, qualident()));
|
||||
else
|
||||
ts.append(qualident());
|
||||
while (S.token() == COMMA) {
|
||||
S.nextToken();
|
||||
ts.append(qualident());
|
||||
|
||||
typeAnnos = typeAnnotationsOpt();
|
||||
if (!typeAnnos.isEmpty())
|
||||
ts.append(F.AnnotatedType(typeAnnos, qualident()));
|
||||
else
|
||||
ts.append(qualident());
|
||||
}
|
||||
return ts.toList();
|
||||
}
|
||||
|
@ -2589,12 +2869,13 @@ public class JavacParser implements Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/** TypeParameter = TypeVariable [TypeParameterBound]
|
||||
/** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
|
||||
* TypeParameterBound = EXTENDS Type {"&" Type}
|
||||
* TypeVariable = Ident
|
||||
*/
|
||||
JCTypeParameter typeParameter() {
|
||||
int pos = S.pos();
|
||||
List<JCTypeAnnotation> annos = typeAnnotationsOpt();
|
||||
Name name = ident();
|
||||
ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
|
||||
if (S.token() == EXTENDS) {
|
||||
|
@ -2605,7 +2886,7 @@ public class JavacParser implements Parser {
|
|||
bounds.append(parseType());
|
||||
}
|
||||
}
|
||||
return toP(F.at(pos).TypeParameter(name, bounds.toList()));
|
||||
return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
|
||||
}
|
||||
|
||||
/** FormalParameters = "(" [ FormalParameterList ] ")"
|
||||
|
@ -2639,12 +2920,31 @@ public class JavacParser implements Parser {
|
|||
*/
|
||||
JCVariableDecl formalParameter() {
|
||||
JCModifiers mods = optFinal(Flags.PARAMETER);
|
||||
// need to distinguish between vararg annos and array annos
|
||||
// look at typeAnnotaitonsPushedBack comment
|
||||
this.permitTypeAnnotationsPushBack = true;
|
||||
JCExpression type = parseType();
|
||||
this.permitTypeAnnotationsPushBack = false;
|
||||
|
||||
if (S.token() == ELLIPSIS) {
|
||||
List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
|
||||
typeAnnotationsPushedBack = null;
|
||||
checkVarargs();
|
||||
mods.flags |= Flags.VARARGS;
|
||||
// insert var arg type annotations
|
||||
if (varargsAnnos != null && varargsAnnos.nonEmpty())
|
||||
type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
|
||||
type = to(F.at(S.pos()).TypeArray(type));
|
||||
|
||||
S.nextToken();
|
||||
} else {
|
||||
// if not a var arg, then typeAnnotationsPushedBack should be null
|
||||
if (typeAnnotationsPushedBack != null
|
||||
&& !typeAnnotationsPushedBack.isEmpty()) {
|
||||
reportSyntaxError(typeAnnotationsPushedBack.head.pos,
|
||||
"illegal.start.of.type");
|
||||
}
|
||||
typeAnnotationsPushedBack = null;
|
||||
}
|
||||
return variableDeclaratorId(mods, type);
|
||||
}
|
||||
|
@ -2829,4 +3129,10 @@ public class JavacParser implements Parser {
|
|||
allowAnnotations = true;
|
||||
}
|
||||
}
|
||||
void checkTypeAnnotations() {
|
||||
if (!allowTypeAnnotations) {
|
||||
log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
|
||||
allowTypeAnnotations = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import javax.tools.StandardJavaFileManager;
|
|||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.DiagnosticListener;
|
||||
|
||||
import com.sun.source.util.AbstractTypeProcessor;
|
||||
import com.sun.source.util.TaskEvent;
|
||||
import com.sun.source.util.TaskListener;
|
||||
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||
|
@ -58,6 +59,7 @@ import com.sun.tools.javac.code.Symbol.*;
|
|||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
import com.sun.tools.javac.main.JavaCompiler.CompileState;
|
||||
import com.sun.tools.javac.model.JavacElements;
|
||||
import com.sun.tools.javac.model.JavacTypes;
|
||||
import com.sun.tools.javac.parser.*;
|
||||
|
@ -93,6 +95,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||
private final boolean lint;
|
||||
private final boolean procOnly;
|
||||
private final boolean fatalErrors;
|
||||
private boolean foundTypeProcessors;
|
||||
|
||||
private final JavacFiler filer;
|
||||
private final JavacMessager messager;
|
||||
|
@ -153,6 +156,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||
options.get("-Xprint") != null;
|
||||
fatalErrors = options.get("fatalEnterError") != null;
|
||||
platformAnnotations = initPlatformAnnotations();
|
||||
foundTypeProcessors = false;
|
||||
|
||||
// Initialize services before any processors are initialzied
|
||||
// in case processors use them.
|
||||
|
@ -670,6 +674,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||
}
|
||||
|
||||
if (matchedNames.size() > 0 || ps.contributed) {
|
||||
foundTypeProcessors = foundTypeProcessors || (ps.processor instanceof AbstractTypeProcessor);
|
||||
boolean processingResult = callProcessor(ps.processor, typeElements, renv);
|
||||
ps.contributed = true;
|
||||
ps.removeSupportedOptions(unmatchedProcessorOptions);
|
||||
|
@ -916,12 +921,16 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||
compiler.log.nerrors += messager.errorCount();
|
||||
if (compiler.errorCount() == 0)
|
||||
compiler.log.nerrors++;
|
||||
} else if (procOnly) {
|
||||
} else if (procOnly && !foundTypeProcessors) {
|
||||
compiler.todo.clear();
|
||||
} else { // Final compilation
|
||||
compiler.close(false);
|
||||
currentContext = contextForNextRound(currentContext, true);
|
||||
this.context = currentContext;
|
||||
updateProcessingState(currentContext, true);
|
||||
compiler = JavaCompiler.instance(currentContext);
|
||||
if (procOnly && foundTypeProcessors)
|
||||
compiler.shouldStopPolicy = CompileState.FLOW;
|
||||
|
||||
if (true) {
|
||||
compiler.enterTrees(cleanTrees(roots));
|
||||
|
@ -1213,6 +1222,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||
node.sym = null;
|
||||
super.visitIdent(node);
|
||||
}
|
||||
public void visitApply(JCMethodInvocation node) {
|
||||
scan(node.typeargs);
|
||||
super.visitApply(node);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@ import java.util.*;
|
|||
/**
|
||||
* Object providing state about a prior round of annotation processing.
|
||||
*
|
||||
* <p>The methods in this class do not take type annotations into account,
|
||||
* as target types, not java elements.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
|
|
|
@ -882,6 +882,8 @@ compiler.misc.bad.const.pool.tag.at=\
|
|||
bad constant pool tag: {0} at {1}
|
||||
compiler.misc.bad.signature=\
|
||||
bad signature: {0}
|
||||
compiler.misc.bad.type.annotation.value=\
|
||||
bad type annotation target type value: {0}
|
||||
compiler.misc.class.file.wrong.class=\
|
||||
class file contains wrong class: {0}
|
||||
compiler.misc.class.file.not.found=\
|
||||
|
@ -1162,6 +1164,10 @@ compiler.err.annotations.not.supported.in.source=\
|
|||
annotations are not supported in -source {0}\n\
|
||||
(use -source 5 or higher to enable annotations)
|
||||
|
||||
compiler.err.type.annotations.not.supported.in.source=\
|
||||
type annotations are not supported in -source {0}\n\
|
||||
(use -source 7 or higher to enable type annotations)
|
||||
|
||||
compiler.err.foreach.not.supported.in.source=\
|
||||
for-each loops are not supported in -source {0}\n\
|
||||
(use -source 5 or higher to enable for-each loops)
|
||||
|
|
|
@ -256,9 +256,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
*/
|
||||
public static final int MODIFIERS = ANNOTATION + 1;
|
||||
|
||||
public static final int ANNOTATED_TYPE = MODIFIERS + 1;
|
||||
|
||||
/** Error trees, of type Erroneous.
|
||||
*/
|
||||
public static final int ERRONEOUS = MODIFIERS + 1;
|
||||
public static final int ERRONEOUS = ANNOTATED_TYPE + 1;
|
||||
|
||||
/** Unary operators, of type Unary.
|
||||
*/
|
||||
|
@ -622,6 +624,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
public JCExpression restype;
|
||||
public List<JCTypeParameter> typarams;
|
||||
public List<JCVariableDecl> params;
|
||||
public List<JCTypeAnnotation> receiverAnnotations;
|
||||
public List<JCExpression> thrown;
|
||||
public JCBlock body;
|
||||
public JCExpression defaultValue; // for annotation types
|
||||
|
@ -631,6 +634,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
JCExpression restype,
|
||||
List<JCTypeParameter> typarams,
|
||||
List<JCVariableDecl> params,
|
||||
List<JCTypeAnnotation> receiver,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
JCExpression defaultValue,
|
||||
|
@ -641,6 +645,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
this.restype = restype;
|
||||
this.typarams = typarams;
|
||||
this.params = params;
|
||||
this.receiverAnnotations = (receiver != null ? receiver : List.<JCTypeAnnotation>nil());
|
||||
this.thrown = thrown;
|
||||
this.body = body;
|
||||
this.defaultValue = defaultValue;
|
||||
|
@ -659,6 +664,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
public List<JCVariableDecl> getParameters() {
|
||||
return params;
|
||||
}
|
||||
public List<JCTypeAnnotation> getReceiverAnnotations() { return receiverAnnotations; }
|
||||
public List<JCExpression> getThrows() {
|
||||
return thrown;
|
||||
}
|
||||
|
@ -1371,6 +1377,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
public static class JCNewArray extends JCExpression implements NewArrayTree {
|
||||
public JCExpression elemtype;
|
||||
public List<JCExpression> dims;
|
||||
public List<JCTypeAnnotation> annotations;
|
||||
public List<List<JCTypeAnnotation>> dimAnnotations;
|
||||
public List<JCExpression> elems;
|
||||
protected JCNewArray(JCExpression elemtype,
|
||||
List<JCExpression> dims,
|
||||
|
@ -1378,6 +1386,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
{
|
||||
this.elemtype = elemtype;
|
||||
this.dims = dims;
|
||||
this.annotations = List.nil();
|
||||
this.dimAnnotations = List.nil();
|
||||
this.elems = elems;
|
||||
}
|
||||
@Override
|
||||
|
@ -1860,9 +1870,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
public static class JCTypeParameter extends JCTree implements TypeParameterTree {
|
||||
public Name name;
|
||||
public List<JCExpression> bounds;
|
||||
protected JCTypeParameter(Name name, List<JCExpression> bounds) {
|
||||
public List<JCTypeAnnotation> annotations;
|
||||
protected JCTypeParameter(Name name, List<JCExpression> bounds, List<JCTypeAnnotation> annotations) {
|
||||
this.name = name;
|
||||
this.bounds = bounds;
|
||||
this.annotations = annotations;
|
||||
}
|
||||
@Override
|
||||
public void accept(Visitor v) { v.visitTypeParameter(this); }
|
||||
|
@ -1872,6 +1884,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
public List<JCExpression> getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
public List<JCTypeAnnotation> getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
@Override
|
||||
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
||||
return v.visitTypeParameter(this, d);
|
||||
|
@ -1962,6 +1977,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
}
|
||||
}
|
||||
|
||||
public static class JCTypeAnnotation extends JCAnnotation {
|
||||
public TypeAnnotationPosition annotation_position;
|
||||
public Attribute.TypeCompound attribute_field;
|
||||
|
||||
protected JCTypeAnnotation(JCTree annotationType, List<JCExpression> args) {
|
||||
super(annotationType, args);
|
||||
this.annotation_position = new TypeAnnotationPosition();
|
||||
}
|
||||
}
|
||||
|
||||
public static class JCModifiers extends JCTree implements com.sun.source.tree.ModifiersTree {
|
||||
public long flags;
|
||||
public List<JCAnnotation> annotations;
|
||||
|
@ -1989,6 +2014,33 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
}
|
||||
}
|
||||
|
||||
public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree {
|
||||
public List<JCTypeAnnotation> annotations;
|
||||
public JCExpression underlyingType;
|
||||
protected JCAnnotatedType(List<JCTypeAnnotation> annotations, JCExpression underlyingType) {
|
||||
this.annotations = annotations;
|
||||
this.underlyingType = underlyingType;
|
||||
}
|
||||
@Override
|
||||
public void accept(Visitor v) { v.visitAnnotatedType(this); }
|
||||
|
||||
public Kind getKind() { return Kind.ANNOTATED_TYPE; }
|
||||
public List<JCTypeAnnotation> getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
public JCExpression getUnderlyingType() {
|
||||
return underlyingType;
|
||||
}
|
||||
@Override
|
||||
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
||||
return v.visitAnnotatedType(this, d);
|
||||
}
|
||||
@Override
|
||||
public int getTag() {
|
||||
return ANNOTATED_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JCErroneous extends JCExpression
|
||||
implements com.sun.source.tree.ErroneousTree {
|
||||
public List<? extends JCTree> errs;
|
||||
|
@ -2056,6 +2108,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
JCExpression restype,
|
||||
List<JCTypeParameter> typarams,
|
||||
List<JCVariableDecl> params,
|
||||
List<JCTypeAnnotation> receiver,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
JCExpression defaultValue);
|
||||
|
@ -2172,6 +2225,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||
public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); }
|
||||
public void visitAnnotation(JCAnnotation that) { visitTree(that); }
|
||||
public void visitModifiers(JCModifiers that) { visitTree(that); }
|
||||
public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); }
|
||||
public void visitErroneous(JCErroneous that) { visitTree(that); }
|
||||
public void visitLetExpr(LetExpr that) { visitTree(that); }
|
||||
|
||||
|
|
|
@ -224,6 +224,15 @@ public class Pretty extends JCTree.Visitor {
|
|||
}
|
||||
}
|
||||
|
||||
public void printTypeAnnotations(List<JCTypeAnnotation> trees) throws IOException {
|
||||
if (trees.nonEmpty())
|
||||
print(" ");
|
||||
for (List<JCTypeAnnotation> l = trees; l.nonEmpty(); l = l.tail) {
|
||||
printExpr(l.head);
|
||||
print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
/** Print documentation comment, if it exists
|
||||
* @param tree The tree for which a documentation comment should be printed.
|
||||
*/
|
||||
|
@ -850,21 +859,33 @@ public class Pretty extends JCTree.Visitor {
|
|||
try {
|
||||
if (tree.elemtype != null) {
|
||||
print("new ");
|
||||
printTypeAnnotations(tree.annotations);
|
||||
JCTree elem = tree.elemtype;
|
||||
if (elem instanceof JCArrayTypeTree)
|
||||
printBaseElementType((JCArrayTypeTree) elem);
|
||||
else
|
||||
printExpr(elem);
|
||||
printBaseElementType(elem);
|
||||
boolean isElemAnnoType = elem instanceof JCAnnotatedType;
|
||||
int i = 0;
|
||||
List<List<JCTypeAnnotation>> da = tree.dimAnnotations;
|
||||
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
|
||||
if (da.size() > i) {
|
||||
printTypeAnnotations(da.get(i));
|
||||
}
|
||||
print("[");
|
||||
i++;
|
||||
printExpr(l.head);
|
||||
print("]");
|
||||
}
|
||||
if (tree.elems != null) {
|
||||
if (isElemAnnoType) {
|
||||
printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
|
||||
}
|
||||
print("[]");
|
||||
}
|
||||
if (isElemAnnoType)
|
||||
elem = ((JCAnnotatedType)elem).underlyingType;
|
||||
if (elem instanceof JCArrayTypeTree)
|
||||
printBrackets((JCArrayTypeTree) elem);
|
||||
}
|
||||
if (tree.elems != null) {
|
||||
if (tree.elemtype != null) print("[]");
|
||||
print("{");
|
||||
printExprs(tree.elems);
|
||||
print("}");
|
||||
|
@ -1112,14 +1133,21 @@ public class Pretty extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
// Prints the inner element type of a nested array
|
||||
private void printBaseElementType(JCArrayTypeTree tree) throws IOException {
|
||||
JCTree elem = tree.elemtype;
|
||||
while (elem instanceof JCWildcard)
|
||||
elem = ((JCWildcard) elem).inner;
|
||||
if (elem instanceof JCArrayTypeTree)
|
||||
printBaseElementType((JCArrayTypeTree) elem);
|
||||
else
|
||||
printExpr(elem);
|
||||
private void printBaseElementType(JCTree tree) throws IOException {
|
||||
switch (tree.getTag()) {
|
||||
case JCTree.TYPEARRAY:
|
||||
printBaseElementType(((JCArrayTypeTree)tree).elemtype);
|
||||
return;
|
||||
case JCTree.WILDCARD:
|
||||
printBaseElementType(((JCWildcard)tree).inner);
|
||||
return;
|
||||
case JCTree.ANNOTATED_TYPE:
|
||||
printBaseElementType(((JCAnnotatedType)tree).underlyingType);
|
||||
return;
|
||||
default:
|
||||
printExpr(tree);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// prints the brackets of a nested array in reverse order
|
||||
|
@ -1127,8 +1155,13 @@ public class Pretty extends JCTree.Visitor {
|
|||
JCTree elem;
|
||||
while (true) {
|
||||
elem = tree.elemtype;
|
||||
if (elem.getTag() == JCTree.ANNOTATED_TYPE) {
|
||||
JCAnnotatedType atype = (JCAnnotatedType) elem;
|
||||
printTypeAnnotations(atype.annotations);
|
||||
elem = atype.underlyingType;
|
||||
}
|
||||
print("[]");
|
||||
if (!(elem instanceof JCArrayTypeTree)) break;
|
||||
if (elem.getTag() != JCTree.TYPEARRAY) break;
|
||||
tree = (JCArrayTypeTree) elem;
|
||||
}
|
||||
}
|
||||
|
@ -1213,6 +1246,15 @@ public class Pretty extends JCTree.Visitor {
|
|||
}
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
try {
|
||||
printTypeAnnotations(tree.annotations);
|
||||
printExpr(tree.underlyingType);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitTree(JCTree tree) {
|
||||
try {
|
||||
print("(UNKNOWN: " + tree + ")");
|
||||
|
@ -1221,4 +1263,5 @@ public class Pretty extends JCTree.Visitor {
|
|||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,13 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
|||
return lb.toList();
|
||||
}
|
||||
|
||||
public JCTree visitAnnotatedType(AnnotatedTypeTree node, P p) {
|
||||
JCAnnotatedType t = (JCAnnotatedType) node;
|
||||
List<JCTypeAnnotation> annotations = copy(t.annotations, p);
|
||||
JCExpression underlyingType = copy(t.underlyingType, p);
|
||||
return M.at(t.pos).AnnotatedType(annotations, underlyingType);
|
||||
}
|
||||
|
||||
public JCTree visitAnnotation(AnnotationTree node, P p) {
|
||||
JCAnnotation t = (JCAnnotation) node;
|
||||
JCTree annotationType = copy(t.annotationType, p);
|
||||
|
@ -233,10 +240,11 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
|||
JCExpression restype = copy(t.restype, p);
|
||||
List<JCTypeParameter> typarams = copy(t.typarams, p);
|
||||
List<JCVariableDecl> params = copy(t.params, p);
|
||||
List<JCTypeAnnotation> receiver = copy(t.receiverAnnotations, p);
|
||||
List<JCExpression> thrown = copy(t.thrown, p);
|
||||
JCBlock body = copy(t.body, p);
|
||||
JCExpression defaultValue = copy(t.defaultValue, p);
|
||||
return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, thrown, body, defaultValue);
|
||||
return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, receiver, thrown, body, defaultValue);
|
||||
}
|
||||
|
||||
public JCTree visitMethodInvocation(MethodInvocationTree node, P p) {
|
||||
|
@ -357,8 +365,9 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
|||
|
||||
public JCTree visitTypeParameter(TypeParameterTree node, P p) {
|
||||
JCTypeParameter t = (JCTypeParameter) node;
|
||||
List<JCTypeAnnotation> annos = copy(t.annotations, p);
|
||||
List<JCExpression> bounds = copy(t.bounds, p);
|
||||
return M.at(t.pos).TypeParameter(t.name, t.bounds);
|
||||
return M.at(t.pos).TypeParameter(t.name, bounds, annos);
|
||||
}
|
||||
|
||||
public JCTree visitInstanceOf(InstanceOfTree node, P p) {
|
||||
|
|
|
@ -298,6 +298,8 @@ public class TreeInfo {
|
|||
case(JCTree.POSTINC):
|
||||
case(JCTree.POSTDEC):
|
||||
return getStartPos(((JCUnary) tree).arg);
|
||||
case(JCTree.ANNOTATED_TYPE):
|
||||
return getStartPos(((JCAnnotatedType) tree).underlyingType);
|
||||
case(JCTree.VARDEF): {
|
||||
JCVariableDecl node = (JCVariableDecl)tree;
|
||||
if (node.mods.pos != Position.NOPOS) {
|
||||
|
@ -859,4 +861,25 @@ public class TreeInfo {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying type of the tree if it is annotated type,
|
||||
* or the tree itself otherwise
|
||||
*/
|
||||
public static JCExpression typeIn(JCExpression tree) {
|
||||
switch (tree.getTag()) {
|
||||
case JCTree.ANNOTATED_TYPE:
|
||||
return ((JCAnnotatedType)tree).underlyingType;
|
||||
case JCTree.IDENT: /* simple names */
|
||||
case JCTree.TYPEIDENT: /* primitive name */
|
||||
case JCTree.SELECT: /* qualified name */
|
||||
case JCTree.TYPEARRAY: /* array types */
|
||||
case JCTree.WILDCARD: /* wild cards */
|
||||
case JCTree.TYPEPARAMETER: /* type parameters */
|
||||
case JCTree.TYPEAPPLY: /* parameterized types */
|
||||
return tree;
|
||||
default:
|
||||
throw new AssertionError("Unexpected type tree: " + tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,6 +168,20 @@ public class TreeMaker implements JCTree.Factory {
|
|||
List<JCVariableDecl> params,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
JCExpression defaultValue) {
|
||||
return MethodDef(
|
||||
mods, name, restype, typarams, params,
|
||||
null, thrown, body, defaultValue);
|
||||
}
|
||||
|
||||
public JCMethodDecl MethodDef(JCModifiers mods,
|
||||
Name name,
|
||||
JCExpression restype,
|
||||
List<JCTypeParameter> typarams,
|
||||
List<JCVariableDecl> params,
|
||||
List<JCTypeAnnotation> receiver,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
JCExpression defaultValue)
|
||||
{
|
||||
JCMethodDecl tree = new JCMethodDecl(mods,
|
||||
|
@ -175,6 +189,7 @@ public class TreeMaker implements JCTree.Factory {
|
|||
restype,
|
||||
typarams,
|
||||
params,
|
||||
receiver,
|
||||
thrown,
|
||||
body,
|
||||
defaultValue,
|
||||
|
@ -430,7 +445,11 @@ public class TreeMaker implements JCTree.Factory {
|
|||
}
|
||||
|
||||
public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
|
||||
JCTypeParameter tree = new JCTypeParameter(name, bounds);
|
||||
return TypeParameter(name, bounds, List.<JCTypeAnnotation>nil());
|
||||
}
|
||||
|
||||
public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCTypeAnnotation> annos) {
|
||||
JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
|
@ -453,6 +472,12 @@ public class TreeMaker implements JCTree.Factory {
|
|||
return tree;
|
||||
}
|
||||
|
||||
public JCTypeAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
|
||||
JCTypeAnnotation tree = new JCTypeAnnotation(annotationType, args);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
|
||||
public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
|
||||
JCModifiers tree = new JCModifiers(flags, annotations);
|
||||
boolean noFlags = (flags & Flags.StandardFlags) == 0;
|
||||
|
@ -464,6 +489,12 @@ public class TreeMaker implements JCTree.Factory {
|
|||
return Modifiers(flags, List.<JCAnnotation>nil());
|
||||
}
|
||||
|
||||
public JCAnnotatedType AnnotatedType(List<JCTypeAnnotation> annotations, JCExpression underlyingType) {
|
||||
JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
|
||||
public JCErroneous Erroneous() {
|
||||
return Erroneous(List.<JCTree>nil());
|
||||
}
|
||||
|
@ -772,6 +803,7 @@ public class TreeMaker implements JCTree.Factory {
|
|||
Type(mtype.getReturnType()),
|
||||
TypeParams(mtype.getTypeArguments()),
|
||||
Params(mtype.getParameterTypes(), m),
|
||||
null,
|
||||
Types(mtype.getThrownTypes()),
|
||||
body,
|
||||
null,
|
||||
|
|
|
@ -85,6 +85,7 @@ public class TreeScanner extends Visitor {
|
|||
scan(tree.restype);
|
||||
scan(tree.typarams);
|
||||
scan(tree.params);
|
||||
scan(tree.receiverAnnotations);
|
||||
scan(tree.thrown);
|
||||
scan(tree.defaultValue);
|
||||
scan(tree.body);
|
||||
|
@ -204,8 +205,11 @@ public class TreeScanner extends Visitor {
|
|||
}
|
||||
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
scan(tree.annotations);
|
||||
scan(tree.elemtype);
|
||||
scan(tree.dims);
|
||||
for (List<JCTypeAnnotation> annos : tree.dimAnnotations)
|
||||
scan(annos);
|
||||
scan(tree.elems);
|
||||
}
|
||||
|
||||
|
@ -270,6 +274,7 @@ public class TreeScanner extends Visitor {
|
|||
}
|
||||
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
scan(tree.annotations);
|
||||
scan(tree.bounds);
|
||||
}
|
||||
|
||||
|
@ -293,6 +298,11 @@ public class TreeScanner extends Visitor {
|
|||
scan(tree.args);
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
scan(tree.annotations);
|
||||
scan(tree.underlyingType);
|
||||
}
|
||||
|
||||
public void visitErroneous(JCErroneous tree) {
|
||||
}
|
||||
|
||||
|
|
|
@ -282,6 +282,11 @@ public class TreeTranslator extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
tree.annotations = translate(tree.annotations);
|
||||
List<List<JCTypeAnnotation>> dimAnnos = List.nil();
|
||||
for (List<JCTypeAnnotation> origDimAnnos : tree.dimAnnotations)
|
||||
dimAnnos = dimAnnos.append(translate(origDimAnnos));
|
||||
tree.dimAnnotations = dimAnnos;
|
||||
tree.elemtype = translate(tree.elemtype);
|
||||
tree.dims = translate(tree.dims);
|
||||
tree.elems = translate(tree.elems);
|
||||
|
@ -363,6 +368,7 @@ public class TreeTranslator extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
tree.annotations = translate(tree.annotations);
|
||||
tree.bounds = translate(tree.bounds);
|
||||
result = tree;
|
||||
}
|
||||
|
@ -400,6 +406,12 @@ public class TreeTranslator extends JCTree.Visitor {
|
|||
result = tree;
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
tree.annotations = translate(tree.annotations);
|
||||
tree.underlyingType = translate(tree.underlyingType);
|
||||
result = tree;
|
||||
}
|
||||
|
||||
public void visitTree(JCTree tree) {
|
||||
throw new AssertionError(tree);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,8 @@ public class Names {
|
|||
public final Name Annotation;
|
||||
public final Name RuntimeVisibleAnnotations;
|
||||
public final Name RuntimeInvisibleAnnotations;
|
||||
public final Name RuntimeVisibleTypeAnnotations;
|
||||
public final Name RuntimeInvisibleTypeAnnotations;
|
||||
public final Name RuntimeVisibleParameterAnnotations;
|
||||
public final Name RuntimeInvisibleParameterAnnotations;
|
||||
public final Name Value;
|
||||
|
@ -115,6 +117,8 @@ public class Names {
|
|||
public final Name getClass;
|
||||
public final Name invoke;
|
||||
public final Name TYPE;
|
||||
public final Name TYPE_USE;
|
||||
public final Name TYPE_PARAMETER;
|
||||
public final Name FIELD;
|
||||
public final Name METHOD;
|
||||
public final Name PARAMETER;
|
||||
|
@ -205,6 +209,8 @@ public class Names {
|
|||
Annotation = fromString("Annotation");
|
||||
RuntimeVisibleAnnotations = fromString("RuntimeVisibleAnnotations");
|
||||
RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
|
||||
RuntimeVisibleTypeAnnotations = fromString("RuntimeVisibleTypeAnnotations");
|
||||
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
||||
RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
|
||||
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
||||
Value = fromString("Value");
|
||||
|
@ -224,6 +230,8 @@ public class Names {
|
|||
invoke = fromString("invoke");
|
||||
|
||||
TYPE = fromString("TYPE");
|
||||
TYPE_USE = fromString("TYPE_USE");
|
||||
TYPE_PARAMETER = fromString("TYPE_PARAMETER");
|
||||
FIELD = fromString("FIELD");
|
||||
METHOD = fromString("METHOD");
|
||||
PARAMETER = fromString("PARAMETER");
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Annotation;
|
||||
import com.sun.tools.classfile.ExtendedAnnotation;
|
||||
import com.sun.tools.classfile.Annotation.Annotation_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Array_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Class_element_value;
|
||||
|
@ -62,6 +63,12 @@ public class AnnotationWriter extends BasicWriter {
|
|||
print(")");
|
||||
}
|
||||
|
||||
public void write(ExtendedAnnotation annot) {
|
||||
write(annot.annotation);
|
||||
print('@');
|
||||
print(annot.position.toString());
|
||||
}
|
||||
|
||||
public void write(Annotation.element_value_pair pair) {
|
||||
print("#" + pair.element_name_index + ":");
|
||||
write(pair.value);
|
||||
|
|
|
@ -51,8 +51,10 @@ import com.sun.tools.classfile.ModuleMemberTable_attribute;
|
|||
import com.sun.tools.classfile.Module_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
|
||||
import com.sun.tools.classfile.Signature_attribute;
|
||||
import com.sun.tools.classfile.SourceDebugExtension_attribute;
|
||||
import com.sun.tools.classfile.SourceFile_attribute;
|
||||
|
@ -434,6 +436,26 @@ public class AttributeWriter extends BasicWriter
|
|||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleTypeAnnotations: ");
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeInvisibleTypeAnnotations: ");
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleParameterAnnotations: ");
|
||||
for (int param = 0; param < attr.parameter_annotations.length; param++) {
|
||||
|
|
|
@ -54,7 +54,7 @@ public class MirroredTypeException extends RuntimeException {
|
|||
* @param type the type being accessed
|
||||
*/
|
||||
public MirroredTypeException(TypeMirror type) {
|
||||
super("Attempt to access Class object for TypeMirror " + type);
|
||||
super("Attempt to access Class object for TypeMirror " + type.toString());
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ public class T6341866 {
|
|||
processorServices.delete();
|
||||
|
||||
List<String> opts = new ArrayList<String>();
|
||||
opts.addAll(Arrays.asList("-d", ".", "-sourcepath", testSrc, "-classpath", testClasses));
|
||||
opts.addAll(Arrays.asList("-d", ".", "-sourcepath", testSrc, "-classpath", testClasses, "-source", "1.6"));
|
||||
if (implicitType.opt != null)
|
||||
opts.add(implicitType.opt);
|
||||
|
||||
|
|
124
langtools/test/tools/javac/api/TestTreePath.java
Normal file
124
langtools/test/tools/javac/api/TestTreePath.java
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 2006 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 6473148
|
||||
* @summary TreePath.iterator() throws NPE
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.util.*;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
public class TestTreePath extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundEnv) {
|
||||
final Trees trees = Trees.instance(this.processingEnv);
|
||||
for (Element element : ElementFilter.typesIn(roundEnv.getRootElements())) {
|
||||
checkTreePath(trees, element, 2);
|
||||
for (Element member : element.getEnclosedElements())
|
||||
checkTreePath(trees, member, 3);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkTreePath(Trees trees, Element element, int expectedLength) {
|
||||
TreePath path = trees.getPath(element);
|
||||
assert path != null;
|
||||
|
||||
int enhancedLength = 0;
|
||||
for (Tree tree : path)
|
||||
++enhancedLength;
|
||||
|
||||
if (enhancedLength != expectedLength)
|
||||
throw new RuntimeException("found path length is wrong");
|
||||
|
||||
int normalLoopLength = 0;
|
||||
Iterator<Tree> iter = path.iterator();
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
++normalLoopLength;
|
||||
}
|
||||
if (normalLoopLength != expectedLength)
|
||||
throw new RuntimeException("found path length is wrong");
|
||||
|
||||
TreePath curr = path;
|
||||
// using getParent
|
||||
int whileLoopLength = 0;
|
||||
while (curr != null) {
|
||||
++whileLoopLength;
|
||||
curr = curr.getParentPath();
|
||||
}
|
||||
if (whileLoopLength != expectedLength)
|
||||
throw new RuntimeException("found path length is wrong");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new FileWriter(f));
|
||||
out.println("class Test { void method() { } }");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
StandardJavaFileManager fileManager
|
||||
= compiler.getStandardFileManager(null, null, null);
|
||||
Iterable<? extends JavaFileObject> tests
|
||||
= fileManager.getJavaFileObjects(writeTestFile());
|
||||
|
||||
JavaCompiler.CompilationTask task =
|
||||
ToolProvider.getSystemJavaCompiler().getTask(
|
||||
null, null, null,
|
||||
Arrays.asList("-processor", this.getClass().getName()), null,
|
||||
tests);
|
||||
task.call();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new TestTreePath().run();
|
||||
}
|
||||
}
|
75
langtools/test/tools/javac/meth/InvokeMH_BAD68.java
Normal file
75
langtools/test/tools/javac/meth/InvokeMH_BAD68.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ##test
|
||||
* ##bug 6754038
|
||||
* ##summary Generate call sites for method handle
|
||||
* ##author jrose
|
||||
*
|
||||
* ##compile/fail -source 7 -target 7 InvokeMH_BAD68.java
|
||||
*/
|
||||
|
||||
/*
|
||||
* Standalone testing:
|
||||
* <code>
|
||||
* $ cd $MY_REPO_DIR/langtools
|
||||
* $ (cd make; make)
|
||||
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH_BAD68.java
|
||||
* $ javap -c -classpath dist meth.InvokeMH_BAD68
|
||||
* </code>
|
||||
*/
|
||||
|
||||
package meth;
|
||||
|
||||
import java.dyn.MethodHandle;
|
||||
|
||||
public class InvokeMH_BAD68 {
|
||||
void test(MethodHandle mh_SiO,
|
||||
MethodHandle mh_vS,
|
||||
MethodHandle mh_vi,
|
||||
MethodHandle mh_vv) {
|
||||
Object o; String s; int i; // for return type testing
|
||||
|
||||
// next five must have sig = (String,int)Object
|
||||
mh_SiO.invoke("world", 123);
|
||||
mh_SiO.invoke("mundus", 456);
|
||||
Object k = "kosmos";
|
||||
mh_SiO.invoke((String)k, 789);
|
||||
o = mh_SiO.invoke((String)null, 000);
|
||||
o = mh_SiO.<Object>invoke("arda", -123);
|
||||
|
||||
// sig = ()String
|
||||
s = mh_vS.<String>invoke();
|
||||
|
||||
// sig = ()int
|
||||
i = mh_vi.<int>invoke();
|
||||
o = mh_vi.<int>invoke();
|
||||
s = mh_vi.<int>invoke(); //BAD
|
||||
mh_vi.<int>invoke();
|
||||
|
||||
// sig = ()void
|
||||
//o = mh_vv.<void>invoke(); //BAD
|
||||
mh_vv.<void>invoke();
|
||||
}
|
||||
}
|
75
langtools/test/tools/javac/meth/InvokeMH_BAD72.java
Normal file
75
langtools/test/tools/javac/meth/InvokeMH_BAD72.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ##test
|
||||
* ##bug 6754038
|
||||
* ##summary Generate call sites for method handle
|
||||
* ##author jrose
|
||||
*
|
||||
* ##compile/fail -source 7 -target 7 InvokeMH_BAD72.java
|
||||
*/
|
||||
|
||||
/*
|
||||
* Standalone testing:
|
||||
* <code>
|
||||
* $ cd $MY_REPO_DIR/langtools
|
||||
* $ (cd make; make)
|
||||
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH_BAD72.java
|
||||
* $ javap -c -classpath dist meth.InvokeMH_BAD72
|
||||
* </code>
|
||||
*/
|
||||
|
||||
package meth;
|
||||
|
||||
import java.dyn.MethodHandle;
|
||||
|
||||
public class InvokeMH_BAD72 {
|
||||
void test(MethodHandle mh_SiO,
|
||||
MethodHandle mh_vS,
|
||||
MethodHandle mh_vi,
|
||||
MethodHandle mh_vv) {
|
||||
Object o; String s; int i; // for return type testing
|
||||
|
||||
// next five must have sig = (String,int)Object
|
||||
mh_SiO.invoke("world", 123);
|
||||
mh_SiO.invoke("mundus", 456);
|
||||
Object k = "kosmos";
|
||||
mh_SiO.invoke((String)k, 789);
|
||||
o = mh_SiO.invoke((String)null, 000);
|
||||
o = mh_SiO.<Object>invoke("arda", -123);
|
||||
|
||||
// sig = ()String
|
||||
s = mh_vS.<String>invoke();
|
||||
|
||||
// sig = ()int
|
||||
i = mh_vi.<int>invoke();
|
||||
o = mh_vi.<int>invoke();
|
||||
//s = mh_vi.<int>invoke(); //BAD
|
||||
mh_vi.<int>invoke();
|
||||
|
||||
// sig = ()void
|
||||
o = mh_vv.<void>invoke(); //BAD
|
||||
mh_vv.<void>invoke();
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ public class T6348499 {
|
|||
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java")));
|
||||
Iterable<String> opts = Arrays.asList("-proc:only",
|
||||
"-processor", "A",
|
||||
"-source", "1.6",
|
||||
"-processorpath", testClasses);
|
||||
StringWriter out = new StringWriter();
|
||||
JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
|
||||
|
|
|
@ -55,6 +55,7 @@ public class T6414633 {
|
|||
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java")));
|
||||
String[] opts = { "-proc:only",
|
||||
"-processor", A.class.getName(),
|
||||
"-source", "1.6",
|
||||
"-classpath", testClasses };
|
||||
JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files);
|
||||
task.call();
|
||||
|
|
|
@ -63,6 +63,7 @@ public class T6430209 {
|
|||
new File(testSrc, "test0.java"), new File(testSrc, "test1.java")));
|
||||
Iterable<String> opts = Arrays.asList("-proc:only",
|
||||
"-processor", "b6341534",
|
||||
"-source", "1.6",
|
||||
"-processorpath", testClasses);
|
||||
StringWriter out = new StringWriter();
|
||||
JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
|
||||
|
|
|
@ -49,7 +49,8 @@ public class T6439826 extends AbstractProcessor {
|
|||
StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
|
||||
Iterable<? extends JavaFileObject> files =
|
||||
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java")));
|
||||
Iterable<String> opts = Arrays.asList("-proc:only",
|
||||
Iterable<String> opts = Arrays.asList("-source","1.6",
|
||||
"-proc:only",
|
||||
"-processor", "T6439826",
|
||||
"-processorpath", testClasses);
|
||||
StringWriter out = new StringWriter();
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2009 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 6593082
|
||||
* @summary MirroredTypeException constructor should not accept null
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
|
||||
import javax.lang.model.type.*;
|
||||
|
||||
public class NpeTest {
|
||||
public static void main(String... args) {
|
||||
try {
|
||||
MirroredTypeException mte = new MirroredTypeException(null);
|
||||
throw new RuntimeException("Expected NPE not thrown.");
|
||||
} catch (NullPointerException npe) {
|
||||
; // success
|
||||
}
|
||||
}
|
||||
}
|
132
langtools/test/tools/javac/quid/QuotedIdent_BAD61.java
Normal file
132
langtools/test/tools/javac/quid/QuotedIdent_BAD61.java
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ##test
|
||||
* ##bug 6746458
|
||||
* ##summary Verify correct lexing of quoted identifiers.
|
||||
* ##author jrose
|
||||
*
|
||||
* ##library ..
|
||||
* ##run main quid.QuotedIdent_BAD61
|
||||
*/
|
||||
|
||||
/*
|
||||
* Standalone testing:
|
||||
* <code>
|
||||
* $ cd $MY_REPO_DIR/langtools
|
||||
* $ (cd make; make)
|
||||
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent_BAD61.java
|
||||
* $ java -version # should print 1.6 or later
|
||||
* $ java -cp dist quid.QuotedIdent_BAD61
|
||||
* </code>
|
||||
*/
|
||||
|
||||
package quid;
|
||||
|
||||
public class QuotedIdent_BAD61 {
|
||||
static void check(int testid, String have, String expect)
|
||||
throws RuntimeException {
|
||||
if ((have == null && have != expect) ||
|
||||
(have != null && !have.equals(expect))) {
|
||||
String msg =
|
||||
"TEST " + testid + ": HAVE \"" +
|
||||
have + "\" EXPECT \"" + expect + "\"";
|
||||
System.out.println("StringConversion: " + msg);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// negative tests:
|
||||
static class #"" { } //BAD empty ident name
|
||||
//static class #"<foo>" { } //BAD bad char in ident name
|
||||
/*static class /*(//BAD ident name interrupted by newline) #"jump:
|
||||
" { } /* uncomment previous line to attempt class w/ bad name */
|
||||
|
||||
static class #"int" extends Number {
|
||||
final int #"int";
|
||||
#"int"(int #"int") {
|
||||
this.#"int" = #"int";
|
||||
}
|
||||
static #"int" valueOf(int #"int") {
|
||||
return new #"int"(#"int");
|
||||
}
|
||||
public int intValue() { return #"int"; }
|
||||
public long longValue() { return #"int"; }
|
||||
public float floatValue() { return #"int"; }
|
||||
public double doubleValue() { return #"int"; }
|
||||
public String toString() { return String.valueOf(#"int"); }
|
||||
}
|
||||
|
||||
class #"*86" {
|
||||
String #"555-1212"() { return "[*86.555-1212]"; }
|
||||
}
|
||||
static#"*86"#"MAKE-*86"() { // note close spacing
|
||||
return new QuotedIdent_BAD61().new#"*86"();
|
||||
}
|
||||
|
||||
static String bar() { return "[bar]"; }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String s;
|
||||
|
||||
String #"sticky \' wicket" = "wicked ' stick";
|
||||
s = #"sticky ' wicket";
|
||||
check(11, s, "wicked \' stick");
|
||||
check(12, #"s", s);
|
||||
check(13, #"\163", s);
|
||||
|
||||
s = #"QuotedIdent_BAD61".bar();
|
||||
check(21, s, "[bar]");
|
||||
|
||||
s = #"int".valueOf(123).toString();
|
||||
check(22, s, "123");
|
||||
|
||||
s = #"MAKE-*86"().#"555-1212"();
|
||||
check(23, s, "[*86.555-1212]");
|
||||
|
||||
class#"{{{inmost}}}" { }
|
||||
s = new#"{{{inmost}}}"().getClass().getName();
|
||||
if (!s.endsWith("{{{inmost}}}"))
|
||||
check(24, s, "should end with \"{{{inmost}}}\"");
|
||||
|
||||
s = #"Yog-Shoggoth".#"(nameless ululation)";
|
||||
check(25, s, "Tekeli-li!");
|
||||
|
||||
s = #"int".class.getName();
|
||||
check(31, s, QuotedIdent_BAD61.class.getName()+"$int");
|
||||
|
||||
Class x86 = Class.forName(QuotedIdent_BAD61.class.getName()+"$*86");
|
||||
if (x86 != #"*86".class)
|
||||
check(32, "reflected "+x86, "static "+#"*86".class);
|
||||
|
||||
s = (String) x86.getDeclaredMethod("555-1212").invoke(#"MAKE-*86"());
|
||||
check(31, s, "[*86.555-1212]");
|
||||
|
||||
System.out.println("OK");
|
||||
}
|
||||
}
|
||||
|
||||
interface #"Yog-Shoggoth" {
|
||||
final String #"(nameless ululation)" = "Tekeli-li!";
|
||||
}
|
132
langtools/test/tools/javac/quid/QuotedIdent_BAD62.java
Normal file
132
langtools/test/tools/javac/quid/QuotedIdent_BAD62.java
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ##test
|
||||
* ##bug 6746458
|
||||
* ##summary Verify correct lexing of quoted identifiers.
|
||||
* ##author jrose
|
||||
*
|
||||
* ##library ..
|
||||
* ##run main quid.QuotedIdent_BAD62
|
||||
*/
|
||||
|
||||
/*
|
||||
* Standalone testing:
|
||||
* <code>
|
||||
* $ cd $MY_REPO_DIR/langtools
|
||||
* $ (cd make; make)
|
||||
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent_BAD62.java
|
||||
* $ java -version # should print 1.6 or later
|
||||
* $ java -cp dist quid.QuotedIdent_BAD62
|
||||
* </code>
|
||||
*/
|
||||
|
||||
package quid;
|
||||
|
||||
public class QuotedIdent_BAD62 {
|
||||
static void check(int testid, String have, String expect)
|
||||
throws RuntimeException {
|
||||
if ((have == null && have != expect) ||
|
||||
(have != null && !have.equals(expect))) {
|
||||
String msg =
|
||||
"TEST " + testid + ": HAVE \"" +
|
||||
have + "\" EXPECT \"" + expect + "\"";
|
||||
System.out.println("StringConversion: " + msg);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// negative tests:
|
||||
//static class #"" { } //BAD empty ident name
|
||||
static class #"<foo>" { } //BAD bad char in ident name
|
||||
/*static class /*(//BAD ident name interrupted by newline) #"jump:
|
||||
" { } /* uncomment previous line to attempt class w/ bad name */
|
||||
|
||||
static class #"int" extends Number {
|
||||
final int #"int";
|
||||
#"int"(int #"int") {
|
||||
this.#"int" = #"int";
|
||||
}
|
||||
static #"int" valueOf(int #"int") {
|
||||
return new #"int"(#"int");
|
||||
}
|
||||
public int intValue() { return #"int"; }
|
||||
public long longValue() { return #"int"; }
|
||||
public float floatValue() { return #"int"; }
|
||||
public double doubleValue() { return #"int"; }
|
||||
public String toString() { return String.valueOf(#"int"); }
|
||||
}
|
||||
|
||||
class #"*86" {
|
||||
String #"555-1212"() { return "[*86.555-1212]"; }
|
||||
}
|
||||
static#"*86"#"MAKE-*86"() { // note close spacing
|
||||
return new QuotedIdent_BAD62().new#"*86"();
|
||||
}
|
||||
|
||||
static String bar() { return "[bar]"; }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String s;
|
||||
|
||||
String #"sticky \' wicket" = "wicked ' stick";
|
||||
s = #"sticky ' wicket";
|
||||
check(11, s, "wicked \' stick");
|
||||
check(12, #"s", s);
|
||||
check(13, #"\163", s);
|
||||
|
||||
s = #"QuotedIdent_BAD62".bar();
|
||||
check(21, s, "[bar]");
|
||||
|
||||
s = #"int".valueOf(123).toString();
|
||||
check(22, s, "123");
|
||||
|
||||
s = #"MAKE-*86"().#"555-1212"();
|
||||
check(23, s, "[*86.555-1212]");
|
||||
|
||||
class#"{{{inmost}}}" { }
|
||||
s = new#"{{{inmost}}}"().getClass().getName();
|
||||
if (!s.endsWith("{{{inmost}}}"))
|
||||
check(24, s, "should end with \"{{{inmost}}}\"");
|
||||
|
||||
s = #"Yog-Shoggoth".#"(nameless ululation)";
|
||||
check(25, s, "Tekeli-li!");
|
||||
|
||||
s = #"int".class.getName();
|
||||
check(31, s, QuotedIdent_BAD62.class.getName()+"$int");
|
||||
|
||||
Class x86 = Class.forName(QuotedIdent_BAD62.class.getName()+"$*86");
|
||||
if (x86 != #"*86".class)
|
||||
check(32, "reflected "+x86, "static "+#"*86".class);
|
||||
|
||||
s = (String) x86.getDeclaredMethod("555-1212").invoke(#"MAKE-*86"());
|
||||
check(31, s, "[*86.555-1212]");
|
||||
|
||||
System.out.println("OK");
|
||||
}
|
||||
}
|
||||
|
||||
interface #"Yog-Shoggoth" {
|
||||
final String #"(nameless ululation)" = "Tekeli-li!";
|
||||
}
|
132
langtools/test/tools/javac/quid/QuotedIdent_BAD63.java
Normal file
132
langtools/test/tools/javac/quid/QuotedIdent_BAD63.java
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ##test
|
||||
* ##bug 6746458
|
||||
* ##summary Verify correct lexing of quoted identifiers.
|
||||
* ##author jrose
|
||||
*
|
||||
* ##library ..
|
||||
* ##run main quid.QuotedIdent_BAD63
|
||||
*/
|
||||
|
||||
/*
|
||||
* Standalone testing:
|
||||
* <code>
|
||||
* $ cd $MY_REPO_DIR/langtools
|
||||
* $ (cd make; make)
|
||||
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent_BAD63.java
|
||||
* $ java -version # should print 1.6 or later
|
||||
* $ java -cp dist quid.QuotedIdent_BAD63
|
||||
* </code>
|
||||
*/
|
||||
|
||||
package quid;
|
||||
|
||||
public class QuotedIdent_BAD63 {
|
||||
static void check(int testid, String have, String expect)
|
||||
throws RuntimeException {
|
||||
if ((have == null && have != expect) ||
|
||||
(have != null && !have.equals(expect))) {
|
||||
String msg =
|
||||
"TEST " + testid + ": HAVE \"" +
|
||||
have + "\" EXPECT \"" + expect + "\"";
|
||||
System.out.println("StringConversion: " + msg);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// negative tests:
|
||||
//static class #"" { } //BAD empty ident name
|
||||
//static class #"<foo>" { } //BAD bad char in ident name
|
||||
static class /*(//BAD ident name interrupted by newline) #"jump:
|
||||
" { } /* uncomment previous line to attempt class w/ bad name */
|
||||
|
||||
static class #"int" extends Number {
|
||||
final int #"int";
|
||||
#"int"(int #"int") {
|
||||
this.#"int" = #"int";
|
||||
}
|
||||
static #"int" valueOf(int #"int") {
|
||||
return new #"int"(#"int");
|
||||
}
|
||||
public int intValue() { return #"int"; }
|
||||
public long longValue() { return #"int"; }
|
||||
public float floatValue() { return #"int"; }
|
||||
public double doubleValue() { return #"int"; }
|
||||
public String toString() { return String.valueOf(#"int"); }
|
||||
}
|
||||
|
||||
class #"*86" {
|
||||
String #"555-1212"() { return "[*86.555-1212]"; }
|
||||
}
|
||||
static#"*86"#"MAKE-*86"() { // note close spacing
|
||||
return new QuotedIdent_BAD63().new#"*86"();
|
||||
}
|
||||
|
||||
static String bar() { return "[bar]"; }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String s;
|
||||
|
||||
String #"sticky \' wicket" = "wicked ' stick";
|
||||
s = #"sticky ' wicket";
|
||||
check(11, s, "wicked \' stick");
|
||||
check(12, #"s", s);
|
||||
check(13, #"\163", s);
|
||||
|
||||
s = #"QuotedIdent_BAD63".bar();
|
||||
check(21, s, "[bar]");
|
||||
|
||||
s = #"int".valueOf(123).toString();
|
||||
check(22, s, "123");
|
||||
|
||||
s = #"MAKE-*86"().#"555-1212"();
|
||||
check(23, s, "[*86.555-1212]");
|
||||
|
||||
class#"{{{inmost}}}" { }
|
||||
s = new#"{{{inmost}}}"().getClass().getName();
|
||||
if (!s.endsWith("{{{inmost}}}"))
|
||||
check(24, s, "should end with \"{{{inmost}}}\"");
|
||||
|
||||
s = #"Yog-Shoggoth".#"(nameless ululation)";
|
||||
check(25, s, "Tekeli-li!");
|
||||
|
||||
s = #"int".class.getName();
|
||||
check(31, s, QuotedIdent_BAD63.class.getName()+"$int");
|
||||
|
||||
Class x86 = Class.forName(QuotedIdent_BAD63.class.getName()+"$*86");
|
||||
if (x86 != #"*86".class)
|
||||
check(32, "reflected "+x86, "static "+#"*86".class);
|
||||
|
||||
s = (String) x86.getDeclaredMethod("555-1212").invoke(#"MAKE-*86"());
|
||||
check(31, s, "[*86.555-1212]");
|
||||
|
||||
System.out.println("OK");
|
||||
}
|
||||
}
|
||||
|
||||
interface #"Yog-Shoggoth" {
|
||||
final String #"(nameless ululation)" = "Tekeli-li!";
|
||||
}
|
38
langtools/test/tools/javac/typeAnnotations/InnerClass.java
Normal file
38
langtools/test/tools/javac/typeAnnotations/InnerClass.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2009 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 6843077
|
||||
* @summary compiler crashes when visiting inner classes
|
||||
* @author Mahmood Ali
|
||||
* @compile -source 1.7 InnerClass.java
|
||||
*/
|
||||
|
||||
class InnerClass {
|
||||
private void a() {
|
||||
new Object() {
|
||||
public <R> void method() { }
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check that type annotations may appear on void method if it is a
|
||||
* method annotation too.
|
||||
* @author Mahmood Ali
|
||||
* @compile -source 1.7 MultipleTargets.java
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
class TypeUseTarget<K extends @A Object> {
|
||||
@A void voidMethod() { }
|
||||
}
|
||||
|
||||
@Target({ElementType.TYPE_USE, ElementType.METHOD})
|
||||
@interface A { }
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check that type annotations may appear on all type parameter
|
||||
* @author Mahmood Ali
|
||||
* @compile -source 1.7 TypeParameterTarget.java
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
class TypeUseTarget<@A K extends Object> {
|
||||
String[] field;
|
||||
|
||||
<@A K, @A V> String genericMethod(K k) { return null; }
|
||||
}
|
||||
|
||||
interface MyInterface { }
|
||||
|
||||
@interface MyAnnotation { }
|
||||
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
@interface A { }
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check that type annotations may appear on all type declarations
|
||||
* @author Mahmood Ali
|
||||
* @compile -source 1.7 TypeUseTarget.java
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
@A
|
||||
class TypeUseTarget<K extends @A Object> {
|
||||
@A String @A [] field;
|
||||
|
||||
@A String test(@A String param, @A String @A ... vararg) @A {
|
||||
@A Object o = new @A String @A [3];
|
||||
TypeUseTarget<@A String> target;
|
||||
return (@A String) null;
|
||||
}
|
||||
|
||||
<K> @A String genericMethod(K k) { return null; }
|
||||
}
|
||||
|
||||
@A
|
||||
interface MyInterface { }
|
||||
|
||||
@A
|
||||
@interface MyAnnotation { }
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface A { }
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test scopes of attribution
|
||||
* @author Mahmood Ali
|
||||
* @compile -source 1.7 Scopes.java
|
||||
*/
|
||||
class Scopes {
|
||||
|
||||
void test() @A(VALUE) { }
|
||||
void test1() @A(value=VALUE) { }
|
||||
|
||||
private static final int VALUE = 1;
|
||||
@interface A { int value(); }
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test that only java 7 allows type annotations
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=AnnotationVersion.out -XDrawDiagnostics -source 1.6 AnnotationVersion.java
|
||||
*/
|
||||
class AnnotationVersion {
|
||||
public void method() @A { }
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
AnnotationVersion.java:32:25: compiler.err.type.annotations.not.supported.in.source: 1.6
|
||||
1 error
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test incomplete array declaration
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=IncompleteArray.out -XDrawDiagnostics -source 1.7 IncompleteArray.java
|
||||
*/
|
||||
class IncompleteArray {
|
||||
int @A [] @A var;
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
IncompleteArray.java:32:13: compiler.err.illegal.start.of.type
|
||||
1 error
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test incomplete vararg declaration
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=IncompleteVararg.out -XDrawDiagnostics -source 1.7 IncompleteVararg.java
|
||||
*/
|
||||
class IncompleteArray {
|
||||
// the last variable may be vararg
|
||||
void method(int @A test) { }
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
IncompleteVararg.java:33:19: compiler.err.illegal.start.of.type
|
||||
1 error
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test indexing of an array
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=IndexArray.out -XDrawDiagnostics -source 1.7 IndexArray.java
|
||||
*/
|
||||
class IndexArray {
|
||||
int[] var;
|
||||
int a = var @A [1];
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
IndexArray.java:33:15: compiler.err.illegal.start.of.expr
|
||||
1 error
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test that compiler doesn't warn about annotated redundant casts
|
||||
* @author Mahmood Ali
|
||||
* @compile/ref=LintCast.out -Xlint:cast -XDrawDiagnostics -source 1.7 LintCast.java
|
||||
*/
|
||||
class LintCast {
|
||||
void unparameterized() {
|
||||
String s = "m";
|
||||
String s1 = (String)s;
|
||||
String s2 = (@A String)s;
|
||||
}
|
||||
|
||||
void parameterized() {
|
||||
List<String> l = null;
|
||||
List<String> l1 = (List<String>)l;
|
||||
List<String> l2 = (List<@A String>)l;
|
||||
}
|
||||
|
||||
void array() {
|
||||
int @A [] a = null;
|
||||
int[] a1 = (int[])a;
|
||||
int[] a2 = (int @A [])a;
|
||||
}
|
||||
|
||||
void sameAnnotations() {
|
||||
@A String annotated = null;
|
||||
String unannotated = null;
|
||||
|
||||
// compiler ignore annotated casts even if redundant
|
||||
@A String anno1 = (@A String)annotated;
|
||||
|
||||
// warn if redundant without an annotation
|
||||
String anno2 = (String)annotated;
|
||||
String unanno2 = (String)unannotated;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,6 @@
|
|||
LintCast.java:36:21: compiler.warn.redundant.cast: java.lang.String
|
||||
LintCast.java:42:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
|
||||
LintCast.java:48:20: compiler.warn.redundant.cast: int[]
|
||||
LintCast.java:60:24: compiler.warn.redundant.cast: java.lang.String
|
||||
LintCast.java:61:26: compiler.warn.redundant.cast: java.lang.String
|
||||
5 warnings
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test old array syntax
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail -XDrawDiagnostics -source 1.7 OldArray.java
|
||||
*/
|
||||
class OldArray {
|
||||
String [@A] s() { return null; }
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check that A is accessible in the class type parameters
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=Scopes.out -XDrawDiagnostics -source 1.7 Scopes.java
|
||||
*/
|
||||
class Scopes<T extends @UniqueInner Object> {
|
||||
@interface UniqueInner { };
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
Scopes.java:31:25: compiler.err.cant.resolve: kindname.class, UniqueInner, ,
|
||||
1 error
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary static field access isn't a valid location
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=StaticFields.out -XDrawDiagnostics -source 1.7 StaticFields.java
|
||||
*/
|
||||
class C {
|
||||
int f;
|
||||
int a = @A C.f;
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
StaticFields.java:33:17: compiler.err.illegal.start.of.expr
|
||||
1 error
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary static methods don't have receivers
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=StaticMethods.out -XDrawDiagnostics -source 1.7 StaticMethods.java
|
||||
*/
|
||||
class StaticMethods {
|
||||
static void main() @A { }
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
StaticMethods.java:32:22: compiler.err.annotation.type.not.applicable
|
||||
1 error
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test type annotation on void generic methods
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail -source 1.7 VoidGenericMethod.java
|
||||
*/
|
||||
class VoidGenericMethod {
|
||||
public <T> @A void method() { }
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for duplicate annotation values
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics -source 1.7 DuplicateAnnotationValue.java
|
||||
*/
|
||||
class DuplicateAnnotationValue {
|
||||
void test() {
|
||||
Object a = String @A(value = 2, value = 1) [].class;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { int value(); }
|
|
@ -0,0 +1,2 @@
|
|||
DuplicateAnnotationValue.java:33:45: compiler.err.duplicate.annotation.member.value: value, A
|
||||
1 error
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for duplicate annotations
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics -source 1.7 DuplicateTypeAnnotation.java
|
||||
*/
|
||||
|
||||
class DuplicateTypeAnnotation {
|
||||
void test() {
|
||||
Object a = String @A @A [].class;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
DuplicateTypeAnnotation.java:34:26: compiler.err.duplicate.annotation
|
||||
1 error
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for invalid annotatins given the target
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics -source 1.7 InvalidLocation.java
|
||||
*/
|
||||
|
||||
class InvalidLocation {
|
||||
void test() {
|
||||
Object a = String @A [].class;
|
||||
}
|
||||
}
|
||||
|
||||
@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE)
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
InvalidLocation.java:34:23: compiler.err.annotation.type.not.applicable
|
||||
1 error
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for missing annotation value
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics -source 1.7 MissingAnnotationValue.java
|
||||
*/
|
||||
class MissingAnnotationValue {
|
||||
void test() {
|
||||
Object a = String @A [].class;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { int field(); }
|
|
@ -0,0 +1,2 @@
|
|||
MissingAnnotationValue.java:33:23: compiler.err.annotation.missing.default.value: A, field
|
||||
1 error
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for duplicate annotation values
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics -source 1.7 DuplicateAnnotationValue.java
|
||||
*/
|
||||
class DuplicateAnnotationValue {
|
||||
void test() {
|
||||
String @A(value = 2, value = 1) [] s;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { int value(); }
|
|
@ -0,0 +1,2 @@
|
|||
DuplicateAnnotationValue.java:33:34: compiler.err.duplicate.annotation.member.value: value, A
|
||||
1 error
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for duplicate annotations
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics -source 1.7 DuplicateTypeAnnotation.java
|
||||
*/
|
||||
|
||||
class DuplicateTypeAnnotation {
|
||||
void test() {
|
||||
String @A @A [] s;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
DuplicateTypeAnnotation.java:34:15: compiler.err.duplicate.annotation
|
||||
1 error
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for invalid annotatins given the target
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics -source 1.7 InvalidLocation.java
|
||||
*/
|
||||
|
||||
class InvalidLocation {
|
||||
void test() {
|
||||
String @A [] s;
|
||||
}
|
||||
}
|
||||
|
||||
@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE)
|
||||
@interface A { }
|
|
@ -0,0 +1,2 @@
|
|||
InvalidLocation.java:34:12: compiler.err.annotation.type.not.applicable
|
||||
1 error
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary check for missing annotation value
|
||||
* @author Mahmood Ali
|
||||
* @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics -source 1.7 MissingAnnotationValue.java
|
||||
*/
|
||||
class MissingAnnotationValue {
|
||||
void test() {
|
||||
String @A [] s;
|
||||
}
|
||||
}
|
||||
|
||||
@interface A { int field(); }
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue