8006775: JSR 308: Compiler changes in JDK8
Co-authored-by: Werner Dietl <wmdietl@cs.washington.edu> Co-authored-by: Matt Papi <mpapi@csail.mit.edu> Co-authored-by: Mahmood Ali <mahmood@notnoop.com> Reviewed-by: jjg
This commit is contained in:
parent
5b1a78dc92
commit
659a96edf9
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.javadoc;
|
||||
|
||||
|
||||
/**
|
||||
* Represents an annotated type.
|
||||
* For example:
|
||||
* <pre>
|
||||
* {@code @NonNull String}
|
||||
* {@code @Positive int}
|
||||
* </pre>
|
||||
*
|
||||
* @author Mahmood Ali
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedType extends Type {
|
||||
|
||||
AnnotationDesc[] annotations();
|
||||
|
||||
Type underlyingType();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,6 +87,15 @@ public interface ExecutableMemberDoc extends MemberDoc {
|
||||
*/
|
||||
Parameter[] parameters();
|
||||
|
||||
/**
|
||||
* Get the receiver annotations of this executable element.
|
||||
* Return an empty array if there are none.
|
||||
*
|
||||
* @return the receiver annotations of this executable element.
|
||||
* @since 1.8
|
||||
*/
|
||||
AnnotationDesc[] receiverAnnotations();
|
||||
|
||||
/**
|
||||
* Return the throws tags in this method.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -141,6 +141,16 @@ public interface Type {
|
||||
*/
|
||||
WildcardType asWildcardType();
|
||||
|
||||
/**
|
||||
* Returns this type as a <code>AnnotatedType</code> if it represents
|
||||
* an annotated type.
|
||||
*
|
||||
* @return a <code>AnnotatedType</code> if the type if an annotated type,
|
||||
* or null if it is not
|
||||
* @since 1.8
|
||||
*/
|
||||
AnnotatedType asAnnotatedType();
|
||||
|
||||
/**
|
||||
* Return this type as an <code>AnnotationTypeDoc</code> if it represents
|
||||
* an annotation type. Array dimensions are ignored.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -55,4 +55,11 @@ public interface TypeVariable extends Type {
|
||||
* which this type variable is declared.
|
||||
*/
|
||||
ProgramElementDoc owner();
|
||||
|
||||
/**
|
||||
* Get the annotations of this program element.
|
||||
* Return an empty array if there are none.
|
||||
*/
|
||||
public AnnotationDesc[] annotations();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.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.8
|
||||
*/
|
||||
public interface AnnotatedTypeTree extends ExpressionTree {
|
||||
List<? extends AnnotationTree> getAnnotations();
|
||||
ExpressionTree getUnderlyingType();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,6 +52,7 @@ public interface MethodTree extends Tree {
|
||||
Tree getReturnType();
|
||||
List<? extends TypeParameterTree> getTypeParameters();
|
||||
List<? extends VariableTree> getParameters();
|
||||
VariableTree getReceiverParameter();
|
||||
List<? extends ExpressionTree> getThrows();
|
||||
BlockTree getBody();
|
||||
Tree getDefaultValue(); // for annotation types
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,11 +46,20 @@ public interface Tree {
|
||||
*/
|
||||
public enum Kind {
|
||||
|
||||
ANNOTATED_TYPE(AnnotatedTypeTree.class),
|
||||
|
||||
/**
|
||||
* Used for instances of {@link AnnotationTree}.
|
||||
* Used for instances of {@link AnnotationTree}
|
||||
* representing declaration annotations.
|
||||
*/
|
||||
ANNOTATION(AnnotationTree.class),
|
||||
|
||||
/**
|
||||
* Used for instances of {@link AnnotationTree}
|
||||
* representing type annotations.
|
||||
*/
|
||||
TYPE_ANNOTATION(AnnotationTree.class),
|
||||
|
||||
/**
|
||||
* Used for instances of {@link ArrayAccessTree}.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -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();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -260,6 +260,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);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,7 +60,7 @@ public final class TaskEvent
|
||||
**/
|
||||
GENERATE,
|
||||
/**
|
||||
* For events relating to overall annotaion processing.
|
||||
* For events relating to overall annotation processing.
|
||||
**/
|
||||
ANNOTATION_PROCESSING,
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -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.getReceiverParameter(), p, r);
|
||||
r = scanAndReduce(node.getThrows(), p, r);
|
||||
r = scanAndReduce(node.getBody(), p, r);
|
||||
r = scanAndReduce(node.getDefaultValue(), p, r);
|
||||
@ -376,7 +377,8 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
||||
}
|
||||
|
||||
public R visitTypeParameter(TypeParameterTree node, P p) {
|
||||
R r = scan(node.getBounds(), p);
|
||||
R r = scan(node.getAnnotations(), p);
|
||||
r = scanAndReduce(node.getBounds(), p, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -394,6 +396,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;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,6 +56,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";
|
||||
@ -120,6 +122,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);
|
||||
}
|
||||
@ -178,6 +182,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,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -498,6 +498,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)
|
||||
@ -657,6 +667,12 @@ public class ClassWriter {
|
||||
write(anno, out);
|
||||
}
|
||||
|
||||
public void write(TypeAnnotation[] annos, ClassOutputStream out) {
|
||||
out.writeShort(annos.length);
|
||||
for (TypeAnnotation anno: annos)
|
||||
write(anno, out);
|
||||
}
|
||||
|
||||
public void write(Annotation anno, ClassOutputStream out) {
|
||||
out.writeShort(anno.type_index);
|
||||
out.writeShort(anno.element_value_pairs.length);
|
||||
@ -664,6 +680,11 @@ public class ClassWriter {
|
||||
write(p, out);
|
||||
}
|
||||
|
||||
public void write(TypeAnnotation anno, ClassOutputStream out) {
|
||||
write(anno.position, out);
|
||||
write(anno.annotation, out);
|
||||
}
|
||||
|
||||
public void write(element_value_pair pair, ClassOutputStream out) {
|
||||
out.writeShort(pair.element_name_index);
|
||||
write(pair.value, out);
|
||||
@ -702,5 +723,89 @@ public class ClassWriter {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Move this to TypeAnnotation to be closer with similar logic?
|
||||
private void write(TypeAnnotation.Position p, ClassOutputStream out) {
|
||||
out.writeByte(p.type.targetTypeValue());
|
||||
switch (p.type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
out.writeShort(p.offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
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;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
out.writeByte(p.exception_index);
|
||||
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 METHOD_TYPE_PARAMETER_BOUND:
|
||||
out.writeByte(p.parameter_index);
|
||||
out.writeByte(p.bound_index);
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
out.writeByte(p.type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
out.writeByte(p.type_index);
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
out.writeByte(p.parameter_index);
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
out.writeShort(p.offset);
|
||||
out.writeByte(p.type_index);
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
out.writeByte(p.parameter_index);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
|
||||
default:
|
||||
throw new AssertionError("ClassWriter: Unknown target type for position: " + p);
|
||||
}
|
||||
|
||||
{ // Append location data for generics/arrays.
|
||||
// TODO: check for overrun?
|
||||
out.writeByte((byte)p.location.size());
|
||||
for (int i : TypeAnnotation.Position.getBinaryFromTypePath(p.location))
|
||||
out.writeByte((byte)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, Section 3.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* 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, TypeAnnotation[] annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeInvisibleTypeAnnotations), annotations);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleTypeAnnotations_attribute(int name_index, TypeAnnotation[] 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 (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, Section 3.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* 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 TypeAnnotation[num_annotations];
|
||||
for (int i = 0; i < annotations.length; i++)
|
||||
annotations[i] = new TypeAnnotation(cr);
|
||||
}
|
||||
|
||||
protected RuntimeTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) {
|
||||
super(name_index, length(annotations));
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
private static int length(TypeAnnotation[] annos) {
|
||||
int n = 2;
|
||||
for (TypeAnnotation anno: annos)
|
||||
n += anno.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public final TypeAnnotation[] annotations;
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, Section 3.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* 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, TypeAnnotation[] annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeVisibleTypeAnnotations), annotations);
|
||||
}
|
||||
|
||||
public RuntimeVisibleTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) {
|
||||
super(name_index, annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeVisibleTypeAnnotations(this, p);
|
||||
}
|
||||
}
|
@ -0,0 +1,656 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.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.List;
|
||||
|
||||
import com.sun.tools.classfile.TypeAnnotation.Position.TypePathEntry;
|
||||
|
||||
/**
|
||||
* See JSR 308 specification, Section 3.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* 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 TypeAnnotation {
|
||||
TypeAnnotation(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
|
||||
constant_pool = cr.getConstantPool();
|
||||
position = read_position(cr);
|
||||
annotation = new Annotation(cr);
|
||||
}
|
||||
|
||||
public TypeAnnotation(ConstantPool constant_pool,
|
||||
Annotation annotation, Position position) {
|
||||
this.constant_pool = constant_pool;
|
||||
this.position = position;
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int n = annotation.length();
|
||||
n += position_length(position);
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return "@" + constant_pool.getUTF8Value(annotation.type_index).toString().substring(1) +
|
||||
" pos: " + position.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public final ConstantPool constant_pool;
|
||||
public final Position position;
|
||||
public final Annotation annotation;
|
||||
|
||||
private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
|
||||
// Copied from ClassReader
|
||||
int tag = cr.readUnsignedByte(); // TargetType tag is a byte
|
||||
if (!TargetType.isValidTargetTypeValue(tag))
|
||||
throw new Annotation.InvalidAnnotation("TypeAnnotation: Invalid type annotation target type value: " + String.format("0x%02X", tag));
|
||||
|
||||
TargetType type = TargetType.fromTargetTypeValue(tag);
|
||||
|
||||
Position position = new Position();
|
||||
position.type = type;
|
||||
|
||||
switch (type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
position.offset = cr.readUnsignedShort();
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
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;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
position.exception_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// type parameter bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
position.bound_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
int in = cr.readUnsignedShort();
|
||||
if (in == 0xFFFF)
|
||||
in = -1;
|
||||
position.type_index = in;
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
position.type_index = cr.readUnsignedShort();
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
position.offset = cr.readUnsignedShort();
|
||||
position.type_index = cr.readUnsignedByte();
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
position.parameter_index = cr.readUnsignedByte();
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
|
||||
default:
|
||||
throw new AssertionError("TypeAnnotation: Unknown target type: " + type);
|
||||
}
|
||||
|
||||
{ // Write type path
|
||||
int len = cr.readUnsignedByte();
|
||||
List<Integer> loc = new ArrayList<Integer>(len);
|
||||
for (int i = 0; i < len * TypePathEntry.bytesPerEntry; ++i)
|
||||
loc.add(cr.readUnsignedByte());
|
||||
position.location = Position.getTypePathFromBinary(loc);
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
private static int position_length(Position pos) {
|
||||
int n = 0;
|
||||
n += 1; // TargetType tag is a byte
|
||||
switch (pos.type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
n += 2;
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
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;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
n += 1; // exception_index
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
n += 1; // parameter_index;
|
||||
break;
|
||||
// type parameter bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
n += 1; // parameter_index
|
||||
n += 1; // bound_index
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
n += 2; // type_index
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
n += 2; // type_index
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
n += 1; // parameter_index
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
n += 2; // offset
|
||||
n += 1; // type index
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
n += 1; // parameter_index
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
|
||||
default:
|
||||
throw new AssertionError("TypeAnnotation: Unknown target type: " + pos.type);
|
||||
}
|
||||
|
||||
{
|
||||
n += 1; // length
|
||||
n += TypePathEntry.bytesPerEntry * pos.location.size(); // bytes for actual array
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// Code duplicated from com.sun.tools.javac.code.TypeAnnotationPosition
|
||||
public static class Position {
|
||||
public enum TypePathEntryKind {
|
||||
ARRAY(0),
|
||||
INNER_TYPE(1),
|
||||
WILDCARD(2),
|
||||
TYPE_ARGUMENT(3);
|
||||
|
||||
public final int tag;
|
||||
|
||||
private TypePathEntryKind(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypePathEntry {
|
||||
/** The fixed number of bytes per TypePathEntry. */
|
||||
public static final int bytesPerEntry = 2;
|
||||
|
||||
public final TypePathEntryKind tag;
|
||||
public final int arg;
|
||||
|
||||
public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
|
||||
public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
|
||||
public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
|
||||
|
||||
private TypePathEntry(TypePathEntryKind tag) {
|
||||
if (!(tag == TypePathEntryKind.ARRAY ||
|
||||
tag == TypePathEntryKind.INNER_TYPE ||
|
||||
tag == TypePathEntryKind.WILDCARD)) {
|
||||
throw new AssertionError("Invalid TypePathEntryKind: " + tag);
|
||||
}
|
||||
this.tag = tag;
|
||||
this.arg = 0;
|
||||
}
|
||||
|
||||
public TypePathEntry(TypePathEntryKind tag, int arg) {
|
||||
if (tag != TypePathEntryKind.TYPE_ARGUMENT) {
|
||||
throw new AssertionError("Invalid TypePathEntryKind: " + tag);
|
||||
}
|
||||
this.tag = tag;
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
public static TypePathEntry fromBinary(int tag, int arg) {
|
||||
if (arg != 0 && tag != TypePathEntryKind.TYPE_ARGUMENT.tag) {
|
||||
throw new AssertionError("Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
|
||||
}
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return ARRAY;
|
||||
case 1:
|
||||
return INNER_TYPE;
|
||||
case 2:
|
||||
return WILDCARD;
|
||||
case 3:
|
||||
return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
|
||||
default:
|
||||
throw new AssertionError("Invalid TypePathEntryKind tag: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tag.toString() +
|
||||
(tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (! (other instanceof TypePathEntry)) {
|
||||
return false;
|
||||
}
|
||||
TypePathEntry tpe = (TypePathEntry) other;
|
||||
return this.tag == tpe.tag && this.arg == tpe.arg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.tag.hashCode() * 17 + this.arg;
|
||||
}
|
||||
}
|
||||
|
||||
public TargetType type = TargetType.UNKNOWN;
|
||||
|
||||
// For generic/array types.
|
||||
// TODO: or should we use null? Noone will use this object.
|
||||
public List<TypePathEntry> location = new ArrayList<TypePathEntry>(0);
|
||||
|
||||
// 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 = null;
|
||||
public int[] lvarLength = null;
|
||||
public int[] lvarIndex = null;
|
||||
|
||||
// For type parameter bound
|
||||
public int bound_index = Integer.MIN_VALUE;
|
||||
|
||||
// For type parameter and method parameter
|
||||
public int parameter_index = Integer.MIN_VALUE;
|
||||
|
||||
// For class extends, implements, and throws clauses
|
||||
public int type_index = Integer.MIN_VALUE;
|
||||
|
||||
// For exception parameters, index into exception table
|
||||
public int exception_index = Integer.MIN_VALUE;
|
||||
|
||||
public Position() {}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('[');
|
||||
sb.append(type);
|
||||
|
||||
switch (type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
if (lvarOffset == null) {
|
||||
sb.append(", lvarOffset is null!");
|
||||
break;
|
||||
}
|
||||
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 parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// type parameter bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
sb.append(", bound_index = ");
|
||||
sb.append(bound_index);
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
sb.append(", exception_index = ");
|
||||
sb.append(exception_index);
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
// TODO: also needs an offset?
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
sb.append(", position UNKNOWN!");
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Unknown target type: " + type);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (!location.isEmpty()) {
|
||||
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() {
|
||||
return !type.isLocal() || isValidOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the binary representation for a type path and set
|
||||
* the {@code location} field.
|
||||
*
|
||||
* @param list The bytecode representation of the type path.
|
||||
*/
|
||||
public static List<TypePathEntry> getTypePathFromBinary(List<Integer> list) {
|
||||
List<TypePathEntry> loc = new ArrayList<TypePathEntry>(list.size() / TypePathEntry.bytesPerEntry);
|
||||
int idx = 0;
|
||||
while (idx < list.size()) {
|
||||
if (idx + 1 == list.size()) {
|
||||
throw new AssertionError("Could not decode type path: " + list);
|
||||
}
|
||||
loc.add(TypePathEntry.fromBinary(list.get(idx), list.get(idx + 1)));
|
||||
idx += 2;
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
public static List<Integer> getBinaryFromTypePath(List<TypePathEntry> locs) {
|
||||
List<Integer> loc = new ArrayList<Integer>(locs.size() * TypePathEntry.bytesPerEntry);
|
||||
for (TypePathEntry tpe : locs) {
|
||||
loc.add(tpe.tag.tag);
|
||||
loc.add(tpe.arg);
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
|
||||
// Code duplicated from com.sun.tools.javac.code.TargetType
|
||||
// The IsLocal flag could be removed here.
|
||||
public enum TargetType {
|
||||
/** For annotations on a class type parameter declaration. */
|
||||
CLASS_TYPE_PARAMETER(0x00),
|
||||
|
||||
/** For annotations on a method type parameter declaration. */
|
||||
METHOD_TYPE_PARAMETER(0x01),
|
||||
|
||||
/** For annotations on the type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS(0x10),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a class. */
|
||||
CLASS_TYPE_PARAMETER_BOUND(0x11),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a method. */
|
||||
METHOD_TYPE_PARAMETER_BOUND(0x12),
|
||||
|
||||
/** For annotations on a field. */
|
||||
FIELD(0x13),
|
||||
|
||||
/** For annotations on a method return type. */
|
||||
METHOD_RETURN(0x14),
|
||||
|
||||
/** For annotations on the method receiver. */
|
||||
METHOD_RECEIVER(0x15),
|
||||
|
||||
/** For annotations on a method parameter. */
|
||||
METHOD_FORMAL_PARAMETER(0x16),
|
||||
|
||||
/** For annotations on a throws clause in a method declaration. */
|
||||
THROWS(0x17),
|
||||
|
||||
/** For annotations on a local variable. */
|
||||
LOCAL_VARIABLE(0x40, true),
|
||||
|
||||
/** For annotations on a resource variable. */
|
||||
RESOURCE_VARIABLE(0x41, true),
|
||||
|
||||
/** For annotations on an exception parameter. */
|
||||
EXCEPTION_PARAMETER(0x42, true),
|
||||
|
||||
/** For annotations on a typecast. */
|
||||
CAST(0x43, true),
|
||||
|
||||
/** For annotations on a type test. */
|
||||
INSTANCEOF(0x44, true),
|
||||
|
||||
/** For annotations on an object creation expression. */
|
||||
NEW(0x45, true),
|
||||
|
||||
/** For annotations on a type argument of an object creation expression. */
|
||||
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
|
||||
|
||||
/** For annotations on a type argument of a method call. */
|
||||
METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
|
||||
|
||||
/** For annotations on a lambda parameter type. */
|
||||
LAMBDA_FORMAL_PARAMETER(0x48, true),
|
||||
|
||||
/** For annotations on a method reference. */
|
||||
METHOD_REFERENCE(0x49, true),
|
||||
|
||||
/** For annotations on a type argument of a method reference. */
|
||||
METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
|
||||
|
||||
/** For annotations with an unknown target. */
|
||||
UNKNOWN(0xFF);
|
||||
|
||||
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50;
|
||||
|
||||
private final int targetTypeValue;
|
||||
private final boolean isLocal;
|
||||
|
||||
private TargetType(int targetTypeValue) {
|
||||
this(targetTypeValue, false);
|
||||
}
|
||||
|
||||
private TargetType(int targetTypeValue, boolean isLocal) {
|
||||
if (targetTypeValue < 0
|
||||
|| targetTypeValue > 255)
|
||||
throw new AssertionError("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue));
|
||||
this.targetTypeValue = targetTypeValue;
|
||||
this.isLocal = isLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 isLocal;
|
||||
}
|
||||
|
||||
public int targetTypeValue() {
|
||||
return this.targetTypeValue;
|
||||
}
|
||||
|
||||
private static final TargetType[] targets;
|
||||
|
||||
static {
|
||||
targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
|
||||
TargetType[] alltargets = values();
|
||||
for (TargetType target : alltargets) {
|
||||
if (target.targetTypeValue != UNKNOWN.targetTypeValue)
|
||||
targets[target.targetTypeValue] = target;
|
||||
}
|
||||
for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
|
||||
if (targets[i] == null)
|
||||
targets[i] = UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isValidTargetTypeValue(int tag) {
|
||||
if (tag == UNKNOWN.targetTypeValue)
|
||||
return true;
|
||||
return (tag >= 0 && tag < targets.length);
|
||||
}
|
||||
|
||||
public static TargetType fromTargetTypeValue(int tag) {
|
||||
if (tag == UNKNOWN.targetTypeValue)
|
||||
return UNKNOWN;
|
||||
|
||||
if (tag < 0 || tag >= targets.length)
|
||||
throw new AssertionError("Unknown TargetType: " + tag);
|
||||
return targets[tag];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -139,6 +139,15 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
|
||||
}
|
||||
}
|
||||
|
||||
protected void addReceiverAnnotations(ExecutableMemberDoc member,
|
||||
Content tree) {
|
||||
if (member.receiverAnnotations().length > 0) {
|
||||
tree.addContent(writer.getSpace());
|
||||
writer.addReceiverAnnotationInfo(member, tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add all the parameters for the executable member.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -137,6 +137,7 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
|
||||
addName(constructor.name(), pre);
|
||||
}
|
||||
addParameters(constructor, pre);
|
||||
writer.addReceiverAnnotationInfo(constructor, pre);
|
||||
addExceptions(constructor, pre);
|
||||
return pre;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1729,6 +1729,17 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||
addAnnotationInfo(packageDoc, packageDoc.annotations(), htmltree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the annotation types of the executable receiver.
|
||||
*
|
||||
* @param method the executable to write the receiver annotations for.
|
||||
* @param htmltree the documentation tree to which the annotation info will be
|
||||
* added
|
||||
*/
|
||||
public void addReceiverAnnotationInfo(ExecutableMemberDoc method, Content htmltree) {
|
||||
addAnnotationInfo(method, method.receiverAnnotations(), htmltree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the annotatation types for the given doc.
|
||||
*
|
||||
@ -1799,6 +1810,26 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||
* documented.
|
||||
*/
|
||||
private List<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) {
|
||||
return getAnnotations(indent, descList, linkBreak, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representations of the annotation types for
|
||||
* the given doc.
|
||||
*
|
||||
* A {@code null} {@code elementType} indicates that all the
|
||||
* annotations should be returned without any filtering.
|
||||
*
|
||||
* @param indent the number of extra spaces to indent the annotations.
|
||||
* @param descList the array of {@link AnnotationDesc}.
|
||||
* @param linkBreak if true, add new line between each member value.
|
||||
* @param elementType the type of targeted element (used for filtering
|
||||
* type annotations from declaration annotations)
|
||||
* @return an array of strings representing the annotations being
|
||||
* documented.
|
||||
*/
|
||||
public List<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
|
||||
boolean isJava5DeclarationLocation) {
|
||||
List<String> results = new ArrayList<String>();
|
||||
StringBuilder annotation;
|
||||
for (int i = 0; i < descList.length; i++) {
|
||||
@ -1812,6 +1843,11 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||
(!isAnnotationDocumented && !isContainerDocumented)) {
|
||||
continue;
|
||||
}
|
||||
/* TODO: check logic here to correctly handle declaration
|
||||
* and type annotations.
|
||||
if (Util.isDeclarationAnnotation(annotationDoc, isJava5DeclarationLocation)) {
|
||||
continue;
|
||||
}*/
|
||||
annotation = new StringBuilder();
|
||||
isAnnotationDocumented = false;
|
||||
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package com.sun.tools.doclets.formats.html;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import com.sun.tools.doclets.internal.toolkit.*;
|
||||
import com.sun.tools.doclets.internal.toolkit.util.*;
|
||||
@ -123,11 +125,50 @@ public class LinkFactoryImpl extends LinkFactory {
|
||||
typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
|
||||
typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
|
||||
typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
|
||||
typeLinkInfo.isJava5DeclarationLocation = false;
|
||||
LinkOutput output = getLinkOutput(typeLinkInfo);
|
||||
((LinkInfoImpl) linkInfo).displayLength += typeLinkInfo.displayLength;
|
||||
return output;
|
||||
}
|
||||
|
||||
protected LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
|
||||
AnnotationDesc annotation) {
|
||||
throw new RuntimeException("Not implemented yet!");
|
||||
}
|
||||
|
||||
public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
|
||||
LinkOutput output = getOutputInstance();
|
||||
AnnotationDesc[] annotations;
|
||||
if (linkInfo.type instanceof AnnotatedType) {
|
||||
annotations = linkInfo.type.asAnnotatedType().annotations();
|
||||
} else if (linkInfo.type instanceof TypeVariable) {
|
||||
annotations = linkInfo.type.asTypeVariable().annotations();
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
|
||||
if (annotations.length == 0)
|
||||
return output;
|
||||
|
||||
List<String> annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
|
||||
|
||||
boolean isFirst = true;
|
||||
for (String anno : annos) {
|
||||
if (!isFirst) {
|
||||
linkInfo.displayLength += 1;
|
||||
output.append(" ");
|
||||
isFirst = false;
|
||||
}
|
||||
output.append(anno);
|
||||
}
|
||||
if (!annos.isEmpty()) {
|
||||
linkInfo.displayLength += 1;
|
||||
output.append(" ");
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a class, return the appropriate tool tip.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -459,6 +459,8 @@ public class LinkInfoImpl extends LinkInfo {
|
||||
|
||||
case CONTEXT_RETURN_TYPE:
|
||||
case CONTEXT_SUMMARY_RETURN_TYPE:
|
||||
excludeTypeBounds = true;
|
||||
break;
|
||||
case CONTEXT_EXECUTABLE_MEMBER_PARAM:
|
||||
excludeTypeBounds = true;
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -130,6 +130,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
|
||||
addName(method.name(), pre);
|
||||
}
|
||||
addParameters(method, pre);
|
||||
addReceiverAnnotations(method, pre);
|
||||
addExceptions(method, pre);
|
||||
return pre;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,9 +26,11 @@
|
||||
package com.sun.tools.doclets.internal.toolkit.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.util.*;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import com.sun.javadoc.AnnotationDesc.ElementValuePair;
|
||||
import com.sun.tools.doclets.internal.toolkit.*;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
@ -304,9 +306,7 @@ public class Util {
|
||||
//Try walking the tree.
|
||||
addAllInterfaceTypes(results,
|
||||
superType,
|
||||
superType instanceof ClassDoc ?
|
||||
((ClassDoc) superType).interfaceTypes() :
|
||||
((ParameterizedType) superType).interfaceTypes(),
|
||||
interfaceTypesOf(superType),
|
||||
false, configuration);
|
||||
List<Type> resultsList = new ArrayList<Type>(results.values());
|
||||
if (sort) {
|
||||
@ -315,6 +315,14 @@ public class Util {
|
||||
return resultsList;
|
||||
}
|
||||
|
||||
private static Type[] interfaceTypesOf(Type type) {
|
||||
if (type instanceof AnnotatedType)
|
||||
type = ((AnnotatedType)type).underlyingType();
|
||||
return type instanceof ClassDoc ?
|
||||
((ClassDoc)type).interfaceTypes() :
|
||||
((ParameterizedType)type).interfaceTypes();
|
||||
}
|
||||
|
||||
public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
|
||||
return getAllInterfaces(type, configuration, true);
|
||||
}
|
||||
@ -325,9 +333,7 @@ public class Util {
|
||||
if (superType == null)
|
||||
return;
|
||||
addAllInterfaceTypes(results, superType,
|
||||
superType instanceof ClassDoc ?
|
||||
((ClassDoc) superType).interfaceTypes() :
|
||||
((ParameterizedType) superType).interfaceTypes(),
|
||||
interfaceTypesOf(superType),
|
||||
raw, configuration);
|
||||
}
|
||||
|
||||
@ -337,9 +343,7 @@ public class Util {
|
||||
if (superType == null)
|
||||
return;
|
||||
addAllInterfaceTypes(results, superType,
|
||||
superType instanceof ClassDoc ?
|
||||
((ClassDoc) superType).interfaceTypes() :
|
||||
((ParameterizedType) superType).interfaceTypes(),
|
||||
interfaceTypesOf(superType),
|
||||
false, configuration);
|
||||
}
|
||||
|
||||
@ -363,6 +367,9 @@ public class Util {
|
||||
results.put(superInterface.asClassDoc(), superInterface);
|
||||
}
|
||||
}
|
||||
if (type instanceof AnnotatedType)
|
||||
type = ((AnnotatedType)type).underlyingType();
|
||||
|
||||
if (type instanceof ParameterizedType)
|
||||
findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
|
||||
else if (((ClassDoc) type).typeParameters().length == 0)
|
||||
@ -494,6 +501,57 @@ public class Util {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isDeclarationTarget(AnnotationDesc targetAnno) {
|
||||
// The error recovery steps here are analogous to TypeAnnotations
|
||||
ElementValuePair[] elems = targetAnno.elementValues();
|
||||
if (elems == null
|
||||
|| elems.length != 1
|
||||
|| !"value".equals(elems[0].element().name())
|
||||
|| !(elems[0].value().value() instanceof AnnotationValue[]))
|
||||
return true; // error recovery
|
||||
|
||||
AnnotationValue[] values = (AnnotationValue[])elems[0].value().value();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
Object value = values[i].value();
|
||||
if (!(value instanceof FieldDoc))
|
||||
return true; // error recovery
|
||||
|
||||
FieldDoc eValue = (FieldDoc)value;
|
||||
if (Util.isJava5DeclarationElementType(eValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the {@code annotationDoc} is to be treated
|
||||
* as a declaration annotation, when targeting the
|
||||
* {@code elemType} element type.
|
||||
*
|
||||
* @param annotationDoc the annotationDoc to check
|
||||
* @param elemType the targeted elemType
|
||||
* @return true if annotationDoc is a declaration annotation
|
||||
*/
|
||||
public static boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc,
|
||||
boolean isJava5DeclarationLocation) {
|
||||
if (!isJava5DeclarationLocation)
|
||||
return false;
|
||||
AnnotationDesc[] annotationDescList = annotationDoc.annotations();
|
||||
// Annotations with no target are treated as declaration as well
|
||||
if (annotationDescList.length==0)
|
||||
return true;
|
||||
for (int i = 0; i < annotationDescList.length; i++) {
|
||||
if (annotationDescList[i].annotationType().qualifiedName().equals(
|
||||
java.lang.annotation.Target.class.getName())) {
|
||||
if (isDeclarationTarget(annotationDescList[i]))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this class is linkable and false if we can't link to the
|
||||
* desired class.
|
||||
@ -662,4 +720,25 @@ public class Util {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given FieldDoc is one of the declaration annotation ElementTypes
|
||||
* defined in Java 5.
|
||||
* Instead of testing for one of the new enum constants added in Java 8, test for
|
||||
* the old constants. This prevents bootstrapping problems.
|
||||
*
|
||||
* @param elt The FieldDoc to test
|
||||
* @return true, iff the given ElementType is one of the constants defined in Java 5
|
||||
* @since 1.8
|
||||
*/
|
||||
public static boolean isJava5DeclarationElementType(FieldDoc elt) {
|
||||
return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) ||
|
||||
elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) ||
|
||||
elt.name().contentEquals(ElementType.FIELD.name()) ||
|
||||
elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) ||
|
||||
elt.name().contentEquals(ElementType.METHOD.name()) ||
|
||||
elt.name().contentEquals(ElementType.PACKAGE.name()) ||
|
||||
elt.name().contentEquals(ElementType.PARAMETER.name()) ||
|
||||
elt.name().contentEquals(ElementType.TYPE.name());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -61,6 +61,11 @@ public abstract class LinkFactory {
|
||||
//Just a primitive.
|
||||
linkInfo.displayLength += type.typeName().length();
|
||||
linkOutput.append(type.typeName());
|
||||
} else if (type.asAnnotatedType() != null) {
|
||||
linkOutput.append(getTypeAnnotationLinks(linkInfo));
|
||||
linkInfo.type = type.asAnnotatedType().underlyingType();
|
||||
linkOutput.append(getLinkOutput(linkInfo));
|
||||
return linkOutput;
|
||||
} else if (type.asWildcardType() != null) {
|
||||
//Wildcard type.
|
||||
linkInfo.isTypeBound = true;
|
||||
@ -82,6 +87,7 @@ public abstract class LinkFactory {
|
||||
linkOutput.append(getLinkOutput(linkInfo));
|
||||
}
|
||||
} else if (type.asTypeVariable()!= null) {
|
||||
linkOutput.append(getTypeAnnotationLinks(linkInfo));
|
||||
linkInfo.isTypeBound = true;
|
||||
//A type variable.
|
||||
Doc owner = type.asTypeVariable().owner();
|
||||
@ -175,6 +181,9 @@ public abstract class LinkFactory {
|
||||
protected abstract LinkOutput getTypeParameterLink(LinkInfo linkInfo,
|
||||
Type typeParam);
|
||||
|
||||
protected abstract LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
|
||||
AnnotationDesc annotation);
|
||||
|
||||
/**
|
||||
* Return the links to the type parameters.
|
||||
*
|
||||
@ -226,6 +235,24 @@ public abstract class LinkFactory {
|
||||
return output;
|
||||
}
|
||||
|
||||
public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
|
||||
LinkOutput output = getOutputInstance();
|
||||
if (linkInfo.type.asAnnotatedType() == null)
|
||||
return output;
|
||||
AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
|
||||
for (int i = 0; i < annotations.length; i++) {
|
||||
if (i > 0) {
|
||||
linkInfo.displayLength += 1;
|
||||
output.append(" ");
|
||||
}
|
||||
output.append(getTypeAnnotationLink(linkInfo, annotations[i]));
|
||||
}
|
||||
|
||||
linkInfo.displayLength += 1;
|
||||
output.append(" ");
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return &lt;, which is used in type parameters. Override this
|
||||
* if your doclet uses something different.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -68,6 +68,12 @@ public abstract class LinkInfo {
|
||||
*/
|
||||
public boolean isTypeBound = false;
|
||||
|
||||
/**
|
||||
* Whether the document element is in a Java 5 declaration
|
||||
* location or not.
|
||||
*/
|
||||
public boolean isJava5DeclarationLocation = true;
|
||||
|
||||
/**
|
||||
* The label for the link.
|
||||
*/
|
||||
|
@ -48,7 +48,7 @@ import static com.sun.tools.javac.code.Kinds.PCK;
|
||||
*
|
||||
* An instance of this class can be in one of three states:
|
||||
*
|
||||
* NOT_STARTED indicates that the Symbol this instance belongs to have not been
|
||||
* NOT_STARTED indicates that the Symbol this instance belongs to has not been
|
||||
* annotated (yet). Specifically if the declaration is not annotated this
|
||||
* instance will never move past NOT_STARTED. You can never go back to
|
||||
* NOT_STARTED.
|
||||
@ -59,7 +59,7 @@ import static com.sun.tools.javac.code.Kinds.PCK;
|
||||
*
|
||||
* "unnamed" this Annotations contains some attributes, possibly the final set.
|
||||
* While in this state you can only prepend or append to the attributes not set
|
||||
* it directly. You can also move back to the IN_PROGRESS sate using reset().
|
||||
* it directly. You can also move back to the IN_PROGRESS state using reset().
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API. If you write code that depends
|
||||
* on this, you do so at your own risk. This code and its internal interfaces
|
||||
@ -67,14 +67,21 @@ import static com.sun.tools.javac.code.Kinds.PCK;
|
||||
*/
|
||||
public class Annotations {
|
||||
|
||||
private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
|
||||
private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
|
||||
private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
|
||||
private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
|
||||
|
||||
/*
|
||||
* This field should never be null
|
||||
*/
|
||||
private List<Attribute.Compound> attributes = NOT_STARTED;
|
||||
private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
|
||||
|
||||
/*
|
||||
* The Symbol this Annotations belong to
|
||||
* This field should never be null
|
||||
*/
|
||||
private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
|
||||
|
||||
/*
|
||||
* The Symbol this Annotations instance belongs to
|
||||
*/
|
||||
private final Symbol sym;
|
||||
|
||||
@ -82,11 +89,15 @@ public class Annotations {
|
||||
this.sym = sym;
|
||||
}
|
||||
|
||||
public List<Attribute.Compound> getAttributes() {
|
||||
return filterSentinels(attributes);
|
||||
public List<Attribute.Compound> getDeclarationAttributes() {
|
||||
return filterDeclSentinels(attributes);
|
||||
}
|
||||
|
||||
public void setAttributes(List<Attribute.Compound> a) {
|
||||
public List<Attribute.TypeCompound> getTypeAttributes() {
|
||||
return type_attributes;
|
||||
}
|
||||
|
||||
public void setDeclarationAttributes(List<Attribute.Compound> a) {
|
||||
Assert.check(pendingCompletion() || !isStarted());
|
||||
if (a == null) {
|
||||
throw new NullPointerException();
|
||||
@ -94,31 +105,51 @@ public class Annotations {
|
||||
attributes = a;
|
||||
}
|
||||
|
||||
public void setTypeAttributes(List<Attribute.TypeCompound> a) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
type_attributes = a;
|
||||
}
|
||||
|
||||
public void setAttributes(Annotations other) {
|
||||
if (other == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
setAttributes(other.getAttributes());
|
||||
setDeclarationAttributes(other.getDeclarationAttributes());
|
||||
setTypeAttributes(other.getTypeAttributes());
|
||||
}
|
||||
|
||||
public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) {
|
||||
public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
|
||||
Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
|
||||
this.setDeclarationAttributes(getAttributesForCompletion(ctx));
|
||||
}
|
||||
|
||||
Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
|
||||
public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
|
||||
this.appendUniqueTypes(getAttributesForCompletion(ctx));
|
||||
}
|
||||
|
||||
private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
|
||||
final Annotate.AnnotateRepeatedContext<T> ctx) {
|
||||
|
||||
Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
|
||||
boolean atLeastOneRepeated = false;
|
||||
List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
|
||||
for (ListBuffer<Attribute.Compound> lb : annotated.values()) {
|
||||
List<T> buf = List.<T>nil();
|
||||
for (ListBuffer<T> lb : annotated.values()) {
|
||||
if (lb.size() == 1) {
|
||||
buf = buf.prepend(lb.first());
|
||||
} else { // repeated
|
||||
buf = buf.prepend(new Placeholder(lb.toList(), sym));
|
||||
// This will break when other subtypes of Attributs.Compound
|
||||
// are introduced, because PlaceHolder is a subtype of TypeCompound.
|
||||
T res;
|
||||
@SuppressWarnings("unchecked")
|
||||
T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym);
|
||||
res = ph;
|
||||
buf = buf.prepend(res);
|
||||
atLeastOneRepeated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Add non-repeating attributes
|
||||
setAttributes(buf.reverse());
|
||||
|
||||
if (atLeastOneRepeated) {
|
||||
// The Symbol s is now annotated with a combination of
|
||||
// finished non-repeating annotations and placeholders for
|
||||
@ -138,7 +169,6 @@ public class Annotations {
|
||||
// Queue a pass that will replace Attribute.Placeholders
|
||||
// with Attribute.Compound (made from synthesized containers).
|
||||
ctx.annotateRepeated(new Annotate.Annotator() {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "repeated annotation pass of: " + sym + " in: " + sym.owner;
|
||||
@ -150,10 +180,12 @@ public class Annotations {
|
||||
}
|
||||
});
|
||||
}
|
||||
// Add non-repeating attributes
|
||||
return buf.reverse();
|
||||
}
|
||||
|
||||
public Annotations reset() {
|
||||
attributes = IN_PROGRESS;
|
||||
attributes = DECL_IN_PROGRESS;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -163,12 +195,16 @@ public class Annotations {
|
||||
|| attributes.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isTypesEmpty() {
|
||||
return type_attributes.isEmpty();
|
||||
}
|
||||
|
||||
public boolean pendingCompletion() {
|
||||
return attributes == IN_PROGRESS;
|
||||
return attributes == DECL_IN_PROGRESS;
|
||||
}
|
||||
|
||||
public Annotations append(List<Attribute.Compound> l) {
|
||||
attributes = filterSentinels(attributes);
|
||||
attributes = filterDeclSentinels(attributes);
|
||||
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
@ -180,8 +216,24 @@ public class Annotations {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Annotations appendUniqueTypes(List<Attribute.TypeCompound> l) {
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
} else if (type_attributes.isEmpty()) {
|
||||
type_attributes = l;
|
||||
} else {
|
||||
// TODO: in case we expect a large number of annotations, this
|
||||
// might be inefficient.
|
||||
for (Attribute.TypeCompound tc : l) {
|
||||
if (!type_attributes.contains(tc))
|
||||
type_attributes = type_attributes.append(tc);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Annotations prepend(List<Attribute.Compound> l) {
|
||||
attributes = filterSentinels(attributes);
|
||||
attributes = filterDeclSentinels(attributes);
|
||||
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
@ -193,19 +245,29 @@ public class Annotations {
|
||||
return this;
|
||||
}
|
||||
|
||||
private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
|
||||
return (a == IN_PROGRESS || a == NOT_STARTED)
|
||||
private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
|
||||
return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
|
||||
? List.<Attribute.Compound>nil()
|
||||
: a;
|
||||
}
|
||||
|
||||
private boolean isStarted() {
|
||||
return attributes != NOT_STARTED;
|
||||
return attributes != DECL_NOT_STARTED;
|
||||
}
|
||||
|
||||
private List<Attribute.Compound> getPlaceholders() {
|
||||
List<Attribute.Compound> res = List.<Attribute.Compound>nil();
|
||||
for (Attribute.Compound a : filterSentinels(attributes)) {
|
||||
for (Attribute.Compound a : filterDeclSentinels(attributes)) {
|
||||
if (a instanceof Placeholder) {
|
||||
res = res.prepend(a);
|
||||
}
|
||||
}
|
||||
return res.reverse();
|
||||
}
|
||||
|
||||
private List<Attribute.TypeCompound> getTypePlaceholders() {
|
||||
List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
|
||||
for (Attribute.TypeCompound a : type_attributes) {
|
||||
if (a instanceof Placeholder) {
|
||||
res = res.prepend(a);
|
||||
}
|
||||
@ -216,50 +278,78 @@ public class Annotations {
|
||||
/*
|
||||
* Replace Placeholders for repeating annotations with their containers
|
||||
*/
|
||||
private void complete(Annotate.AnnotateRepeatedContext ctx) {
|
||||
Assert.check(!pendingCompletion());
|
||||
private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
|
||||
Log log = ctx.log;
|
||||
Env<AttrContext> env = ctx.env;
|
||||
JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
// TODO: can we reduce duplication in the following branches?
|
||||
if (ctx.isTypeCompound) {
|
||||
Assert.check(!isTypesEmpty());
|
||||
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Attribute.Compound> result = List.nil();
|
||||
for (Attribute.Compound a : getAttributes()) {
|
||||
if (a instanceof Placeholder) {
|
||||
Attribute.Compound replacement = replaceOne((Placeholder) a, ctx);
|
||||
|
||||
if (null != replacement) {
|
||||
result = result.prepend(replacement);
|
||||
}
|
||||
} else {
|
||||
result = result.prepend(a);
|
||||
if (isTypesEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Attribute.TypeCompound> result = List.nil();
|
||||
for (Attribute.TypeCompound a : getTypeAttributes()) {
|
||||
if (a instanceof Placeholder) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a;
|
||||
Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext());
|
||||
|
||||
if (null != replacement) {
|
||||
result = result.prepend(replacement);
|
||||
}
|
||||
} else {
|
||||
result = result.prepend(a);
|
||||
}
|
||||
}
|
||||
|
||||
type_attributes = result.reverse();
|
||||
|
||||
Assert.check(Annotations.this.getTypePlaceholders().isEmpty());
|
||||
} else {
|
||||
Assert.check(!pendingCompletion());
|
||||
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Attribute.Compound> result = List.nil();
|
||||
for (Attribute.Compound a : getDeclarationAttributes()) {
|
||||
if (a instanceof Placeholder) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx);
|
||||
|
||||
if (null != replacement) {
|
||||
result = result.prepend(replacement);
|
||||
}
|
||||
} else {
|
||||
result = result.prepend(a);
|
||||
}
|
||||
}
|
||||
|
||||
attributes = result.reverse();
|
||||
|
||||
Assert.check(Annotations.this.getPlaceholders().isEmpty());
|
||||
}
|
||||
|
||||
attributes = result.reverse();
|
||||
|
||||
Assert.check(Annotations.this.getPlaceholders().isEmpty());
|
||||
} finally {
|
||||
log.useSource(oldSource);
|
||||
}
|
||||
}
|
||||
|
||||
private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) {
|
||||
private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
|
||||
Log log = ctx.log;
|
||||
|
||||
// Process repeated annotations
|
||||
Attribute.Compound validRepeated =
|
||||
ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
|
||||
T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
|
||||
|
||||
if (validRepeated != null) {
|
||||
// Check that the container isn't manually
|
||||
// present along with repeated instances of
|
||||
// its contained annotation.
|
||||
ListBuffer<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
|
||||
ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
|
||||
if (manualContainer != null) {
|
||||
log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
|
||||
manualContainer.first().type.tsym);
|
||||
@ -268,16 +358,20 @@ public class Annotations {
|
||||
|
||||
// A null return will delete the Placeholder
|
||||
return validRepeated;
|
||||
|
||||
}
|
||||
|
||||
private static class Placeholder extends Attribute.Compound {
|
||||
private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
|
||||
|
||||
private List<Attribute.Compound> placeholderFor;
|
||||
private Symbol on;
|
||||
private final Annotate.AnnotateRepeatedContext<T> ctx;
|
||||
private final List<T> placeholderFor;
|
||||
private final Symbol on;
|
||||
|
||||
public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
|
||||
super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
|
||||
public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
|
||||
super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
|
||||
ctx.isTypeCompound ?
|
||||
((Attribute.TypeCompound)placeholderFor.head).position :
|
||||
null);
|
||||
this.ctx = ctx;
|
||||
this.placeholderFor = placeholderFor;
|
||||
this.on = on;
|
||||
}
|
||||
@ -287,8 +381,12 @@ public class Annotations {
|
||||
return "<placeholder: " + placeholderFor + " on: " + on + ">";
|
||||
}
|
||||
|
||||
public List<Attribute.Compound> getPlaceholderFor() {
|
||||
public List<T> getPlaceholderFor() {
|
||||
return placeholderFor;
|
||||
}
|
||||
|
||||
public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -217,6 +217,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 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -233,23 +233,23 @@ public class Flags {
|
||||
public static final long PROPRIETARY = 1L<<38;
|
||||
|
||||
/**
|
||||
* Flag that marks a a multi-catch parameter
|
||||
* Flag that marks a multi-catch parameter.
|
||||
*/
|
||||
public static final long UNION = 1L<<39;
|
||||
|
||||
/**
|
||||
* Flag that marks a special kind of bridge methods (the ones that
|
||||
* come from restricted supertype bounds)
|
||||
* Flag that marks a special kind of bridge method (the ones that
|
||||
* come from restricted supertype bounds).
|
||||
*/
|
||||
public static final long OVERRIDE_BRIDGE = 1L<<40;
|
||||
|
||||
/**
|
||||
* Flag that marks an 'effectively final' local variable
|
||||
* Flag that marks an 'effectively final' local variable.
|
||||
*/
|
||||
public static final long EFFECTIVELY_FINAL = 1L<<41;
|
||||
|
||||
/**
|
||||
* Flag that marks non-override equivalent methods with the same signature
|
||||
* Flag that marks non-override equivalent methods with the same signature.
|
||||
*/
|
||||
public static final long CLASH = 1L<<42;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -74,7 +74,7 @@ public class Lint
|
||||
* the given annotations.
|
||||
*/
|
||||
public Lint augment(Annotations annots) {
|
||||
return augmentor.augment(this, annots.getAttributes());
|
||||
return augmentor.augment(this, annots.getDeclarationAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,7 +82,7 @@ public class Lint
|
||||
* the given annotations and flags.
|
||||
*/
|
||||
public Lint augment(Annotations annots, long flags) {
|
||||
Lint l = augmentor.augment(this, annots.getAttributes());
|
||||
Lint l = augmentor.augment(this, annots.getDeclarationAttributes());
|
||||
if ((flags & DEPRECATED) != 0) {
|
||||
if (l == this)
|
||||
l = new Lint(this);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,10 @@ package com.sun.tools.javac.code;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import com.sun.tools.javac.api.Messages;
|
||||
import com.sun.tools.javac.code.Type.AnnotatedType;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
@ -35,7 +38,6 @@ import com.sun.tools.javac.util.ListBuffer;
|
||||
|
||||
import static com.sun.tools.javac.code.BoundKind.*;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.TypeTag.ARRAY;
|
||||
import static com.sun.tools.javac.code.TypeTag.CLASS;
|
||||
import static com.sun.tools.javac.code.TypeTag.FORALL;
|
||||
|
||||
@ -188,7 +190,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) {
|
||||
buf.append(visit(t.getEnclosingType(), locale));
|
||||
buf.append(".");
|
||||
buf.append('.');
|
||||
buf.append(className(t, false, locale));
|
||||
} else {
|
||||
buf.append(className(t, true, locale));
|
||||
@ -196,7 +198,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
if (t.getTypeArguments().nonEmpty()) {
|
||||
buf.append('<');
|
||||
buf.append(visitTypes(t.getTypeArguments(), locale));
|
||||
buf.append(">");
|
||||
buf.append('>');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
@ -231,6 +233,17 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
return visitType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
|
||||
if (t.typeAnnotations != null &&
|
||||
t.typeAnnotations.nonEmpty()) {
|
||||
// TODO: better logic for arrays, ...
|
||||
return "(" + t.typeAnnotations + " :: " + visit(t.underlyingType, locale) + ")";
|
||||
} else {
|
||||
return "({} :: " + visit(t.underlyingType, locale) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public String visitType(Type t, Locale locale) {
|
||||
String s = (t.tsym == null || t.tsym.name == null)
|
||||
? localize(locale, "compiler.misc.type.none")
|
||||
@ -296,8 +309,13 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
args = args.tail;
|
||||
buf.append(',');
|
||||
}
|
||||
if (args.head.tag == ARRAY) {
|
||||
buf.append(visit(((ArrayType) args.head).elemtype, locale));
|
||||
if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) {
|
||||
buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
|
||||
if (args.head.getAnnotations().nonEmpty()) {
|
||||
buf.append(' ');
|
||||
buf.append(args.head.getAnnotations());
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append("...");
|
||||
} else {
|
||||
buf.append(visit(args.head, locale));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -176,9 +176,6 @@ public enum Source {
|
||||
public boolean allowTryWithResources() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowTypeAnnotations() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowBinaryLiterals() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
@ -215,6 +212,9 @@ public enum Source {
|
||||
public boolean allowEffectivelyFinalInInnerClasses() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowTypeAnnotations() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowRepeatedAnnotations() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
|
@ -84,7 +84,15 @@ public abstract class Symbol implements Element {
|
||||
* method to make sure that the class symbol is loaded.
|
||||
*/
|
||||
public List<Attribute.Compound> getRawAttributes() {
|
||||
return annotations.getAttributes();
|
||||
return annotations.getDeclarationAttributes();
|
||||
}
|
||||
|
||||
/** An accessor method for the type attributes of this symbol.
|
||||
* Attributes of class symbols should be accessed through the accessor
|
||||
* method to make sure that the class symbol is loaded.
|
||||
*/
|
||||
public List<Attribute.TypeCompound> getRawTypeAttributes() {
|
||||
return annotations.getTypeAttributes();
|
||||
}
|
||||
|
||||
/** Fetch a particular annotation from a symbol. */
|
||||
@ -454,6 +462,14 @@ public abstract class Symbol implements Element {
|
||||
return getRawAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Should there be a {@code
|
||||
* javax.lang.model.element.Element.getTypeAnnotationMirrors()}.
|
||||
*/
|
||||
public final List<Attribute.TypeCompound> getTypeAnnotationMirrors() {
|
||||
return getRawTypeAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method should never be used by javac internally.
|
||||
*/
|
||||
@ -795,6 +811,12 @@ public abstract class Symbol implements Element {
|
||||
return super.getRawAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Attribute.TypeCompound> getRawTypeAttributes() {
|
||||
if (completer != null) complete();
|
||||
return super.getRawTypeAttributes();
|
||||
}
|
||||
|
||||
public Type erasure(Types types) {
|
||||
if (erasure_field == null)
|
||||
erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
|
||||
@ -1387,7 +1409,7 @@ public abstract class Symbol implements Element {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public List<VarSymbol> getParameters() {
|
||||
public List<VarSymbol> getParameters() {
|
||||
return params();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,10 +25,7 @@
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.sun.tools.javac.code.TargetType.TargetAttribute.*;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
|
||||
/**
|
||||
* Describes the type of program element an extended annotation (or extended
|
||||
@ -44,178 +41,89 @@ import static com.sun.tools.javac.code.TargetType.TargetAttribute.*;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
// Code duplicated in com.sun.tools.classfile.TypeAnnotation.TargetType
|
||||
public enum TargetType {
|
||||
/** For annotations on a class type parameter declaration. */
|
||||
CLASS_TYPE_PARAMETER(0x00),
|
||||
|
||||
//
|
||||
// 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 a method type parameter declaration. */
|
||||
METHOD_TYPE_PARAMETER(0x01),
|
||||
|
||||
/** For annotations on the type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS(0x14),
|
||||
CLASS_EXTENDS(0x10),
|
||||
|
||||
/** For annotations on the inner type of an "extends" or "implements" clause. */
|
||||
CLASS_EXTENDS_GENERIC_OR_ARRAY(0x15, HasLocation),
|
||||
/** For annotations on a bound of a type parameter of a class. */
|
||||
CLASS_TYPE_PARAMETER_BOUND(0x11),
|
||||
|
||||
/** For annotations on a bound of a type parameter of a method. */
|
||||
METHOD_TYPE_PARAMETER_BOUND(0x12),
|
||||
|
||||
/** For annotations on a field. */
|
||||
FIELD(0x13),
|
||||
|
||||
/** For annotations on a method return type. */
|
||||
METHOD_RETURN(0x14),
|
||||
|
||||
/** For annotations on the method receiver. */
|
||||
METHOD_RECEIVER(0x15),
|
||||
|
||||
/** For annotations on a method parameter. */
|
||||
METHOD_FORMAL_PARAMETER(0x16),
|
||||
|
||||
/** For annotations on a throws clause in a method declaration. */
|
||||
THROWS(0x16),
|
||||
THROWS(0x17),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated THROWS_GENERIC_OR_ARRAY(0x17, HasLocation),
|
||||
/** For annotations on a local variable. */
|
||||
LOCAL_VARIABLE(0x40, true),
|
||||
|
||||
/** For annotations in type arguments of object creation expressions. */
|
||||
NEW_TYPE_ARGUMENT(0x18, IsLocal),
|
||||
NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x19, HasLocation, IsLocal),
|
||||
/** For annotations on a resource variable. */
|
||||
RESOURCE_VARIABLE(0x41, true),
|
||||
|
||||
METHOD_TYPE_ARGUMENT(0x1A, IsLocal),
|
||||
METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x1B, HasLocation, IsLocal),
|
||||
/** For annotations on an exception parameter. */
|
||||
EXCEPTION_PARAMETER(0x42, true),
|
||||
|
||||
WILDCARD_BOUND(0x1C, HasBound),
|
||||
WILDCARD_BOUND_GENERIC_OR_ARRAY(0x1D, HasBound, HasLocation),
|
||||
/** For annotations on a typecast. */
|
||||
CAST(0x43, true),
|
||||
|
||||
CLASS_LITERAL(0x1E, IsLocal),
|
||||
CLASS_LITERAL_GENERIC_OR_ARRAY(0x1F, HasLocation, IsLocal),
|
||||
/** For annotations on a type test. */
|
||||
INSTANCEOF(0x44, true),
|
||||
|
||||
METHOD_TYPE_PARAMETER(0x20, HasParameter),
|
||||
/** For annotations on an object creation expression. */
|
||||
NEW(0x45, true),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x21, HasLocation, HasParameter),
|
||||
/** For annotations on a type argument of an object creation expression. */
|
||||
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
|
||||
|
||||
CLASS_TYPE_PARAMETER(0x22, HasParameter),
|
||||
/** For annotations on a type argument of a method call. */
|
||||
METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
|
||||
|
||||
// invalid location
|
||||
//@Deprecated CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x23, HasLocation, HasParameter),
|
||||
/** For annotations on a lambda parameter type. */
|
||||
LAMBDA_FORMAL_PARAMETER(0x48, true),
|
||||
|
||||
/** For annotations on a method reference. */
|
||||
METHOD_REFERENCE(0x49, true),
|
||||
|
||||
/** For annotations on a type argument of a method reference. */
|
||||
METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
|
||||
|
||||
/** For annotations with an unknown target. */
|
||||
UNKNOWN(-1);
|
||||
UNKNOWN(0xFF);
|
||||
|
||||
static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
|
||||
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x92;
|
||||
|
||||
private final int targetTypeValue;
|
||||
private final Set<TargetAttribute> flags;
|
||||
private final boolean isLocal;
|
||||
|
||||
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);
|
||||
private TargetType(int targetTypeValue) {
|
||||
this(targetTypeValue, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
private TargetType(int targetTypeValue, boolean isLocal) {
|
||||
if (targetTypeValue < 0
|
||||
|| targetTypeValue > 255)
|
||||
Assert.error("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue));
|
||||
this.targetTypeValue = targetTypeValue;
|
||||
this.isLocal = isLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,7 +134,7 @@ public enum TargetType {
|
||||
* member declaration signature tree
|
||||
*/
|
||||
public boolean isLocal() {
|
||||
return flags.contains(IsLocal);
|
||||
return isLocal;
|
||||
}
|
||||
|
||||
public int targetTypeValue() {
|
||||
@ -239,7 +147,7 @@ public enum TargetType {
|
||||
targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
|
||||
TargetType[] alltargets = values();
|
||||
for (TargetType target : alltargets) {
|
||||
if (target.targetTypeValue >= 0)
|
||||
if (target.targetTypeValue != UNKNOWN.targetTypeValue)
|
||||
targets[target.targetTypeValue] = target;
|
||||
}
|
||||
for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
|
||||
@ -249,22 +157,18 @@ public enum TargetType {
|
||||
}
|
||||
|
||||
public static boolean isValidTargetTypeValue(int tag) {
|
||||
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
|
||||
if (tag == UNKNOWN.targetTypeValue)
|
||||
return true;
|
||||
|
||||
return (tag >= 0 && tag < targets.length);
|
||||
}
|
||||
|
||||
public static TargetType fromTargetTypeValue(int tag) {
|
||||
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
|
||||
if (tag == UNKNOWN.targetTypeValue)
|
||||
return UNKNOWN;
|
||||
|
||||
if (tag < 0 || tag >= targets.length)
|
||||
throw new IllegalArgumentException("Unknown TargetType: " + tag);
|
||||
Assert.error("Unknown TargetType: " + tag);
|
||||
return targets[tag];
|
||||
}
|
||||
|
||||
static enum TargetAttribute {
|
||||
HasLocation, HasParameter, HasBound, IsLocal;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,6 +31,7 @@ import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.type.*;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
@ -87,7 +88,7 @@ public class Type implements PrimitiveType {
|
||||
*/
|
||||
protected TypeTag tag;
|
||||
|
||||
/** The defining class / interface / package / type variable
|
||||
/** The defining class / interface / package / type variable.
|
||||
*/
|
||||
public TypeSymbol tsym;
|
||||
|
||||
@ -166,7 +167,7 @@ public class Type implements PrimitiveType {
|
||||
/**
|
||||
* Get the representation of this type used for modelling purposes.
|
||||
* By default, this is itself. For ErrorType, a different value
|
||||
* may be provided,
|
||||
* may be provided.
|
||||
*/
|
||||
public Type getModelType() {
|
||||
return this;
|
||||
@ -245,6 +246,14 @@ public class Type implements PrimitiveType {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is an annotated type, return the underlying type.
|
||||
* Otherwise, return the type itself.
|
||||
*/
|
||||
public Type unannotatedType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Return the base types of a list of types.
|
||||
*/
|
||||
public static List<Type> baseTypes(List<Type> ts) {
|
||||
@ -339,8 +348,11 @@ public class Type implements PrimitiveType {
|
||||
args = args.tail;
|
||||
buf.append(',');
|
||||
}
|
||||
if (args.head.tag == ARRAY) {
|
||||
buf.append(((ArrayType)args.head).elemtype);
|
||||
if (args.head.unannotatedType().tag == ARRAY) {
|
||||
buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
|
||||
if (args.head.getAnnotations().nonEmpty()) {
|
||||
buf.append(args.head.getAnnotations());
|
||||
}
|
||||
buf.append("...");
|
||||
} else {
|
||||
buf.append(args.head);
|
||||
@ -350,10 +362,12 @@ public class Type implements PrimitiveType {
|
||||
|
||||
/** Access methods.
|
||||
*/
|
||||
public List<? extends AnnotationMirror> getAnnotations() { return List.nil(); }
|
||||
public List<Type> getTypeArguments() { return List.nil(); }
|
||||
public Type getEnclosingType() { return null; }
|
||||
public Type getEnclosingType() { return null; }
|
||||
public List<Type> getParameterTypes() { return List.nil(); }
|
||||
public Type getReturnType() { return null; }
|
||||
public Type getReceiverType() { return null; }
|
||||
public List<Type> getThrownTypes() { return List.nil(); }
|
||||
public Type getUpperBound() { return null; }
|
||||
public Type getLowerBound() { return null; }
|
||||
@ -600,7 +614,7 @@ public class Type implements PrimitiveType {
|
||||
|
||||
/** The enclosing type of this type. If this is the type of an inner
|
||||
* class, outer_field refers to the type of its enclosing
|
||||
* instance class, in all other cases it referes to noType.
|
||||
* instance class, in all other cases it refers to noType.
|
||||
*/
|
||||
private Type outer_field;
|
||||
|
||||
@ -974,6 +988,10 @@ public class Type implements PrimitiveType {
|
||||
public Type restype;
|
||||
public List<Type> thrown;
|
||||
|
||||
/** The type annotations on the method receiver.
|
||||
*/
|
||||
public Type recvtype;
|
||||
|
||||
public MethodType(List<Type> argtypes,
|
||||
Type restype,
|
||||
List<Type> thrown,
|
||||
@ -1000,6 +1018,7 @@ public class Type implements PrimitiveType {
|
||||
|
||||
public List<Type> getParameterTypes() { return argtypes; }
|
||||
public Type getReturnType() { return restype; }
|
||||
public Type getReceiverType() { return recvtype; }
|
||||
public List<Type> getThrownTypes() { return thrown; }
|
||||
|
||||
public boolean isErroneous() {
|
||||
@ -1028,6 +1047,7 @@ public class Type implements PrimitiveType {
|
||||
for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
|
||||
l.head.complete();
|
||||
restype.complete();
|
||||
recvtype.complete();
|
||||
for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
|
||||
l.head.complete();
|
||||
}
|
||||
@ -1112,7 +1132,11 @@ public class Type implements PrimitiveType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getUpperBound() { return bound; }
|
||||
public Type getUpperBound() {
|
||||
if ((bound == null || bound.tag == NONE) && this != tsym.type)
|
||||
bound = tsym.type.getUpperBound();
|
||||
return bound;
|
||||
}
|
||||
|
||||
int rank_field = -1;
|
||||
|
||||
@ -1183,6 +1207,7 @@ public class Type implements PrimitiveType {
|
||||
public Type getEnclosingType() { return qtype.getEnclosingType(); }
|
||||
public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
|
||||
public Type getReturnType() { return qtype.getReturnType(); }
|
||||
public Type getReceiverType() { return qtype.getReceiverType(); }
|
||||
public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
|
||||
public List<Type> allparams() { return qtype.allparams(); }
|
||||
public Type getUpperBound() { return qtype.getUpperBound(); }
|
||||
@ -1435,7 +1460,7 @@ public class Type implements PrimitiveType {
|
||||
}
|
||||
|
||||
public Type constType(Object constValue) { return this; }
|
||||
public Type getEnclosingType() { return this; }
|
||||
public Type getEnclosingType() { return this; }
|
||||
public Type getReturnType() { return this; }
|
||||
public Type asSub(Symbol sym) { return this; }
|
||||
public Type map(Mapping f) { return this; }
|
||||
@ -1461,11 +1486,165 @@ public class Type implements PrimitiveType {
|
||||
}
|
||||
}
|
||||
|
||||
public static class AnnotatedType extends Type
|
||||
implements javax.lang.model.type.AnnotatedType {
|
||||
/** The type annotations on this type.
|
||||
*/
|
||||
public List<Attribute.TypeCompound> typeAnnotations;
|
||||
|
||||
/** The underlying type that is annotated.
|
||||
*/
|
||||
public Type underlyingType;
|
||||
|
||||
public AnnotatedType(Type underlyingType) {
|
||||
super(underlyingType.tag, underlyingType.tsym);
|
||||
this.typeAnnotations = List.nil();
|
||||
this.underlyingType = underlyingType;
|
||||
Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED,
|
||||
"Can't annotate already annotated type: " + underlyingType);
|
||||
}
|
||||
|
||||
public AnnotatedType(List<Attribute.TypeCompound> typeAnnotations,
|
||||
Type underlyingType) {
|
||||
super(underlyingType.tag, underlyingType.tsym);
|
||||
this.typeAnnotations = typeAnnotations;
|
||||
this.underlyingType = underlyingType;
|
||||
Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED,
|
||||
"Can't annotate already annotated type: " + underlyingType +
|
||||
"; adding: " + typeAnnotations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKind getKind() {
|
||||
return TypeKind.ANNOTATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AnnotationMirror> getAnnotations() {
|
||||
return typeAnnotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror getUnderlyingType() {
|
||||
return underlyingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type unannotatedType() {
|
||||
return underlyingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R,S> R accept(Type.Visitor<R,S> v, S s) {
|
||||
return v.visitAnnotatedType(this, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
|
||||
return v.visitAnnotated(this, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type map(Mapping f) {
|
||||
underlyingType.map(f);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type constType(Object constValue) { return underlyingType.constType(constValue); }
|
||||
@Override
|
||||
public Type getEnclosingType() { return underlyingType.getEnclosingType(); }
|
||||
|
||||
@Override
|
||||
public Type getReturnType() { return underlyingType.getReturnType(); }
|
||||
@Override
|
||||
public List<Type> getTypeArguments() { return underlyingType.getTypeArguments(); }
|
||||
@Override
|
||||
public List<Type> getParameterTypes() { return underlyingType.getParameterTypes(); }
|
||||
@Override
|
||||
public Type getReceiverType() { return underlyingType.getReceiverType(); }
|
||||
@Override
|
||||
public List<Type> getThrownTypes() { return underlyingType.getThrownTypes(); }
|
||||
@Override
|
||||
public Type getUpperBound() { return underlyingType.getUpperBound(); }
|
||||
@Override
|
||||
public Type getLowerBound() { return underlyingType.getLowerBound(); }
|
||||
|
||||
@Override
|
||||
public boolean isErroneous() { return underlyingType.isErroneous(); }
|
||||
@Override
|
||||
public boolean isCompound() { return underlyingType.isCompound(); }
|
||||
@Override
|
||||
public boolean isInterface() { return underlyingType.isInterface(); }
|
||||
@Override
|
||||
public List<Type> allparams() { return underlyingType.allparams(); }
|
||||
@Override
|
||||
public boolean isNumeric() { return underlyingType.isNumeric(); }
|
||||
@Override
|
||||
public boolean isReference() { return underlyingType.isReference(); }
|
||||
@Override
|
||||
public boolean isParameterized() { return underlyingType.isParameterized(); }
|
||||
@Override
|
||||
public boolean isRaw() { return underlyingType.isRaw(); }
|
||||
@Override
|
||||
public boolean isFinal() { return underlyingType.isFinal(); }
|
||||
@Override
|
||||
public boolean isSuperBound() { return underlyingType.isSuperBound(); }
|
||||
@Override
|
||||
public boolean isExtendsBound() { return underlyingType.isExtendsBound(); }
|
||||
@Override
|
||||
public boolean isUnbound() { return underlyingType.isUnbound(); }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO more logic for arrays, etc.
|
||||
if (typeAnnotations != null &&
|
||||
!typeAnnotations.isEmpty()) {
|
||||
return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
|
||||
} else {
|
||||
return "({} :: " + underlyingType.toString() +")";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Type t) { return underlyingType.contains(t); }
|
||||
|
||||
// TODO: attach annotations?
|
||||
@Override
|
||||
public Type withTypeVar(Type t) { return underlyingType.withTypeVar(t); }
|
||||
|
||||
// TODO: attach annotations?
|
||||
@Override
|
||||
public TypeSymbol asElement() { return underlyingType.asElement(); }
|
||||
|
||||
// TODO: attach annotations?
|
||||
@Override
|
||||
public MethodType asMethodType() { return underlyingType.asMethodType(); }
|
||||
|
||||
@Override
|
||||
public void complete() { underlyingType.complete(); }
|
||||
|
||||
@Override
|
||||
public TypeMirror getComponentType() { return ((ArrayType)underlyingType).getComponentType(); }
|
||||
|
||||
// The result is an ArrayType, but only in the model sense, not the Type sense.
|
||||
public AnnotatedType makeVarargs() {
|
||||
AnnotatedType atype = new AnnotatedType(((ArrayType)underlyingType).makeVarargs());
|
||||
atype.typeAnnotations = this.typeAnnotations;
|
||||
return atype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror getExtendsBound() { return ((WildcardType)underlyingType).getExtendsBound(); }
|
||||
@Override
|
||||
public TypeMirror getSuperBound() { return ((WildcardType)underlyingType).getSuperBound(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor for types. A visitor is used to implement operations
|
||||
* (or relations) on types. Most common operations on types are
|
||||
* binary relations and this interface is designed for binary
|
||||
* relations, that is, operations on the form
|
||||
* relations, that is, operations of the form
|
||||
* Type × S → R.
|
||||
* <!-- In plain text: Type x S -> R -->
|
||||
*
|
||||
@ -1486,6 +1665,7 @@ public class Type implements PrimitiveType {
|
||||
R visitForAll(ForAll t, S s);
|
||||
R visitUndetVar(UndetVar t, S s);
|
||||
R visitErrorType(ErrorType t, S s);
|
||||
R visitAnnotatedType(AnnotatedType t, S s);
|
||||
R visitType(Type t, S s);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
/** A type annotation position.
|
||||
@ -34,12 +36,92 @@ import com.sun.tools.javac.util.*;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
// Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
|
||||
public class TypeAnnotationPosition {
|
||||
|
||||
public enum TypePathEntryKind {
|
||||
ARRAY(0),
|
||||
INNER_TYPE(1),
|
||||
WILDCARD(2),
|
||||
TYPE_ARGUMENT(3);
|
||||
|
||||
public final int tag;
|
||||
|
||||
private TypePathEntryKind(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypePathEntry {
|
||||
/** The fixed number of bytes per TypePathEntry. */
|
||||
public static final int bytesPerEntry = 2;
|
||||
|
||||
public final TypePathEntryKind tag;
|
||||
public final int arg;
|
||||
|
||||
public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
|
||||
public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
|
||||
public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
|
||||
|
||||
private TypePathEntry(TypePathEntryKind tag) {
|
||||
Assert.check(tag == TypePathEntryKind.ARRAY ||
|
||||
tag == TypePathEntryKind.INNER_TYPE ||
|
||||
tag == TypePathEntryKind.WILDCARD,
|
||||
"Invalid TypePathEntryKind: " + tag);
|
||||
this.tag = tag;
|
||||
this.arg = 0;
|
||||
}
|
||||
|
||||
public TypePathEntry(TypePathEntryKind tag, int arg) {
|
||||
Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
|
||||
"Invalid TypePathEntryKind: " + tag);
|
||||
this.tag = tag;
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
public static TypePathEntry fromBinary(int tag, int arg) {
|
||||
Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
|
||||
"Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return ARRAY;
|
||||
case 1:
|
||||
return INNER_TYPE;
|
||||
case 2:
|
||||
return WILDCARD;
|
||||
case 3:
|
||||
return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
|
||||
default:
|
||||
Assert.error("Invalid TypePathEntryKind tag: " + tag);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tag.toString() +
|
||||
(tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (! (other instanceof TypePathEntry)) {
|
||||
return false;
|
||||
}
|
||||
TypePathEntry tpe = (TypePathEntry) other;
|
||||
return this.tag == tpe.tag && this.arg == tpe.arg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.tag.hashCode() * 17 + this.arg;
|
||||
}
|
||||
}
|
||||
|
||||
public TargetType type = TargetType.UNKNOWN;
|
||||
|
||||
// For generic/array types.
|
||||
public List<Integer> location = List.nil();
|
||||
public List<TypePathEntry> location = List.nil();
|
||||
|
||||
// Tree position.
|
||||
public int pos = -1;
|
||||
@ -59,11 +141,13 @@ public class TypeAnnotationPosition {
|
||||
// For type parameter and method parameter
|
||||
public int parameter_index = Integer.MIN_VALUE;
|
||||
|
||||
// For class extends, implements, and throws classes
|
||||
// For class extends, implements, and throws clauses
|
||||
public int type_index = Integer.MIN_VALUE;
|
||||
|
||||
// For wildcards
|
||||
public TypeAnnotationPosition wildcard_position = null;
|
||||
// For exception parameters, index into exception table
|
||||
public int exception_index = Integer.MIN_VALUE;
|
||||
|
||||
public TypeAnnotationPosition() {}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -72,27 +156,27 @@ public class TypeAnnotationPosition {
|
||||
sb.append(type);
|
||||
|
||||
switch (type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
// 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
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
if (lvarOffset == null) {
|
||||
sb.append(", lvarOffset is null!");
|
||||
break;
|
||||
}
|
||||
sb.append(", {");
|
||||
for (int i = 0; i < lvarOffset.length; ++i) {
|
||||
if (i != 0) sb.append("; ");
|
||||
sb.append(", start_pc = ");
|
||||
sb.append("start_pc = ");
|
||||
sb.append(lvarOffset[i]);
|
||||
sb.append(", length = ");
|
||||
sb.append(lvarLength[i]);
|
||||
@ -101,73 +185,72 @@ public class TypeAnnotationPosition {
|
||||
}
|
||||
sb.append("}");
|
||||
break;
|
||||
// method receiver
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
// type parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
// type parameters bound
|
||||
// type parameter 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
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
// throws
|
||||
// throws
|
||||
case THROWS:
|
||||
sb.append(", type_index = ");
|
||||
sb.append(type_index);
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
case CLASS_LITERAL_GENERIC_OR_ARRAY:
|
||||
sb.append(", offset = ");
|
||||
sb.append(offset);
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
sb.append(", exception_index = ");
|
||||
sb.append(exception_index);
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
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:
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
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:
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
// TODO: also needs an offset?
|
||||
sb.append(", param_index = ");
|
||||
sb.append(parameter_index);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
sb.append(", position UNKNOWN!");
|
||||
break;
|
||||
default:
|
||||
// throw new AssertionError("unknown type: " + type);
|
||||
Assert.error("Unknown target type: " + type);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (type.hasLocation()) {
|
||||
if (!location.isEmpty()) {
|
||||
sb.append(", location = (");
|
||||
sb.append(location);
|
||||
sb.append(")");
|
||||
@ -186,10 +269,33 @@ public class TypeAnnotationPosition {
|
||||
* @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;
|
||||
return !type.isLocal() || isValidOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the binary representation for a type path and set
|
||||
* the {@code location} field.
|
||||
*
|
||||
* @param list The bytecode representation of the type path.
|
||||
*/
|
||||
public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
|
||||
ListBuffer<TypePathEntry> loc = ListBuffer.lb();
|
||||
Iterator<Integer> iter = list.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Integer fst = iter.next();
|
||||
Assert.check(iter.hasNext(), "Could not decode type path: " + list);
|
||||
Integer snd = iter.next();
|
||||
loc = loc.append(TypePathEntry.fromBinary(fst, snd));
|
||||
}
|
||||
return loc.toList();
|
||||
}
|
||||
|
||||
public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
|
||||
ListBuffer<Integer> loc = ListBuffer.lb();
|
||||
for (TypePathEntry tpe : locs) {
|
||||
loc = loc.append(tpe.tag.tag);
|
||||
loc = loc.append(tpe.arg);
|
||||
}
|
||||
return loc.toList();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,13 +34,14 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
|
||||
import com.sun.tools.javac.comp.Check;
|
||||
import com.sun.tools.javac.jvm.ClassReader;
|
||||
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.*;
|
||||
import static com.sun.tools.javac.code.Scope.*;
|
||||
@ -684,6 +685,8 @@ public class Types {
|
||||
//where
|
||||
private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
|
||||
if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
|
||||
t = t.unannotatedType();
|
||||
s = s.unannotatedType();
|
||||
if (((ArrayType)t).elemtype.isPrimitive()) {
|
||||
return isSameType(elemtype(t), elemtype(s));
|
||||
} else {
|
||||
@ -709,7 +712,10 @@ public class Types {
|
||||
}
|
||||
|
||||
private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
|
||||
if (t.tag != ARRAY || isReifiable(t)) return;
|
||||
if (t.tag != ARRAY || isReifiable(t))
|
||||
return;
|
||||
t = t.unannotatedType();
|
||||
s = s.unannotatedType();
|
||||
ArrayType from = (ArrayType)t;
|
||||
boolean shouldWarn = false;
|
||||
switch (s.tag) {
|
||||
@ -739,6 +745,12 @@ public class Types {
|
||||
return isSubtype(t, s, false);
|
||||
}
|
||||
public boolean isSubtype(Type t, Type s, boolean capture) {
|
||||
if (t == s)
|
||||
return true;
|
||||
|
||||
t = t.unannotatedType();
|
||||
s = s.unannotatedType();
|
||||
|
||||
if (t == s)
|
||||
return true;
|
||||
|
||||
@ -1683,6 +1695,7 @@ public class Types {
|
||||
case WILDCARD:
|
||||
return elemtype(upperBound(t));
|
||||
case ARRAY:
|
||||
t = t.unannotatedType();
|
||||
return ((ArrayType)t).elemtype;
|
||||
case FORALL:
|
||||
return elemtype(((ForAll)t).qtype);
|
||||
@ -2011,6 +2024,11 @@ public class Types {
|
||||
public Type visitErrorType(ErrorType t, Boolean recurse) {
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
|
||||
return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse));
|
||||
}
|
||||
};
|
||||
|
||||
private Mapping erasureFun = new Mapping ("erasure") {
|
||||
@ -2953,6 +2971,7 @@ public class Types {
|
||||
* graph. Undefined for all but reference types.
|
||||
*/
|
||||
public int rank(Type t) {
|
||||
t = t.unannotatedType();
|
||||
switch(t.tag) {
|
||||
case CLASS: {
|
||||
ClassType cls = (ClassType)t;
|
||||
@ -3654,6 +3673,7 @@ public class Types {
|
||||
t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
|
||||
}
|
||||
}
|
||||
t = t.unannotatedType();
|
||||
ClassType cls = (ClassType)t;
|
||||
if (cls.isRaw() || !cls.isParameterized())
|
||||
return cls;
|
||||
@ -4172,6 +4192,8 @@ public class Types {
|
||||
public R visitForAll(ForAll t, S s) { return visitType(t, s); }
|
||||
public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); }
|
||||
public R visitErrorType(ErrorType t, S s) { return visitType(t, s); }
|
||||
// Pretend annotations don't exist
|
||||
public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,6 +26,7 @@
|
||||
package com.sun.tools.javac.comp;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.code.*;
|
||||
@ -87,20 +88,30 @@ public class Annotate {
|
||||
private int enterCount = 0;
|
||||
|
||||
ListBuffer<Annotator> q = new ListBuffer<Annotator>();
|
||||
ListBuffer<Annotator> typesQ = new ListBuffer<Annotator>();
|
||||
ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
|
||||
|
||||
public void normal(Annotator a) {
|
||||
q.append(a);
|
||||
}
|
||||
ListBuffer<Annotator> afterRepeatedQ = new ListBuffer<Annotator>();
|
||||
|
||||
public void earlier(Annotator a) {
|
||||
q.prepend(a);
|
||||
}
|
||||
|
||||
public void normal(Annotator a) {
|
||||
q.append(a);
|
||||
}
|
||||
|
||||
public void typeAnnotation(Annotator a) {
|
||||
typesQ.append(a);
|
||||
}
|
||||
|
||||
public void repeated(Annotator a) {
|
||||
repeatedQ.append(a);
|
||||
}
|
||||
|
||||
public void afterRepeated(Annotator a) {
|
||||
afterRepeatedQ.append(a);
|
||||
}
|
||||
|
||||
/** Called when the Enter phase starts. */
|
||||
public void enterStart() {
|
||||
enterCount++;
|
||||
@ -116,12 +127,18 @@ public class Annotate {
|
||||
if (enterCount != 0) return;
|
||||
enterCount++;
|
||||
try {
|
||||
while (q.nonEmpty())
|
||||
while (q.nonEmpty()) {
|
||||
q.next().enterAnnotation();
|
||||
|
||||
}
|
||||
while (typesQ.nonEmpty()) {
|
||||
typesQ.next().enterAnnotation();
|
||||
}
|
||||
while (repeatedQ.nonEmpty()) {
|
||||
repeatedQ.next().enterAnnotation();
|
||||
}
|
||||
while (afterRepeatedQ.nonEmpty()) {
|
||||
afterRepeatedQ.next().enterAnnotation();
|
||||
}
|
||||
} finally {
|
||||
enterCount--;
|
||||
}
|
||||
@ -141,16 +158,18 @@ public class Annotate {
|
||||
* This context contains all the information needed to synthesize new
|
||||
* annotations trees by the completer for repeating annotations.
|
||||
*/
|
||||
public class AnnotateRepeatedContext {
|
||||
public class AnnotateRepeatedContext<T extends Attribute.Compound> {
|
||||
public final Env<AttrContext> env;
|
||||
public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
|
||||
public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
|
||||
public final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated;
|
||||
public final Map<T, JCDiagnostic.DiagnosticPosition> pos;
|
||||
public final Log log;
|
||||
public final boolean isTypeCompound;
|
||||
|
||||
public AnnotateRepeatedContext(Env<AttrContext> env,
|
||||
Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
|
||||
Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos,
|
||||
Log log) {
|
||||
Map<Symbol.TypeSymbol, ListBuffer<T>> annotated,
|
||||
Map<T, JCDiagnostic.DiagnosticPosition> pos,
|
||||
Log log,
|
||||
boolean isTypeCompound) {
|
||||
Assert.checkNonNull(env);
|
||||
Assert.checkNonNull(annotated);
|
||||
Assert.checkNonNull(pos);
|
||||
@ -160,6 +179,7 @@ public class Annotate {
|
||||
this.annotated = annotated;
|
||||
this.pos = pos;
|
||||
this.log = log;
|
||||
this.isTypeCompound = isTypeCompound;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,7 +190,7 @@ public class Annotate {
|
||||
* @param repeatingAnnotations a List of repeating annotations
|
||||
* @return a new Attribute.Compound that is the container for the repeatingAnnotations
|
||||
*/
|
||||
public Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> repeatingAnnotations, Symbol sym) {
|
||||
public T processRepeatedAnnotations(List<T> repeatingAnnotations, Symbol sym) {
|
||||
return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this, sym);
|
||||
}
|
||||
|
||||
@ -246,7 +266,12 @@ public class Annotate {
|
||||
((MethodSymbol)method, value));
|
||||
t.type = result;
|
||||
}
|
||||
return new Attribute.Compound(a.type, buf.toList());
|
||||
// TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation.
|
||||
// However, how do we find the correct position?
|
||||
Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
|
||||
// TODO: is this something we want? Who would use it?
|
||||
// a.attribute = ac;
|
||||
return ac;
|
||||
}
|
||||
|
||||
Attribute enterAttributeValue(Type expected,
|
||||
@ -329,6 +354,15 @@ public class Annotate {
|
||||
return new Attribute.Error(attr.attribExpr(tree, env, expected));
|
||||
}
|
||||
|
||||
Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
|
||||
Type expected,
|
||||
Env<AttrContext> env) {
|
||||
Attribute.Compound c = enterAnnotation(a, expected, env);
|
||||
Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition());
|
||||
a.attribute = tc;
|
||||
return tc;
|
||||
}
|
||||
|
||||
/* *********************************
|
||||
* Support for repeating annotations
|
||||
***********************************/
|
||||
@ -337,10 +371,10 @@ public class Annotate {
|
||||
* synthesized container annotation or null IFF all repeating
|
||||
* annotation are invalid. This method reports errors/warnings.
|
||||
*/
|
||||
private Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> annotations,
|
||||
AnnotateRepeatedContext ctx,
|
||||
Symbol on) {
|
||||
Attribute.Compound firstOccurrence = annotations.head;
|
||||
private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
|
||||
AnnotateRepeatedContext<T> ctx,
|
||||
Symbol on) {
|
||||
T firstOccurrence = annotations.head;
|
||||
List<Attribute> repeated = List.nil();
|
||||
Type origAnnoType = null;
|
||||
Type arrayOfOrigAnnoType = null;
|
||||
@ -350,16 +384,16 @@ public class Annotate {
|
||||
Assert.check(!annotations.isEmpty() &&
|
||||
!annotations.tail.isEmpty()); // i.e. size() > 1
|
||||
|
||||
for (List<Attribute.Compound> al = annotations;
|
||||
for (List<T> al = annotations;
|
||||
!al.isEmpty();
|
||||
al = al.tail)
|
||||
{
|
||||
Attribute.Compound currentAnno = al.head;
|
||||
T currentAnno = al.head;
|
||||
|
||||
origAnnoType = currentAnno.type;
|
||||
if (arrayOfOrigAnnoType == null) {
|
||||
arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
|
||||
}
|
||||
}
|
||||
|
||||
Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno));
|
||||
if (currentContainerType == null) {
|
||||
@ -383,25 +417,46 @@ public class Annotate {
|
||||
|
||||
if (!repeated.isEmpty()) {
|
||||
repeated = repeated.reverse();
|
||||
JCAnnotation annoTree;
|
||||
TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
|
||||
Pair<MethodSymbol, Attribute> p =
|
||||
new Pair<MethodSymbol, Attribute>(containerValueSymbol,
|
||||
new Attribute.Array(arrayOfOrigAnnoType, repeated));
|
||||
annoTree = m.Annotation(new Attribute.Compound(targetContainerType,
|
||||
List.of(p)));
|
||||
if (ctx.isTypeCompound) {
|
||||
/* TODO: the following code would be cleaner:
|
||||
Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
|
||||
((Attribute.TypeCompound)annotations.head).position);
|
||||
JCTypeAnnotation annoTree = m.TypeAnnotation(at);
|
||||
at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env);
|
||||
*/
|
||||
// However, we directly construct the TypeCompound to keep the
|
||||
// direct relation to the contained TypeCompounds.
|
||||
Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
|
||||
((Attribute.TypeCompound)annotations.head).position);
|
||||
|
||||
if (!chk.annotationApplicable(annoTree, on))
|
||||
log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
|
||||
// TODO: annotation applicability checks from below?
|
||||
|
||||
if (!chk.validateAnnotationDeferErrors(annoTree))
|
||||
log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
|
||||
at.setSynthesized(true);
|
||||
|
||||
Attribute.Compound c = enterAnnotation(annoTree,
|
||||
targetContainerType,
|
||||
ctx.env);
|
||||
c.setSynthesized(true);
|
||||
return c;
|
||||
@SuppressWarnings("unchecked")
|
||||
T x = (T) at;
|
||||
return x;
|
||||
} else {
|
||||
Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
|
||||
JCAnnotation annoTree = m.Annotation(c);
|
||||
|
||||
if (!chk.annotationApplicable(annoTree, on))
|
||||
log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
|
||||
|
||||
if (!chk.validateAnnotationDeferErrors(annoTree))
|
||||
log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
|
||||
|
||||
c = enterAnnotation(annoTree, targetContainerType, ctx.env);
|
||||
c.setSynthesized(true);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T x = (T) c;
|
||||
return x;
|
||||
}
|
||||
} else {
|
||||
return null; // errors should have been reported elsewhere
|
||||
}
|
||||
|
@ -26,9 +26,9 @@
|
||||
package com.sun.tools.javac.comp;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.source.tree.IdentifierTree;
|
||||
@ -45,7 +45,6 @@ import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
|
||||
import com.sun.tools.javac.comp.Infer.InferenceContext;
|
||||
import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.jvm.Target;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
|
||||
@ -880,6 +879,7 @@ public class Attr extends JCTree.Visitor {
|
||||
deferredLintHandler.flush(tree.pos());
|
||||
chk.checkDeprecatedAnnotation(tree.pos(), m);
|
||||
|
||||
|
||||
// Create a new environment with local scope
|
||||
// for attributing the method.
|
||||
Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
|
||||
@ -923,6 +923,21 @@ public class Attr extends JCTree.Visitor {
|
||||
// Check that result type is well-formed.
|
||||
chk.validate(tree.restype, localEnv);
|
||||
|
||||
// Check that receiver type is well-formed.
|
||||
if (tree.recvparam != null) {
|
||||
// Use a new environment to check the receiver parameter.
|
||||
// Otherwise I get "might not have been initialized" errors.
|
||||
// Is there a better way?
|
||||
Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
|
||||
attribType(tree.recvparam, newEnv);
|
||||
chk.validate(tree.recvparam, newEnv);
|
||||
if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
|
||||
// The == covers the common non-generic case, but for generic classes we need isSameType;
|
||||
// note that equals didn't work.
|
||||
log.error(tree.recvparam.pos(), "incorrect.receiver.type");
|
||||
}
|
||||
}
|
||||
|
||||
// annotation method checks
|
||||
if ((owner.flags() & ANNOTATION) != 0) {
|
||||
// annotation method cannot have throws clause
|
||||
@ -996,9 +1011,14 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
// Attribute all type annotations in the body
|
||||
memberEnter.typeAnnotate(tree.body, localEnv, m);
|
||||
annotate.flush();
|
||||
|
||||
// Attribute method body.
|
||||
attribStat(tree.body, localEnv);
|
||||
}
|
||||
|
||||
localEnv.info.scope.leave();
|
||||
result = tree.type = m.type;
|
||||
chk.validateAnnotations(tree.mods.annotations, m);
|
||||
@ -1019,6 +1039,12 @@ public class Attr extends JCTree.Visitor {
|
||||
memberEnter.memberEnter(tree, env);
|
||||
annotate.flush();
|
||||
}
|
||||
} else {
|
||||
if (tree.init != null) {
|
||||
// Field initializer expression need to be entered.
|
||||
memberEnter.typeAnnotate(tree.init, env, tree.sym);
|
||||
annotate.flush();
|
||||
}
|
||||
}
|
||||
|
||||
VarSymbol v = tree.sym;
|
||||
@ -1076,6 +1102,11 @@ public class Attr extends JCTree.Visitor {
|
||||
new MethodSymbol(tree.flags | BLOCK, names.empty, null,
|
||||
env.info.scope.owner);
|
||||
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
|
||||
|
||||
// Attribute all type annotations in the block
|
||||
memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
|
||||
annotate.flush();
|
||||
|
||||
attribStats(tree.stats, localEnv);
|
||||
} else {
|
||||
// Create a new local environment with a local scope.
|
||||
@ -1847,10 +1878,24 @@ public class Attr extends JCTree.Visitor {
|
||||
// If enclosing class is given, attribute it, and
|
||||
// complete class name to be fully qualified
|
||||
JCExpression clazz = tree.clazz; // Class field following new
|
||||
JCExpression clazzid = // Identifier in class field
|
||||
(clazz.hasTag(TYPEAPPLY))
|
||||
? ((JCTypeApply) clazz).clazz
|
||||
: clazz;
|
||||
JCExpression clazzid; // Identifier in class field
|
||||
JCAnnotatedType annoclazzid; // Annotated type enclosing clazzid
|
||||
annoclazzid = null;
|
||||
|
||||
if (clazz.hasTag(TYPEAPPLY)) {
|
||||
clazzid = ((JCTypeApply) clazz).clazz;
|
||||
if (clazzid.hasTag(ANNOTATED_TYPE)) {
|
||||
annoclazzid = (JCAnnotatedType) clazzid;
|
||||
clazzid = annoclazzid.underlyingType;
|
||||
}
|
||||
} else {
|
||||
if (clazz.hasTag(ANNOTATED_TYPE)) {
|
||||
annoclazzid = (JCAnnotatedType) clazz;
|
||||
clazzid = annoclazzid.underlyingType;
|
||||
} else {
|
||||
clazzid = clazz;
|
||||
}
|
||||
}
|
||||
|
||||
JCExpression clazzid1 = clazzid; // The same in fully qualified form
|
||||
|
||||
@ -1865,14 +1910,30 @@ public class Attr extends JCTree.Visitor {
|
||||
// yields a clazz T.C.
|
||||
Type encltype = chk.checkRefType(tree.encl.pos(),
|
||||
attribExpr(tree.encl, env));
|
||||
// TODO 308: in <expr>.new C, do we also want to add the type annotations
|
||||
// from expr to the combined type, or not? Yes, do this.
|
||||
clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
|
||||
((JCIdent) clazzid).name);
|
||||
if (clazz.hasTag(TYPEAPPLY))
|
||||
clazz = make.at(tree.pos).
|
||||
|
||||
if (clazz.hasTag(ANNOTATED_TYPE)) {
|
||||
JCAnnotatedType annoType = (JCAnnotatedType) clazz;
|
||||
List<JCAnnotation> annos = annoType.annotations;
|
||||
|
||||
if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
|
||||
clazzid1 = make.at(tree.pos).
|
||||
TypeApply(clazzid1,
|
||||
((JCTypeApply) clazz).arguments);
|
||||
}
|
||||
|
||||
clazzid1 = make.at(tree.pos).
|
||||
AnnotatedType(annos, clazzid1);
|
||||
} else if (clazz.hasTag(TYPEAPPLY)) {
|
||||
clazzid1 = make.at(tree.pos).
|
||||
TypeApply(clazzid1,
|
||||
((JCTypeApply) clazz).arguments);
|
||||
else
|
||||
clazz = clazzid1;
|
||||
}
|
||||
|
||||
clazz = clazzid1;
|
||||
}
|
||||
|
||||
// Attribute clazz expression and store
|
||||
@ -1889,6 +1950,9 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.clazz.type = clazztype;
|
||||
TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
|
||||
clazzid.type = ((JCIdent) clazzid).sym.type;
|
||||
if (annoclazzid != null) {
|
||||
annoclazzid.type = clazzid.type;
|
||||
}
|
||||
if (!clazztype.isErroneous()) {
|
||||
if (cdef != null && clazztype.tsym.isInterface()) {
|
||||
log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new");
|
||||
@ -3255,8 +3319,18 @@ public class Attr extends JCTree.Visitor {
|
||||
// Tree<Point>.Visitor.
|
||||
else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
|
||||
Type normOuter = site;
|
||||
if (normOuter.hasTag(CLASS))
|
||||
if (normOuter.hasTag(CLASS)) {
|
||||
normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
|
||||
if (site.getKind() == TypeKind.ANNOTATED) {
|
||||
// Propagate any type annotations.
|
||||
// TODO: should asEnclosingSuper do this?
|
||||
// Note that the type annotations in site will be updated
|
||||
// by annotateType. Therefore, modify site instead
|
||||
// of creating a new AnnotatedType.
|
||||
((AnnotatedType)site).underlyingType = normOuter;
|
||||
normOuter = site;
|
||||
}
|
||||
}
|
||||
if (normOuter == null) // perhaps from an import
|
||||
normOuter = types.erasure(ownOuter);
|
||||
if (normOuter != ownOuter)
|
||||
@ -3644,8 +3718,15 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.type = result = checkIntersection(tree, tree.bounds);
|
||||
}
|
||||
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
TypeVar typeVar = (TypeVar)tree.type;
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
TypeVar typeVar = (TypeVar) tree.type;
|
||||
|
||||
if (tree.annotations != null && tree.annotations.nonEmpty()) {
|
||||
AnnotatedType antype = new AnnotatedType(typeVar);
|
||||
annotateType(antype, tree.annotations);
|
||||
tree.type = antype;
|
||||
}
|
||||
|
||||
if (!typeVar.bound.isErroneous()) {
|
||||
//fixup type-parameter bound computed in 'attribTypeVariables'
|
||||
typeVar.bound = checkIntersection(tree, tree.bounds);
|
||||
@ -3741,6 +3822,44 @@ public class Attr extends JCTree.Visitor {
|
||||
result = tree.type = syms.errType;
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
Type underlyingType = attribType(tree.getUnderlyingType(), env);
|
||||
this.attribAnnotationTypes(tree.annotations, env);
|
||||
AnnotatedType antype = new AnnotatedType(underlyingType);
|
||||
annotateType(antype, tree.annotations);
|
||||
result = tree.type = antype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the annotations to the particular type.
|
||||
*/
|
||||
public void annotateType(final AnnotatedType type, final List<JCAnnotation> annotations) {
|
||||
if (annotations.isEmpty())
|
||||
return;
|
||||
annotate.typeAnnotation(new Annotate.Annotator() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "annotate " + annotations + " onto " + type;
|
||||
}
|
||||
@Override
|
||||
public void enterAnnotation() {
|
||||
List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
|
||||
type.typeAnnotations = compounds;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
|
||||
if (annotations.isEmpty())
|
||||
return List.nil();
|
||||
|
||||
ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
|
||||
for (JCAnnotation anno : annotations) {
|
||||
buf.append((Attribute.TypeCompound) anno.attribute);
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
public void visitErroneous(JCErroneous tree) {
|
||||
if (tree.errs != null)
|
||||
for (JCTree err : tree.errs)
|
||||
@ -3972,6 +4091,12 @@ public class Attr extends JCTree.Visitor {
|
||||
(c.flags() & ABSTRACT) == 0) {
|
||||
checkSerialVersionUID(tree, c);
|
||||
}
|
||||
|
||||
// Correctly organize the postions of the type annotations
|
||||
TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree);
|
||||
|
||||
// Check type annotations applicability rules
|
||||
validateTypeAnnotations(tree);
|
||||
}
|
||||
// where
|
||||
/** get a diagnostic position for an attribute of Type t, or null if attribute missing */
|
||||
@ -4029,6 +4154,94 @@ public class Attr extends JCTree.Visitor {
|
||||
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.hasTag(TYPE_ANNOTATION)) {
|
||||
// TODO: It seems to WMD as if the annotation in
|
||||
// parameters, in particular also the recvparam, are never
|
||||
// of type JCTypeAnnotation and therefore never checked!
|
||||
// Luckily this check doesn't really do anything that isn't
|
||||
// also done elsewhere.
|
||||
chk.validateTypeAnnotation(tree, false);
|
||||
}
|
||||
super.visitAnnotation(tree);
|
||||
}
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
chk.validateTypeAnnotations(tree.annotations, true);
|
||||
scan(tree.bounds);
|
||||
// Don't call super.
|
||||
// This is needed because above we call validateTypeAnnotation with
|
||||
// false, which would forbid annotations on type parameters.
|
||||
// super.visitTypeParameter(tree);
|
||||
}
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
// Static methods cannot have receiver type annotations.
|
||||
// In test case FailOver15.java, the nested method getString has
|
||||
// a null sym, because an unknown class is instantiated.
|
||||
// I would say it's safe to skip.
|
||||
if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
|
||||
if (tree.recvparam != null) {
|
||||
// TODO: better error message. Is the pos good?
|
||||
log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
|
||||
}
|
||||
}
|
||||
if (tree.restype != null && tree.restype.type != null) {
|
||||
validateAnnotatedType(tree.restype, tree.restype.type);
|
||||
}
|
||||
super.visitMethodDef(tree);
|
||||
}
|
||||
public void visitVarDef(final JCVariableDecl tree) {
|
||||
if (tree.sym != null && tree.sym.type != null)
|
||||
validateAnnotatedType(tree, tree.sym.type);
|
||||
super.visitVarDef(tree);
|
||||
}
|
||||
public void visitTypeCast(JCTypeCast tree) {
|
||||
if (tree.clazz != null && tree.clazz.type != null)
|
||||
validateAnnotatedType(tree.clazz, tree.clazz.type);
|
||||
super.visitTypeCast(tree);
|
||||
}
|
||||
public void visitTypeTest(JCInstanceOf tree) {
|
||||
if (tree.clazz != null && tree.clazz.type != null)
|
||||
validateAnnotatedType(tree.clazz, tree.clazz.type);
|
||||
super.visitTypeTest(tree);
|
||||
}
|
||||
// TODO: what else do we need?
|
||||
// public void visitNewClass(JCNewClass tree) {
|
||||
// public void visitNewArray(JCNewArray tree) {
|
||||
|
||||
/* I would want to model this after
|
||||
* com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
|
||||
* and override visitSelect and visitTypeApply.
|
||||
* However, we only set the annotated type in the top-level type
|
||||
* of the symbol.
|
||||
* Therefore, we need to override each individual location where a type
|
||||
* can occur.
|
||||
*/
|
||||
private void validateAnnotatedType(final JCTree errtree, final Type type) {
|
||||
if (type.getEnclosingType() != null &&
|
||||
type != type.getEnclosingType()) {
|
||||
validateEnclosingAnnotatedType(errtree, type.getEnclosingType());
|
||||
}
|
||||
for (Type targ : type.getTypeArguments()) {
|
||||
validateAnnotatedType(errtree, targ);
|
||||
}
|
||||
}
|
||||
private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) {
|
||||
validateAnnotatedType(errtree, type);
|
||||
if (type.tsym != null &&
|
||||
type.tsym.isStatic() &&
|
||||
type.getAnnotations().nonEmpty()) {
|
||||
// Enclosing static classes cannot have type annotations.
|
||||
log.error(errtree.pos(), "cant.annotate.static.class");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// <editor-fold desc="post-attribution visitor">
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,7 @@
|
||||
package com.sun.tools.javac.comp;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
@ -101,6 +101,9 @@ public class Check {
|
||||
context.put(checkKey, this);
|
||||
|
||||
names = Names.instance(context);
|
||||
dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
|
||||
names.FIELD, names.METHOD, names.CONSTRUCTOR,
|
||||
names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
|
||||
log = Log.instance(context);
|
||||
rs = Resolve.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
@ -572,35 +575,28 @@ public class Check {
|
||||
if (!tree.type.isErroneous() &&
|
||||
(env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
|
||||
&& types.isSameType(tree.expr.type, tree.clazz.type)
|
||||
&& !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
|
||||
&& !is292targetTypeCast(tree)) {
|
||||
log.warning(Lint.LintCategory.CAST,
|
||||
tree.pos(), "redundant.cast", tree.expr.type);
|
||||
}
|
||||
}
|
||||
//where
|
||||
private boolean is292targetTypeCast(JCTypeCast tree) {
|
||||
boolean is292targetTypeCast = false;
|
||||
JCExpression expr = TreeInfo.skipParens(tree.expr);
|
||||
if (expr.hasTag(APPLY)) {
|
||||
JCMethodInvocation apply = (JCMethodInvocation)expr;
|
||||
Symbol sym = TreeInfo.symbol(apply.meth);
|
||||
is292targetTypeCast = sym != null &&
|
||||
sym.kind == MTH &&
|
||||
(sym.flags() & HYPOTHETICAL) != 0;
|
||||
}
|
||||
return is292targetTypeCast;
|
||||
private boolean is292targetTypeCast(JCTypeCast tree) {
|
||||
boolean is292targetTypeCast = false;
|
||||
JCExpression expr = TreeInfo.skipParens(tree.expr);
|
||||
if (expr.hasTag(APPLY)) {
|
||||
JCMethodInvocation apply = (JCMethodInvocation)expr;
|
||||
Symbol sym = TreeInfo.symbol(apply.meth);
|
||||
is292targetTypeCast = sym != null &&
|
||||
sym.kind == MTH &&
|
||||
(sym.flags() & HYPOTHETICAL) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//where
|
||||
/** Is type a type variable, or a (possibly multi-dimensional) array of
|
||||
* type variables?
|
||||
*/
|
||||
boolean isTypeVar(Type t) {
|
||||
return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t));
|
||||
return is292targetTypeCast;
|
||||
}
|
||||
|
||||
private static final boolean ignoreAnnotatedCasts = true;
|
||||
|
||||
/** Check that a type is within some bounds.
|
||||
*
|
||||
* Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
|
||||
@ -853,7 +849,7 @@ public class Check {
|
||||
// System.out.println("actuals: " + argtypes);
|
||||
List<Type> formals = owntype.getParameterTypes();
|
||||
Type last = useVarargs ? formals.last() : null;
|
||||
if (sym.name==names.init &&
|
||||
if (sym.name == names.init &&
|
||||
sym.owner == syms.enumSym)
|
||||
formals = formals.tail.tail;
|
||||
List<JCExpression> args = argtrees;
|
||||
@ -1326,6 +1322,11 @@ public class Check {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
tree.underlyingType.accept(this);
|
||||
}
|
||||
|
||||
/** Default visitor method: do nothing.
|
||||
*/
|
||||
@Override
|
||||
@ -2246,7 +2247,7 @@ public class Check {
|
||||
void checkImplementations(JCClassDecl tree) {
|
||||
checkImplementations(tree, tree.sym, tree.sym);
|
||||
}
|
||||
//where
|
||||
//where
|
||||
/** Check that all methods which implement some
|
||||
* method in `ic' conform to the method they implement.
|
||||
*/
|
||||
@ -2587,6 +2588,13 @@ public class Check {
|
||||
validateAnnotation(a, s);
|
||||
}
|
||||
|
||||
/** Check the type annotations.
|
||||
*/
|
||||
public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
|
||||
for (JCAnnotation a : annotations)
|
||||
validateTypeAnnotation(a, isTypeParameter);
|
||||
}
|
||||
|
||||
/** Check an annotation of a symbol.
|
||||
*/
|
||||
private void validateAnnotation(JCAnnotation a, Symbol s) {
|
||||
@ -2613,6 +2621,14 @@ public class Check {
|
||||
}
|
||||
}
|
||||
|
||||
public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
|
||||
Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a);
|
||||
validateAnnotationTree(a);
|
||||
|
||||
if (!isTypeAnnotation(a, isTypeParameter))
|
||||
log.error(a.pos(), "annotation.type.not.applicable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the proposed container 'repeatable' on the
|
||||
* annotation type symbol 's'. Report errors at position
|
||||
@ -2795,45 +2811,90 @@ public class Check {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Is the annotation applicable to type annotations? */
|
||||
protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
|
||||
Attribute.Compound atTarget =
|
||||
a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
|
||||
if (atTarget == null) {
|
||||
// An annotation without @Target is not a type annotation.
|
||||
return false;
|
||||
}
|
||||
|
||||
Attribute atValue = atTarget.member(names.value);
|
||||
if (!(atValue instanceof Attribute.Array)) {
|
||||
return false; // error recovery
|
||||
}
|
||||
|
||||
Attribute.Array arr = (Attribute.Array) atValue;
|
||||
for (Attribute app : arr.values) {
|
||||
if (!(app instanceof Attribute.Enum)) {
|
||||
return false; // recovery
|
||||
}
|
||||
Attribute.Enum e = (Attribute.Enum) app;
|
||||
|
||||
if (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.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
|
||||
Name[] targets;
|
||||
|
||||
if (arr == null) {
|
||||
return true;
|
||||
targets = defaultTargetMetaInfo(a, s);
|
||||
} else {
|
||||
// TODO: can we optimize this?
|
||||
targets = new Name[arr.values.length];
|
||||
for (int i=0; i<arr.values.length; ++i) {
|
||||
Attribute app = arr.values[i];
|
||||
if (!(app instanceof Attribute.Enum)) {
|
||||
return true; // recovery
|
||||
}
|
||||
Attribute.Enum e = (Attribute.Enum) app;
|
||||
targets[i] = e.value.name;
|
||||
}
|
||||
}
|
||||
for (Attribute app : arr.values) {
|
||||
if (!(app instanceof Attribute.Enum)) return true; // recovery
|
||||
Attribute.Enum e = (Attribute.Enum) app;
|
||||
if (e.value.name == names.TYPE)
|
||||
for (Name target : targets) {
|
||||
if (target == names.TYPE)
|
||||
{ if (s.kind == TYP) return true; }
|
||||
else if (e.value.name == names.FIELD)
|
||||
else if (target == names.FIELD)
|
||||
{ if (s.kind == VAR && s.owner.kind != MTH) return true; }
|
||||
else if (e.value.name == names.METHOD)
|
||||
else if (target == names.METHOD)
|
||||
{ if (s.kind == MTH && !s.isConstructor()) return true; }
|
||||
else if (e.value.name == names.PARAMETER)
|
||||
else if (target == names.PARAMETER)
|
||||
{ if (s.kind == VAR &&
|
||||
s.owner.kind == MTH &&
|
||||
(s.flags() & PARAMETER) != 0)
|
||||
return true;
|
||||
}
|
||||
else if (e.value.name == names.CONSTRUCTOR)
|
||||
else if (target == names.CONSTRUCTOR)
|
||||
{ if (s.kind == MTH && s.isConstructor()) return true; }
|
||||
else if (e.value.name == names.LOCAL_VARIABLE)
|
||||
else if (target == names.LOCAL_VARIABLE)
|
||||
{ if (s.kind == VAR && s.owner.kind == MTH &&
|
||||
(s.flags() & PARAMETER) == 0)
|
||||
return true;
|
||||
}
|
||||
else if (e.value.name == names.ANNOTATION_TYPE)
|
||||
else if (target == names.ANNOTATION_TYPE)
|
||||
{ if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
|
||||
return true;
|
||||
}
|
||||
else if (e.value.name == names.PACKAGE)
|
||||
else if (target == names.PACKAGE)
|
||||
{ if (s.kind == PCK) return true; }
|
||||
else if (e.value.name == names.TYPE_USE)
|
||||
else if (target == names.TYPE_USE)
|
||||
{ if (s.kind == TYP ||
|
||||
s.kind == VAR ||
|
||||
(s.kind == MTH && !s.isConstructor() &&
|
||||
!s.type.getReturnType().hasTag(VOID)))
|
||||
!s.type.getReturnType().hasTag(VOID)) ||
|
||||
(s.kind == MTH && s.isConstructor()))
|
||||
return true;
|
||||
}
|
||||
else if (target == names.TYPE_PARAMETER)
|
||||
{ if (s.kind == TYP && s.type.hasTag(TYPEVAR))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -2852,6 +2913,11 @@ public class Check {
|
||||
return (Attribute.Array) atValue;
|
||||
}
|
||||
|
||||
private final Name[] dfltTargetMeta;
|
||||
private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
|
||||
return dfltTargetMeta;
|
||||
}
|
||||
|
||||
/** Check an annotation value.
|
||||
*
|
||||
* @param a The annotation tree to check
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,8 +29,6 @@ import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
|
||||
|
||||
import static com.sun.tools.javac.jvm.ByteCodes.*;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,6 +35,7 @@ import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.comp.Resolve;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
@ -2175,6 +2176,11 @@ public class Flow {
|
||||
unrefdResources.remove(sym);
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
// annotations don't get scanned
|
||||
tree.underlyingType.accept(this);
|
||||
}
|
||||
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
// Do nothing for TopLevel since each class is visited individually
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2288,7 +2288,7 @@ public class Lower extends TreeTranslator {
|
||||
return tree.packageAnnotations.nonEmpty();
|
||||
case NONEMPTY:
|
||||
for (Attribute.Compound a :
|
||||
tree.packge.annotations.getAttributes()) {
|
||||
tree.packge.annotations.getDeclarationAttributes()) {
|
||||
Attribute.RetentionPolicy p = types.getRetention(a);
|
||||
if (p != Attribute.RetentionPolicy.SOURCE)
|
||||
return true;
|
||||
@ -2685,6 +2685,13 @@ public class Lower extends TreeTranslator {
|
||||
result = tree;
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
// No need to retain type annotations any longer.
|
||||
// tree.annotations = translate(tree.annotations);
|
||||
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())
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,15 +25,19 @@
|
||||
|
||||
package com.sun.tools.javac.comp;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
@ -345,12 +349,15 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
* @param params The method's value parameters.
|
||||
* @param res The method's result type,
|
||||
* null if it is a constructor.
|
||||
* @param recvparam The method's receiver parameter,
|
||||
* null if none given; TODO: or already set here?
|
||||
* @param thrown The method's thrown exceptions.
|
||||
* @param env The method's (local) environment.
|
||||
*/
|
||||
Type signature(List<JCTypeParameter> typarams,
|
||||
List<JCVariableDecl> params,
|
||||
JCTree res,
|
||||
JCVariableDecl recvparam,
|
||||
List<JCExpression> thrown,
|
||||
Env<AttrContext> env) {
|
||||
|
||||
@ -368,6 +375,15 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
// Attribute result type, if one is given.
|
||||
Type restype = res == null ? syms.voidType : attr.attribType(res, env);
|
||||
|
||||
// Attribute receiver type, if one is given.
|
||||
Type recvtype;
|
||||
if (recvparam!=null) {
|
||||
memberEnter(recvparam, env);
|
||||
recvtype = recvparam.vartype.type;
|
||||
} else {
|
||||
recvtype = null;
|
||||
}
|
||||
|
||||
// Attribute thrown exceptions.
|
||||
ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
|
||||
for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
|
||||
@ -376,10 +392,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
exc = chk.checkClassType(l.head.pos(), exc);
|
||||
thrownbuf.append(exc);
|
||||
}
|
||||
Type mtype = new MethodType(argbuf.toList(),
|
||||
MethodType mtype = new MethodType(argbuf.toList(),
|
||||
restype,
|
||||
thrownbuf.toList(),
|
||||
syms.methodClass);
|
||||
mtype.recvtype = recvtype;
|
||||
|
||||
return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
|
||||
}
|
||||
|
||||
@ -573,7 +591,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
try {
|
||||
// Compute the method type
|
||||
m.type = signature(tree.typarams, tree.params,
|
||||
tree.restype, tree.thrown,
|
||||
tree.restype, tree.recvparam,
|
||||
tree.thrown,
|
||||
localEnv);
|
||||
} finally {
|
||||
chk.setDeferredLintHandler(prevLintHandler);
|
||||
@ -597,6 +616,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
enclScope.enter(m);
|
||||
}
|
||||
annotateLater(tree.mods.annotations, localEnv, m);
|
||||
// Visit the signature of the method. Note that
|
||||
// TypeAnnotate doesn't descend into the body.
|
||||
typeAnnotate(tree, localEnv, m);
|
||||
|
||||
if (tree.defaultValue != null)
|
||||
annotateDefaultValueLater(tree.defaultValue, localEnv, m);
|
||||
}
|
||||
@ -642,7 +665,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
//(a plain array type) with the more precise VarargsType --- we need
|
||||
//to do it this way because varargs is represented in the tree as a modifier
|
||||
//on the parameter declaration, and not as a distinct type of array node.
|
||||
ArrayType atype = (ArrayType)tree.vartype.type;
|
||||
ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType();
|
||||
tree.vartype.type = atype.makeVarargs();
|
||||
}
|
||||
Scope enclScope = enter.enterScope(env);
|
||||
@ -665,6 +688,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
enclScope.enter(v);
|
||||
}
|
||||
annotateLater(tree.mods.annotations, localEnv, v);
|
||||
typeAnnotate(tree.vartype, env, tree.sym);
|
||||
annotate.flush();
|
||||
v.pos = tree.pos;
|
||||
}
|
||||
|
||||
@ -759,7 +784,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
log.error(annotations.head.pos,
|
||||
"already.annotated",
|
||||
kindName(s), s);
|
||||
enterAnnotations(annotations, localEnv, s);
|
||||
actualEnterAnnotations(annotations, localEnv, s);
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
}
|
||||
@ -781,7 +806,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
}
|
||||
|
||||
/** Enter a set of annotations. */
|
||||
private void enterAnnotations(List<JCAnnotation> annotations,
|
||||
private void actualEnterAnnotations(List<JCAnnotation> annotations,
|
||||
Env<AttrContext> env,
|
||||
Symbol s) {
|
||||
Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
|
||||
@ -817,11 +842,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
&& s.owner.kind != MTH
|
||||
&& types.isSameType(c.type, syms.deprecatedType)) {
|
||||
s.flags_field |= Flags.DEPRECATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.annotations.setAttributesWithCompletion(
|
||||
annotate.new AnnotateRepeatedContext(env, annotated, pos, log));
|
||||
s.annotations.setDeclarationAttributesWithCompletion(
|
||||
annotate.new AnnotateRepeatedContext<Attribute.Compound>(env, annotated, pos, log, false));
|
||||
}
|
||||
|
||||
/** Queue processing of an attribute default value. */
|
||||
@ -900,6 +925,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
// create an environment for evaluating the base clauses
|
||||
Env<AttrContext> baseEnv = baseEnv(tree, env);
|
||||
|
||||
if (tree.extending != null)
|
||||
typeAnnotate(tree.extending, baseEnv, sym);
|
||||
for (JCExpression impl : tree.implementing)
|
||||
typeAnnotate(impl, baseEnv, sym);
|
||||
annotate.flush();
|
||||
|
||||
// Determine supertype.
|
||||
Type supertype =
|
||||
(tree.extending != null)
|
||||
@ -969,10 +1000,15 @@ 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
|
||||
|
||||
chk.checkNonCyclicDecl(tree);
|
||||
|
||||
attr.attribTypeVariables(tree.typarams, baseEnv);
|
||||
// Do this here, where we have the symbol.
|
||||
for (JCTypeParameter tp : tree.typarams)
|
||||
typeAnnotate(tp, baseEnv, sym);
|
||||
annotate.flush();
|
||||
|
||||
// Add default constructor if needed.
|
||||
if ((c.flags() & INTERFACE) == 0 &&
|
||||
@ -1050,12 +1086,120 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
} finally {
|
||||
isFirst = true;
|
||||
}
|
||||
}
|
||||
annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree));
|
||||
}
|
||||
|
||||
// commit pending annotations
|
||||
annotate.flush();
|
||||
private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
|
||||
final Env<AttrContext> env,
|
||||
final Symbol s) {
|
||||
Map<TypeSymbol, ListBuffer<Attribute.TypeCompound>> annotated =
|
||||
new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.TypeCompound>>();
|
||||
Map<Attribute.TypeCompound, DiagnosticPosition> pos =
|
||||
new HashMap<Attribute.TypeCompound, DiagnosticPosition>();
|
||||
|
||||
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
|
||||
JCAnnotation a = al.head;
|
||||
Attribute.TypeCompound tc = annotate.enterTypeAnnotation(a,
|
||||
syms.annotationType,
|
||||
env);
|
||||
if (tc == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (annotated.containsKey(a.type.tsym)) {
|
||||
if (source.allowRepeatedAnnotations()) {
|
||||
ListBuffer<Attribute.TypeCompound> l = annotated.get(a.type.tsym);
|
||||
l = l.append(tc);
|
||||
annotated.put(a.type.tsym, l);
|
||||
pos.put(tc, a.pos());
|
||||
} else {
|
||||
log.error(a.pos(), "duplicate.annotation");
|
||||
}
|
||||
} else {
|
||||
annotated.put(a.type.tsym, ListBuffer.of(tc));
|
||||
pos.put(tc, a.pos());
|
||||
}
|
||||
}
|
||||
|
||||
s.annotations.appendTypeAttributesWithCompletion(
|
||||
annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
|
||||
}
|
||||
|
||||
public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
|
||||
tree.accept(new TypeAnnotate(env, sym));
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to use a TreeScanner, because it is not enough to visit the top-level
|
||||
* annotations. We also need to visit type arguments, etc.
|
||||
*/
|
||||
private class TypeAnnotate extends TreeScanner {
|
||||
private Env<AttrContext> env;
|
||||
private Symbol sym;
|
||||
|
||||
public TypeAnnotate(final Env<AttrContext> env, final Symbol sym) {
|
||||
this.env = env;
|
||||
this.sym = sym;
|
||||
}
|
||||
|
||||
void annotateTypeLater(final List<JCAnnotation> annotations) {
|
||||
if (annotations.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
annotate.normal(new Annotate.Annotator() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "type annotate " + annotations + " onto " + sym + " in " + sym.owner;
|
||||
}
|
||||
@Override
|
||||
public void enterAnnotation() {
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
actualEnterTypeAnnotations(annotations, env, sym);
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAnnotatedType(final JCAnnotatedType tree) {
|
||||
annotateTypeLater(tree.annotations);
|
||||
super.visitAnnotatedType(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeParameter(final JCTypeParameter tree) {
|
||||
annotateTypeLater(tree.annotations);
|
||||
super.visitTypeParameter(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewArray(final JCNewArray tree) {
|
||||
annotateTypeLater(tree.annotations);
|
||||
for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
|
||||
annotateTypeLater(dimAnnos);
|
||||
super.visitNewArray(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodDef(final JCMethodDecl tree) {
|
||||
scan(tree.mods);
|
||||
scan(tree.restype);
|
||||
scan(tree.typarams);
|
||||
scan(tree.recvparam);
|
||||
scan(tree.params);
|
||||
scan(tree.thrown);
|
||||
scan(tree.defaultValue);
|
||||
// Do not annotate the body, just the signature.
|
||||
// scan(tree.body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
|
||||
Scope baseScope = new Scope(tree.sym);
|
||||
//import already entered local classes into base scope
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -55,7 +55,6 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
|
||||
@ -696,7 +695,7 @@ public class Resolve {
|
||||
|
||||
if (varargsFormal == null &&
|
||||
argtypes.size() != formals.size()) {
|
||||
report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
|
||||
reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
|
||||
}
|
||||
|
||||
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
|
||||
@ -707,7 +706,7 @@ public class Resolve {
|
||||
}
|
||||
|
||||
if (formals.head != varargsFormal) {
|
||||
report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
|
||||
reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
|
||||
}
|
||||
|
||||
if (useVarargs) {
|
||||
@ -724,7 +723,7 @@ public class Resolve {
|
||||
}
|
||||
}
|
||||
|
||||
private void report(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
|
||||
private void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
|
||||
boolean inferDiag = inferenceContext != infer.emptyContext;
|
||||
InapplicableMethodException ex = inferDiag ?
|
||||
infer.inferenceException : inapplicableMethodException;
|
||||
@ -748,7 +747,7 @@ public class Resolve {
|
||||
} else {
|
||||
if (!isAccessible(env, t)) {
|
||||
Symbol location = env.enclClass.sym;
|
||||
report(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
|
||||
reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -761,7 +760,7 @@ public class Resolve {
|
||||
|
||||
@Override
|
||||
public void report(DiagnosticPosition pos, JCDiagnostic details) {
|
||||
report(methodDiag, deferredAttrContext.inferenceContext, details);
|
||||
reportMC(methodDiag, deferredAttrContext.inferenceContext, details);
|
||||
}
|
||||
};
|
||||
return new MethodResultInfo(to, checkContext);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -483,6 +483,7 @@ public class TransTypes extends TreeTranslator {
|
||||
tree.restype = translate(tree.restype, null);
|
||||
tree.typarams = List.nil();
|
||||
tree.params = translateVarDefs(tree.params);
|
||||
tree.recvparam = translate(tree.recvparam, null);
|
||||
tree.thrown = translate(tree.thrown, null);
|
||||
tree.body = translate(tree.body, tree.sym.erasure(types).getReturnType());
|
||||
tree.type = erasure(tree.type);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -351,8 +351,8 @@ public class ClassReader implements Completer {
|
||||
|
||||
/** Read a byte.
|
||||
*/
|
||||
byte nextByte() {
|
||||
return buf[bp++];
|
||||
int nextByte() {
|
||||
return buf[bp++] & 0xFF;
|
||||
}
|
||||
|
||||
/** Read an integer.
|
||||
@ -1172,6 +1172,19 @@ public class ClassReader implements Completer {
|
||||
}
|
||||
},
|
||||
|
||||
new AttributeReader(names.RuntimeVisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) {
|
||||
protected void read(Symbol sym, int attrLen) {
|
||||
attachTypeAnnotations(sym);
|
||||
}
|
||||
},
|
||||
|
||||
new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) {
|
||||
protected void read(Symbol sym, int attrLen) {
|
||||
attachTypeAnnotations(sym);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// The following attributes for a Code attribute are not currently handled
|
||||
// StackMapTable
|
||||
// SourceDebugExtension
|
||||
@ -1381,6 +1394,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.normal(new TypeAnnotationCompleter(sym, proxies.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Attach the default value for an annotation element.
|
||||
*/
|
||||
void attachAnnotationDefault(final Symbol sym) {
|
||||
@ -1427,6 +1451,111 @@ public class ClassReader implements Completer {
|
||||
return new CompoundAnnotationProxy(t, pairs.toList());
|
||||
}
|
||||
|
||||
TypeAnnotationProxy readTypeAnnotation() {
|
||||
TypeAnnotationPosition position = readPosition();
|
||||
CompoundAnnotationProxy proxy = readCompoundAnnotation();
|
||||
|
||||
return new TypeAnnotationProxy(proxy, position);
|
||||
}
|
||||
|
||||
TypeAnnotationPosition readPosition() {
|
||||
int tag = nextByte(); // TargetType tag is a byte
|
||||
|
||||
if (!TargetType.isValidTargetTypeValue(tag))
|
||||
throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
|
||||
|
||||
TypeAnnotationPosition position = new TypeAnnotationPosition();
|
||||
TargetType type = TargetType.fromTargetTypeValue(tag);
|
||||
|
||||
position.type = type;
|
||||
|
||||
switch (type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
position.offset = nextChar();
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
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;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
position.exception_index = nextByte();
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
position.parameter_index = nextByte();
|
||||
break;
|
||||
// type parameter bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
position.parameter_index = nextByte();
|
||||
position.bound_index = nextByte();
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
position.type_index = nextChar();
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
position.type_index = nextChar();
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
position.parameter_index = nextByte();
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
position.offset = nextChar();
|
||||
position.type_index = nextByte();
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
position.parameter_index = nextByte();
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
|
||||
default:
|
||||
throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + position);
|
||||
}
|
||||
|
||||
{ // See whether there is location info and read it
|
||||
int len = nextByte();
|
||||
ListBuffer<Integer> loc = ListBuffer.lb();
|
||||
for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i)
|
||||
loc = loc.append(nextByte());
|
||||
position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList());
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
Attribute readAttributeValue() {
|
||||
char c = (char) buf[bp++];
|
||||
switch (c) {
|
||||
@ -1748,7 +1877,7 @@ public class ClassReader implements Completer {
|
||||
Annotations annotations = sym.annotations;
|
||||
List<Attribute.Compound> newList = deproxyCompoundList(l);
|
||||
if (annotations.pendingCompletion()) {
|
||||
annotations.setAttributes(newList);
|
||||
annotations.setDeclarationAttributes(newList);
|
||||
} else {
|
||||
annotations.append(newList);
|
||||
}
|
||||
@ -1758,6 +1887,39 @@ 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);
|
||||
sym.annotations.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes()));
|
||||
} finally {
|
||||
currentClassFile = previousClassFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Reading Symbols
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,12 +31,14 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
|
||||
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.code.Types.UniqueType;
|
||||
@ -47,7 +49,6 @@ import com.sun.tools.javac.jvm.Pool.MethodHandle;
|
||||
import com.sun.tools.javac.jvm.Pool.Variable;
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
import static com.sun.tools.javac.code.BoundKind.*;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Kinds.*;
|
||||
import static com.sun.tools.javac.code.TypeTag.*;
|
||||
@ -68,19 +69,17 @@ public class ClassWriter extends ClassFile {
|
||||
protected static final Context.Key<ClassWriter> classWriterKey =
|
||||
new Context.Key<ClassWriter>();
|
||||
|
||||
private final Symtab syms;
|
||||
|
||||
private final Options options;
|
||||
|
||||
/** Switch: verbose output.
|
||||
*/
|
||||
private boolean verbose;
|
||||
|
||||
/** Switch: scramble private names.
|
||||
/** Switch: scramble private field names.
|
||||
*/
|
||||
private boolean scramble;
|
||||
|
||||
/** Switch: scramble private names.
|
||||
/** Switch: scramble all field names.
|
||||
*/
|
||||
private boolean scrambleAll;
|
||||
|
||||
@ -96,7 +95,7 @@ public class ClassWriter extends ClassFile {
|
||||
*/
|
||||
private boolean genCrt;
|
||||
|
||||
/** Switch: describe the generated stackmap
|
||||
/** Switch: describe the generated stackmap.
|
||||
*/
|
||||
boolean debugstackmap;
|
||||
|
||||
@ -114,7 +113,7 @@ public class ClassWriter extends ClassFile {
|
||||
private Types types;
|
||||
|
||||
/** The initial sizes of the data and constant pool buffers.
|
||||
* sizes are increased when buffers get full.
|
||||
* Sizes are increased when buffers get full.
|
||||
*/
|
||||
static final int DATA_BUF_SIZE = 0x0fff0;
|
||||
static final int POOL_BUF_SIZE = 0x1fff0;
|
||||
@ -181,7 +180,6 @@ public class ClassWriter extends ClassFile {
|
||||
|
||||
log = Log.instance(context);
|
||||
names = Names.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
options = Options.instance(context);
|
||||
target = Target.instance(context);
|
||||
source = Source.instance(context);
|
||||
@ -279,6 +277,7 @@ public class ClassWriter extends ClassFile {
|
||||
/** Assemble signature of given type in string buffer.
|
||||
*/
|
||||
void assembleSig(Type type) {
|
||||
type = type.unannotatedType();
|
||||
switch (type.getTag()) {
|
||||
case BYTE:
|
||||
sigbuf.appendByte('B');
|
||||
@ -379,6 +378,7 @@ public class ClassWriter extends ClassFile {
|
||||
}
|
||||
|
||||
void assembleClassSig(Type type) {
|
||||
type = type.unannotatedType();
|
||||
ClassType ct = (ClassType)type;
|
||||
ClassSymbol c = (ClassSymbol)ct.tsym;
|
||||
enterInner(c);
|
||||
@ -722,6 +722,7 @@ public class ClassWriter extends ClassFile {
|
||||
acount++;
|
||||
}
|
||||
acount += writeJavaAnnotations(sym.getRawAttributes());
|
||||
acount += writeTypeAnnotations(sym.getRawTypeAttributes());
|
||||
return acount;
|
||||
}
|
||||
|
||||
@ -838,6 +839,76 @@ 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 == null || tc.position.type == TargetType.UNKNOWN) {
|
||||
boolean found = false;
|
||||
// TODO: the position for the container annotation of a
|
||||
// repeating type annotation has to be set.
|
||||
// This cannot be done when the container is created, because
|
||||
// then the position is not determined yet.
|
||||
// How can we link these pieces better together?
|
||||
if (tc.values.size() == 1) {
|
||||
Pair<MethodSymbol, Attribute> val = tc.values.get(0);
|
||||
if (val.fst.getSimpleName().contentEquals("value") &&
|
||||
val.snd instanceof Attribute.Array) {
|
||||
Attribute.Array arr = (Attribute.Array) val.snd;
|
||||
if (arr.values.length != 0 &&
|
||||
arr.values[0] instanceof Attribute.TypeCompound) {
|
||||
TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0];
|
||||
if (atycomp.position.type != TargetType.UNKNOWN) {
|
||||
tc.position = atycomp.position;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// This happens for nested types like @A Outer. @B Inner.
|
||||
// For method parameters we get the annotation twice! Once with
|
||||
// a valid position, once unknown.
|
||||
// TODO: find a cleaner solution.
|
||||
// System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!tc.position.emitToClassfile())
|
||||
continue;
|
||||
switch (types.getRetention(tc)) {
|
||||
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 visitor to write an attribute including its leading
|
||||
* single-character marker.
|
||||
*/
|
||||
@ -914,6 +985,94 @@ public class ClassWriter extends ClassFile {
|
||||
p.snd.accept(awriter);
|
||||
}
|
||||
}
|
||||
|
||||
void writeTypeAnnotation(Attribute.TypeCompound c) {
|
||||
writePosition(c.position);
|
||||
writeCompoundAttribute(c);
|
||||
}
|
||||
|
||||
void writePosition(TypeAnnotationPosition p) {
|
||||
databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
|
||||
switch (p.type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
databuf.appendChar(p.offset);
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
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;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
databuf.appendByte(p.exception_index);
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
break;
|
||||
// type parameter bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
databuf.appendByte(p.bound_index);
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
databuf.appendChar(p.type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
databuf.appendChar(p.type_index);
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
databuf.appendChar(p.offset);
|
||||
databuf.appendByte(p.type_index);
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
databuf.appendByte(p.parameter_index);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
|
||||
default:
|
||||
throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p);
|
||||
}
|
||||
|
||||
{ // Append location data for generics/arrays.
|
||||
databuf.appendByte(p.location.size());
|
||||
java.util.List<Integer> loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location);
|
||||
for (int i : loc)
|
||||
databuf.appendByte((byte)i);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Writing Objects
|
||||
**********************************************************************/
|
||||
@ -1661,6 +1820,7 @@ public class ClassWriter extends ClassFile {
|
||||
|
||||
acount += writeFlagAttrs(c.flags());
|
||||
acount += writeJavaAnnotations(c.getRawAttributes());
|
||||
acount += writeTypeAnnotations(c.getRawTypeAttributes());
|
||||
acount += writeEnclosingMethodAttribute(c);
|
||||
acount += writeExtraClassAttributes(c);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1924,17 +1924,70 @@ 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.annotations.isTypesEmpty())
|
||||
return;
|
||||
for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
|
||||
TypeAnnotationPosition p = ta.position;
|
||||
p.lvarOffset = new int[] { (int)lv.start_pc };
|
||||
p.lvarLength = new int[] { (int)lv.length };
|
||||
p.lvarIndex = new int[] { (int)lv.reg };
|
||||
p.isValidOffset = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Method to be called after compressCatchTable to
|
||||
// fill in the exception table index for type
|
||||
// annotations on exception parameters.
|
||||
public void fillExceptionParameterPositions() {
|
||||
for (int i = 0; i < varBufferSize; ++i) {
|
||||
LocalVar lv = varBuffer[i];
|
||||
if (lv == null || lv.sym == null
|
||||
|| lv.sym.annotations.isTypesEmpty()
|
||||
|| !lv.sym.isExceptionParameter())
|
||||
return;
|
||||
|
||||
int exidx = findExceptionIndex(lv);
|
||||
|
||||
for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
|
||||
TypeAnnotationPosition p = ta.position;
|
||||
p.exception_index = exidx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int findExceptionIndex(LocalVar lv) {
|
||||
List<char[]> iter = catchInfo.toList();
|
||||
int len = catchInfo.length();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
char[] catchEntry = iter.head;
|
||||
iter = iter.tail;
|
||||
char handlerpc = catchEntry[2];
|
||||
if (lv.start_pc == handlerpc + 1) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Put a live variable range into the buffer to be output to the
|
||||
* class file.
|
||||
*/
|
||||
void putVar(LocalVar var) {
|
||||
if (!varDebugInfo) return;
|
||||
// Keep local variables if
|
||||
// 1) we need them for debug information
|
||||
// 2) it is an exception type and it contains type annotations
|
||||
if (!varDebugInfo &&
|
||||
(!var.sym.isExceptionParameter() ||
|
||||
var.sym.annotations.isTypesEmpty())) return;
|
||||
if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
|
||||
if (varBuffer == null)
|
||||
varBuffer = new LocalVar[20];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1016,8 +1016,11 @@ public class Gen extends JCTree.Visitor {
|
||||
code.frameBeforeLast = null;
|
||||
}
|
||||
|
||||
//compress exception table
|
||||
// Compress exception table
|
||||
code.compressCatchTable();
|
||||
|
||||
// Fill in type annotation positions for exception parameters
|
||||
code.fillExceptionParameterPositions();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1738,6 +1741,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
|
||||
@ -1775,10 +1779,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.getRawTypeAttributes()) {
|
||||
if (ta.position.pos == treePos) {
|
||||
ta.position.offset = code.cp;
|
||||
ta.position.lvarOffset = new int[] { code.cp };
|
||||
ta.position.isValidOffset = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR
|
||||
&& code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT)
|
||||
return;
|
||||
|
||||
for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
|
||||
if (ta.position.pos == treePos) {
|
||||
ta.position.offset = code.cp;
|
||||
ta.position.lvarOffset = new int[] { 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.getRawTypeAttributes()) {
|
||||
if (ta.position.pos == treePos) {
|
||||
ta.position.offset = code.cp;
|
||||
ta.position.lvarOffset = new int[] { code.cp };
|
||||
ta.position.isValidOffset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visitNewClass(JCNewClass tree) {
|
||||
// Enclosing instances or anonymous classes should have been eliminated
|
||||
// by now.
|
||||
Assert.check(tree.encl == null && tree.def == null);
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
|
||||
code.emitop2(new_, makeRef(tree.pos(), tree.type));
|
||||
code.emitop0(dup);
|
||||
@ -1793,6 +1835,7 @@ public class Gen extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
setTypeAnnotationPositions(tree.pos);
|
||||
|
||||
if (tree.elems != null) {
|
||||
Type elemtype = types.elemtype(tree.type);
|
||||
@ -2122,6 +2165,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.
|
||||
@ -2138,6 +2182,7 @@ 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);
|
||||
@ -2184,7 +2229,7 @@ public class Gen extends JCTree.Visitor {
|
||||
code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type));
|
||||
result = items.makeStackItem(pt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Symbol ssym = TreeInfo.symbol(tree.selected);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -158,7 +158,7 @@ public class JNIWriter {
|
||||
return false;
|
||||
|
||||
/* temporary code for backwards compatibility */
|
||||
for (Attribute.Compound a: c.annotations.getAttributes()) {
|
||||
for (Attribute.Compound a: c.annotations.getDeclarationAttributes()) {
|
||||
if (a.type.tsym == syms.nativeHeaderType_old.tsym)
|
||||
return true;
|
||||
}
|
||||
@ -167,7 +167,7 @@ public class JNIWriter {
|
||||
for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
|
||||
if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0)
|
||||
return true;
|
||||
for (Attribute.Compound a: i.sym.annotations.getAttributes()) {
|
||||
for (Attribute.Compound a: i.sym.annotations.getDeclarationAttributes()) {
|
||||
if (a.type.tsym == syms.nativeHeaderType.tsym)
|
||||
return true;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -513,7 +513,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
*/
|
||||
public CompileState shouldStopPolicyIfNoError;
|
||||
|
||||
/** A queue of all as yet unattributed classes.oLo
|
||||
/** A queue of all as yet unattributed classes.
|
||||
*/
|
||||
public Todo todo;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,9 +25,9 @@
|
||||
|
||||
package com.sun.tools.javac.model;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -333,4 +333,28 @@ public class JavacTypes implements javax.lang.model.util.Types {
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public List<? extends AnnotationMirror> typeAnnotationsOf(TypeMirror type) {
|
||||
// TODO: these methods can be removed.
|
||||
return null; // ((Type)type).typeAnnotations;
|
||||
}
|
||||
|
||||
public <A extends Annotation> A typeAnnotationOf(TypeMirror type,
|
||||
Class<A> annotationType) {
|
||||
// TODO: these methods can be removed.
|
||||
return null; // JavacElements.getAnnotation(((Type)type).typeAnnotations, annotationType);
|
||||
}
|
||||
|
||||
public TypeMirror receiverTypeOf(ExecutableType type) {
|
||||
return ((Type)type).asMethodType().recvtype;
|
||||
}
|
||||
|
||||
/*
|
||||
public <A extends Annotation> A receiverTypeAnnotationOf(
|
||||
ExecutableType type, Class<A> annotationType) {
|
||||
return JavacElements.getAnnotation(
|
||||
((Type)type).asMethodType().receiverTypeAnnotations,
|
||||
annotationType);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -59,6 +59,7 @@ public class Scanner implements Lexer {
|
||||
private List<Token> savedTokens = new ArrayList<Token>();
|
||||
|
||||
private JavaTokenizer tokenizer;
|
||||
|
||||
/**
|
||||
* Create a scanner from the input array. This method might
|
||||
* modify the array. To avoid copying the input array, ensure
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,7 +38,7 @@ import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
|
||||
/** The char reader used by the javac lexer/tokenizer. Returns the sequence of
|
||||
* characters contained in the input stream, handling unicode escape accordingly.
|
||||
* Additionally, it provide features for saving chars into a buffer and to retrieve
|
||||
* Additionally, it provides features for saving chars into a buffer and to retrieve
|
||||
* them at a later stage.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -817,9 +817,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
/** The set of package-info files to be processed this round. */
|
||||
List<PackageSymbol> packageInfoFiles;
|
||||
|
||||
/** The number of Messager errors generated in this round. */
|
||||
int nMessagerErrors;
|
||||
|
||||
/** Create a round (common code). */
|
||||
private Round(Context context, int number, int priorErrors, int priorWarnings,
|
||||
Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
|
||||
@ -829,7 +826,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
compiler = JavaCompiler.instance(context);
|
||||
log = Log.instance(context);
|
||||
log.nerrors = priorErrors;
|
||||
log.nwarnings += priorWarnings;
|
||||
log.nwarnings = priorWarnings;
|
||||
if (number == 1) {
|
||||
Assert.checkNonNull(deferredDiagnosticHandler);
|
||||
this.deferredDiagnosticHandler = deferredDiagnosticHandler;
|
||||
@ -870,7 +867,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles) {
|
||||
this(prev.nextContext(),
|
||||
prev.number+1,
|
||||
prev.nMessagerErrors,
|
||||
prev.compiler.log.nerrors,
|
||||
prev.compiler.log.nwarnings,
|
||||
null);
|
||||
this.genClassFiles = prev.genClassFiles;
|
||||
@ -911,15 +908,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
|
||||
/** Create the compiler to be used for the final compilation. */
|
||||
JavaCompiler finalCompiler(boolean errorStatus) {
|
||||
JavaCompiler finalCompiler() {
|
||||
try {
|
||||
Context nextCtx = nextContext();
|
||||
JavacProcessingEnvironment.this.context = nextCtx;
|
||||
JavaCompiler c = JavaCompiler.instance(nextCtx);
|
||||
c.log.nwarnings += compiler.log.nwarnings;
|
||||
if (errorStatus) {
|
||||
c.log.nerrors += compiler.log.nerrors;
|
||||
}
|
||||
c.log.initRound(compiler.log);
|
||||
return c;
|
||||
} finally {
|
||||
compiler.close(false);
|
||||
@ -1027,8 +1021,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
if (!taskListener.isEmpty())
|
||||
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
|
||||
}
|
||||
|
||||
nMessagerErrors = messager.errorCount();
|
||||
}
|
||||
|
||||
void showDiagnostics(boolean showAll) {
|
||||
@ -1107,9 +1099,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
next.put(Tokens.tokensKey, tokens);
|
||||
|
||||
Log nextLog = Log.instance(next);
|
||||
// propogate the log's writers directly, instead of going through context
|
||||
nextLog.setWriters(log);
|
||||
nextLog.setSourceMap(log);
|
||||
nextLog.initRound(log);
|
||||
|
||||
JavaCompiler oldCompiler = JavaCompiler.instance(context);
|
||||
JavaCompiler nextCompiler = JavaCompiler.instance(next);
|
||||
@ -1206,7 +1196,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
new LinkedHashSet<JavaFileObject>(filer.getGeneratedSourceFileObjects());
|
||||
roots = cleanTrees(round.roots);
|
||||
|
||||
JavaCompiler compiler = round.finalCompiler(errorStatus);
|
||||
JavaCompiler compiler = round.finalCompiler();
|
||||
|
||||
if (newSourceFiles.size() > 0)
|
||||
roots = roots.appendList(compiler.parseFiles(newSourceFiles));
|
||||
@ -1311,7 +1301,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
if (procNames != null)
|
||||
return true;
|
||||
|
||||
String procPath;
|
||||
URL[] urls = new URL[1];
|
||||
for(File pathElement : workingpath) {
|
||||
try {
|
||||
@ -1382,6 +1371,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
node.sym = null;
|
||||
super.visitIdent(node);
|
||||
}
|
||||
public void visitAnnotation(JCAnnotation node) {
|
||||
node.attribute = null;
|
||||
super.visitAnnotation(node);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1666,6 +1666,9 @@ compiler.misc.bad.const.pool.tag.at=\
|
||||
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}
|
||||
|
||||
@ -2149,6 +2152,23 @@ compiler.err.assert.as.identifier=\
|
||||
as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\
|
||||
(use -source 1.3 or lower to use ''assert'' as an identifier)
|
||||
|
||||
# TODO 308: make a better error message
|
||||
compiler.err.this.as.identifier=\
|
||||
as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
|
||||
|
||||
# TODO 308: make a better error message
|
||||
compiler.err.cant.annotate.static.class=\
|
||||
enclosing static nested class cannot be annotated
|
||||
# TODO 308: make a better error message
|
||||
compiler.err.cant.annotate.nested.type=\
|
||||
nested type cannot be annotated
|
||||
|
||||
compiler.err.incorrect.receiver.type=\
|
||||
the receiver type does not match the enclosing class type
|
||||
|
||||
compiler.err.no.annotations.on.dot.class=\
|
||||
no annotations are allowed in the type of a class literal
|
||||
|
||||
# 0: string
|
||||
compiler.err.generics.not.supported.in.source=\
|
||||
generics are not supported in -source {0}\n\
|
||||
@ -2164,9 +2184,10 @@ compiler.err.annotations.not.supported.in.source=\
|
||||
annotations are not supported in -source {0}\n\
|
||||
(use -source 5 or higher to enable annotations)
|
||||
|
||||
#308 compiler.err.type.annotations.not.supported.in.source=\
|
||||
#308 type annotations are not supported in -source {0}\n\
|
||||
#308 (use -source 7 or higher to enable type annotations)
|
||||
# 0: string
|
||||
compiler.err.type.annotations.not.supported.in.source=\
|
||||
type annotations are not supported in -source {0}\n\
|
||||
(use -source 8 or higher to enable type annotations)
|
||||
|
||||
# 0: string
|
||||
compiler.err.foreach.not.supported.in.source=\
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -1340,6 +1340,10 @@ compiler.err.enum.as.identifier=\u30EA\u30EA\u30FC\u30B95\u304B\u3089''enum''\u3
|
||||
|
||||
compiler.err.assert.as.identifier=\u30EA\u30EA\u30FC\u30B91.4\u304B\u3089''assert''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u3001\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''assert''\u3092\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001-source 1.3\u4EE5\u524D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044)
|
||||
|
||||
# TODO 308: make a better error message
|
||||
# compiler.err.this.as.identifier=\
|
||||
# as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
|
||||
|
||||
# 0: string
|
||||
compiler.err.generics.not.supported.in.source=\u7DCF\u79F0\u578B\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(\u7DCF\u79F0\u578B\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 5\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044)
|
||||
|
||||
@ -1351,7 +1355,7 @@ compiler.err.annotations.not.supported.in.source=\u6CE8\u91C8\u306F-source {0}\u
|
||||
|
||||
#308 compiler.err.type.annotations.not.supported.in.source=\
|
||||
#308 type annotations are not supported in -source {0}\n\
|
||||
#308 (use -source 7 or higher to enable type annotations)
|
||||
#308 (use -source 8 or higher to enable type annotations)
|
||||
|
||||
# 0: string
|
||||
compiler.err.foreach.not.supported.in.source=for-each\u30EB\u30FC\u30D7\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(for-each\u30EB\u30FC\u30D7\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 5\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -1340,6 +1340,10 @@ compiler.err.enum.as.identifier=\u4ECE\u53D1\u884C\u7248 5 \u5F00\u59CB, ''enum'
|
||||
|
||||
compiler.err.assert.as.identifier=\u4ECE\u53D1\u884C\u7248 1.4 \u5F00\u59CB, ''assert'' \u662F\u4E00\u4E2A\u5173\u952E\u5B57, \u4F46\u4E0D\u80FD\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.3 \u6216\u66F4\u4F4E\u7248\u672C\u4EE5\u5C06 ''assert'' \u7528\u4F5C\u6807\u8BC6\u7B26)
|
||||
|
||||
# TODO 308: make a better error message
|
||||
# compiler.err.this.as.identifier=\
|
||||
# as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
|
||||
|
||||
# 0: string
|
||||
compiler.err.generics.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301\u6CDB\u578B\n(\u8BF7\u4F7F\u7528 -source 5 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528\u6CDB\u578B)
|
||||
|
||||
@ -1351,7 +1355,7 @@ compiler.err.annotations.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\
|
||||
|
||||
#308 compiler.err.type.annotations.not.supported.in.source=\
|
||||
#308 type annotations are not supported in -source {0}\n\
|
||||
#308 (use -source 7 or higher to enable type annotations)
|
||||
#308 (use -source 8 or higher to enable type annotations)
|
||||
|
||||
# 0: string
|
||||
compiler.err.foreach.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301 for-each \u5FAA\u73AF\n(\u8BF7\u4F7F\u7528 -source 5 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528 for-each \u5FAA\u73AF)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -250,11 +250,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
*/
|
||||
TYPEAPPLY,
|
||||
|
||||
/** Union types, of type TypeUnion
|
||||
/** Union types, of type TypeUnion.
|
||||
*/
|
||||
TYPEUNION,
|
||||
|
||||
/** Intersection types, of type TypeIntersection
|
||||
/** Intersection types, of type TypeIntersection.
|
||||
*/
|
||||
TYPEINTERSECTION,
|
||||
|
||||
@ -274,10 +274,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
*/
|
||||
ANNOTATION,
|
||||
|
||||
/** metadata: Type annotation.
|
||||
*/
|
||||
TYPE_ANNOTATION,
|
||||
|
||||
/** metadata: Modifiers
|
||||
*/
|
||||
MODIFIERS,
|
||||
|
||||
/** An annotated type tree.
|
||||
*/
|
||||
ANNOTATED_TYPE,
|
||||
|
||||
/** Error trees, of type Erroneous.
|
||||
@ -725,6 +731,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public JCExpression restype;
|
||||
/** type parameters */
|
||||
public List<JCTypeParameter> typarams;
|
||||
/** receiver parameter */
|
||||
public JCVariableDecl recvparam;
|
||||
/** value parameters */
|
||||
public List<JCVariableDecl> params;
|
||||
/** exceptions thrown by this method */
|
||||
@ -739,6 +747,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
Name name,
|
||||
JCExpression restype,
|
||||
List<JCTypeParameter> typarams,
|
||||
JCVariableDecl recvparam,
|
||||
List<JCVariableDecl> params,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
@ -750,6 +759,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
this.restype = restype;
|
||||
this.typarams = typarams;
|
||||
this.params = params;
|
||||
this.recvparam = recvparam;
|
||||
// TODO: do something special if the given type is null?
|
||||
// receiver != null ? receiver : List.<JCTypeAnnotation>nil());
|
||||
this.thrown = thrown;
|
||||
this.body = body;
|
||||
this.defaultValue = defaultValue;
|
||||
@ -768,6 +780,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public List<JCVariableDecl> getParameters() {
|
||||
return params;
|
||||
}
|
||||
public JCVariableDecl getReceiverParameter() { return recvparam; }
|
||||
public List<JCExpression> getThrows() {
|
||||
return thrown;
|
||||
}
|
||||
@ -1505,6 +1518,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public static class JCNewArray extends JCExpression implements NewArrayTree {
|
||||
public JCExpression elemtype;
|
||||
public List<JCExpression> dims;
|
||||
// type annotations on inner-most component
|
||||
public List<JCAnnotation> annotations;
|
||||
// type annotations on dimensions
|
||||
public List<List<JCAnnotation>> dimAnnotations;
|
||||
public List<JCExpression> elems;
|
||||
protected JCNewArray(JCExpression elemtype,
|
||||
List<JCExpression> dims,
|
||||
@ -1512,6 +1529,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
|
||||
@ -2152,9 +2171,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public Name name;
|
||||
/** bounds */
|
||||
public List<JCExpression> bounds;
|
||||
protected JCTypeParameter(Name name, List<JCExpression> bounds) {
|
||||
/** type annotations on type parameter */
|
||||
public List<JCAnnotation> annotations;
|
||||
protected JCTypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annotations) {
|
||||
this.name = name;
|
||||
this.bounds = bounds;
|
||||
this.annotations = annotations;
|
||||
}
|
||||
@Override
|
||||
public void accept(Visitor v) { v.visitTypeParameter(this); }
|
||||
@ -2164,6 +2186,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public List<JCExpression> getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
public List<JCAnnotation> getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
@Override
|
||||
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
||||
return v.visitTypeParameter(this, d);
|
||||
@ -2230,16 +2255,27 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
}
|
||||
|
||||
public static class JCAnnotation extends JCExpression implements AnnotationTree {
|
||||
// Either Tag.ANNOTATION or Tag.TYPE_ANNOTATION
|
||||
private Tag tag;
|
||||
|
||||
public JCTree annotationType;
|
||||
public List<JCExpression> args;
|
||||
protected JCAnnotation(JCTree annotationType, List<JCExpression> args) {
|
||||
|
||||
// Attribute.Compound if tag is ANNOTATION
|
||||
// Attribute.TypeCompound if tag is TYPE_ANNOTATION
|
||||
public Attribute.Compound attribute;
|
||||
|
||||
protected JCAnnotation(Tag tag, JCTree annotationType, List<JCExpression> args) {
|
||||
this.tag = tag;
|
||||
this.annotationType = annotationType;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor v) { v.visitAnnotation(this); }
|
||||
|
||||
public Kind getKind() { return Kind.ANNOTATION; }
|
||||
public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
|
||||
|
||||
public JCTree getAnnotationType() { return annotationType; }
|
||||
public List<JCExpression> getArguments() {
|
||||
return args;
|
||||
@ -2250,7 +2286,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
}
|
||||
@Override
|
||||
public Tag getTag() {
|
||||
return ANNOTATION;
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2281,6 +2317,35 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
}
|
||||
}
|
||||
|
||||
public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree {
|
||||
// type annotations
|
||||
public List<JCAnnotation> annotations;
|
||||
public JCExpression underlyingType;
|
||||
|
||||
protected JCAnnotatedType(List<JCAnnotation> 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<JCAnnotation> 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 Tag getTag() {
|
||||
return ANNOTATED_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JCErroneous extends JCExpression
|
||||
implements com.sun.source.tree.ErroneousTree {
|
||||
public List<? extends JCTree> errs;
|
||||
@ -2347,6 +2412,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
Name name,
|
||||
JCExpression restype,
|
||||
List<JCTypeParameter> typarams,
|
||||
JCVariableDecl recvparam,
|
||||
List<JCVariableDecl> params,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
@ -2472,6 +2538,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); }
|
||||
|
||||
|
@ -29,7 +29,6 @@ import java.io.*;
|
||||
|
||||
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
@ -261,6 +260,15 @@ public class Pretty extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
public void printTypeAnnotations(List<JCAnnotation> trees) throws IOException {
|
||||
if (trees.nonEmpty())
|
||||
print(" ");
|
||||
for (List<JCAnnotation> 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.
|
||||
*/
|
||||
@ -491,6 +499,12 @@ public class Pretty extends JCTree.Visitor {
|
||||
print(" " + tree.name);
|
||||
}
|
||||
print("(");
|
||||
if (tree.recvparam!=null) {
|
||||
printExpr(tree.recvparam);
|
||||
if (tree.params.size() > 0) {
|
||||
print(", ");
|
||||
}
|
||||
}
|
||||
printExprs(tree.params);
|
||||
print(")");
|
||||
if (tree.thrown.nonEmpty()) {
|
||||
@ -543,7 +557,15 @@ public class Pretty extends JCTree.Visitor {
|
||||
} else {
|
||||
printExpr(tree.mods);
|
||||
if ((tree.mods.flags & VARARGS) != 0) {
|
||||
printExpr(((JCArrayTypeTree) tree.vartype).elemtype);
|
||||
JCTree vartype = tree.vartype;
|
||||
List<JCAnnotation> tas = null;
|
||||
if (vartype instanceof JCAnnotatedType) {
|
||||
tas = ((JCAnnotatedType)vartype).annotations;
|
||||
vartype = ((JCAnnotatedType)vartype).underlyingType;
|
||||
}
|
||||
printExpr(((JCArrayTypeTree) vartype).elemtype);
|
||||
if (tas != null)
|
||||
printTypeAnnotations(tas);
|
||||
print("... " + tree.name);
|
||||
} else {
|
||||
printExpr(tree.vartype);
|
||||
@ -919,16 +941,29 @@ public class Pretty extends JCTree.Visitor {
|
||||
try {
|
||||
if (tree.elemtype != null) {
|
||||
print("new ");
|
||||
printTypeAnnotations(tree.annotations);
|
||||
JCTree elem = tree.elemtype;
|
||||
if (elem.hasTag(TYPEARRAY))
|
||||
printBaseElementType((JCArrayTypeTree) elem);
|
||||
else
|
||||
printExpr(elem);
|
||||
printBaseElementType(elem);
|
||||
boolean isElemAnnoType = elem instanceof JCAnnotatedType;
|
||||
int i = 0;
|
||||
List<List<JCAnnotation>> 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);
|
||||
}
|
||||
@ -1225,6 +1260,12 @@ public class Pretty extends JCTree.Visitor {
|
||||
JCTree elem;
|
||||
while (true) {
|
||||
elem = tree.elemtype;
|
||||
if (elem.hasTag(ANNOTATED_TYPE)) {
|
||||
JCAnnotatedType atype = (JCAnnotatedType) elem;
|
||||
elem = atype.underlyingType;
|
||||
if (!elem.hasTag(TYPEARRAY)) break;
|
||||
printTypeAnnotations(atype.annotations);
|
||||
}
|
||||
print("[]");
|
||||
if (!elem.hasTag(TYPEARRAY)) break;
|
||||
tree = (JCArrayTypeTree) elem;
|
||||
@ -1327,6 +1368,32 @@ public class Pretty extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
try {
|
||||
if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) {
|
||||
JCFieldAccess access = (JCFieldAccess) tree.underlyingType;
|
||||
printExpr(access.selected, TreeInfo.postfixPrec);
|
||||
print(".");
|
||||
printTypeAnnotations(tree.annotations);
|
||||
print(access.name);
|
||||
} else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
|
||||
JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
|
||||
printBaseElementType(tree);
|
||||
printTypeAnnotations(tree.annotations);
|
||||
print("[]");
|
||||
JCExpression elem = array.elemtype;
|
||||
if (elem.hasTag(TYPEARRAY)) {
|
||||
printBrackets((JCArrayTypeTree) elem);
|
||||
}
|
||||
} else {
|
||||
printTypeAnnotations(tree.annotations);
|
||||
printExpr(tree.underlyingType);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitTree(JCTree tree) {
|
||||
try {
|
||||
print("(UNKNOWN: " + tree + ")");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -71,11 +71,26 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
||||
return lb.toList();
|
||||
}
|
||||
|
||||
public JCTree visitAnnotatedType(AnnotatedTypeTree node, P p) {
|
||||
JCAnnotatedType t = (JCAnnotatedType) node;
|
||||
List<JCAnnotation> 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);
|
||||
List<JCExpression> args = copy(t.args, p);
|
||||
return M.at(t.pos).Annotation(annotationType, args);
|
||||
if (t.getKind() == Tree.Kind.TYPE_ANNOTATION) {
|
||||
JCAnnotation newTA = M.at(t.pos).TypeAnnotation(annotationType, args);
|
||||
newTA.attribute = t.attribute;
|
||||
return newTA;
|
||||
} else {
|
||||
JCAnnotation newT = M.at(t.pos).Annotation(annotationType, args);
|
||||
newT.attribute = t.attribute;
|
||||
return newT;
|
||||
}
|
||||
}
|
||||
|
||||
public JCTree visitAssert(AssertTree node, P p) {
|
||||
@ -233,10 +248,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);
|
||||
JCVariableDecl recvparam = copy(t.recvparam, 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, recvparam, params, thrown, body, defaultValue);
|
||||
}
|
||||
|
||||
public JCTree visitMethodInvocation(MethodInvocationTree node, P p) {
|
||||
@ -384,8 +400,9 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
||||
|
||||
public JCTree visitTypeParameter(TypeParameterTree node, P p) {
|
||||
JCTypeParameter t = (JCTypeParameter) node;
|
||||
List<JCAnnotation> annos = copy(t.annotations, p);
|
||||
List<JCExpression> bounds = copy(t.bounds, p);
|
||||
return M.at(t.pos).TypeParameter(t.name, bounds);
|
||||
return M.at(t.pos).TypeParameter(t.name, bounds, annos);
|
||||
}
|
||||
|
||||
public JCTree visitInstanceOf(InstanceOfTree node, P p) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -453,6 +453,19 @@ public class TreeInfo {
|
||||
case POSTINC:
|
||||
case POSTDEC:
|
||||
return getStartPos(((JCUnary) tree).arg);
|
||||
case ANNOTATED_TYPE: {
|
||||
JCAnnotatedType node = (JCAnnotatedType) tree;
|
||||
if (node.annotations.nonEmpty()) {
|
||||
if (node.underlyingType.hasTag(TYPEARRAY) ||
|
||||
node.underlyingType.hasTag(SELECT)) {
|
||||
return getStartPos(node.underlyingType);
|
||||
} else {
|
||||
return getStartPos(node.annotations.head);
|
||||
}
|
||||
} else {
|
||||
return getStartPos(node.underlyingType);
|
||||
}
|
||||
}
|
||||
case NEWCLASS: {
|
||||
JCNewClass node = (JCNewClass)tree;
|
||||
if (node.encl != null)
|
||||
@ -560,6 +573,8 @@ public class TreeInfo {
|
||||
return getEndPos(((JCUnary) tree).arg, endPosTable);
|
||||
case WHILELOOP:
|
||||
return getEndPos(((JCWhileLoop) tree).body, endPosTable);
|
||||
case ANNOTATED_TYPE:
|
||||
return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable);
|
||||
case ERRONEOUS: {
|
||||
JCErroneous node = (JCErroneous)tree;
|
||||
if (node.errs != null && node.errs.nonEmpty())
|
||||
@ -799,6 +814,8 @@ public class TreeInfo {
|
||||
return ((JCFieldAccess) tree).sym;
|
||||
case TYPEAPPLY:
|
||||
return symbol(((JCTypeApply) tree).clazz);
|
||||
case ANNOTATED_TYPE:
|
||||
return symbol(((JCAnnotatedType) tree).underlyingType);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -1036,17 +1053,24 @@ public class TreeInfo {
|
||||
case NULLCHK:
|
||||
return Tree.Kind.OTHER;
|
||||
|
||||
case ANNOTATION:
|
||||
return Tree.Kind.ANNOTATION;
|
||||
case TYPE_ANNOTATION:
|
||||
return Tree.Kind.TYPE_ANNOTATION;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying type of the tree if it is annotated type,
|
||||
* or the tree itself otherwise
|
||||
* Returns the underlying type of the tree if it is an annotated type,
|
||||
* or the tree itself otherwise.
|
||||
*/
|
||||
public static JCExpression typeIn(JCExpression tree) {
|
||||
switch (tree.getTag()) {
|
||||
case ANNOTATED_TYPE:
|
||||
return ((JCAnnotatedType)tree).underlyingType;
|
||||
case IDENT: /* simple names */
|
||||
case TYPEIDENT: /* primitive name */
|
||||
case SELECT: /* qualified name */
|
||||
@ -1054,20 +1078,55 @@ public class TreeInfo {
|
||||
case WILDCARD: /* wild cards */
|
||||
case TYPEPARAMETER: /* type parameters */
|
||||
case TYPEAPPLY: /* parameterized types */
|
||||
case ERRONEOUS: /* error tree TODO: needed for BadCast JSR308 test case. Better way? */
|
||||
return tree;
|
||||
default:
|
||||
throw new AssertionError("Unexpected type tree: " + tree);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the inner-most type of a type tree.
|
||||
* For an array that contains an annotated type, return that annotated type.
|
||||
* TODO: currently only used by Pretty. Describe behavior better.
|
||||
*/
|
||||
public static JCTree innermostType(JCTree type) {
|
||||
switch (type.getTag()) {
|
||||
case TYPEARRAY:
|
||||
return innermostType(((JCArrayTypeTree)type).elemtype);
|
||||
case WILDCARD:
|
||||
return innermostType(((JCWildcard)type).inner);
|
||||
default:
|
||||
return type;
|
||||
JCTree lastAnnotatedType = null;
|
||||
JCTree cur = type;
|
||||
loop: while (true) {
|
||||
switch (cur.getTag()) {
|
||||
case TYPEARRAY:
|
||||
lastAnnotatedType = null;
|
||||
cur = ((JCArrayTypeTree)cur).elemtype;
|
||||
break;
|
||||
case WILDCARD:
|
||||
lastAnnotatedType = null;
|
||||
cur = ((JCWildcard)cur).inner;
|
||||
break;
|
||||
case ANNOTATED_TYPE:
|
||||
lastAnnotatedType = cur;
|
||||
cur = ((JCAnnotatedType)cur).underlyingType;
|
||||
break;
|
||||
default:
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
if (lastAnnotatedType!=null) {
|
||||
return lastAnnotatedType;
|
||||
} else {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TypeAnnotationFinder extends TreeScanner {
|
||||
public boolean foundTypeAnno = false;
|
||||
public void visitAnnotation(JCAnnotation tree) {
|
||||
foundTypeAnno = foundTypeAnno || tree.hasTag(TYPE_ANNOTATION);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean containsTypeAnnotation(JCTree e) {
|
||||
TypeAnnotationFinder finder = new TypeAnnotationFinder();
|
||||
finder.scan(e);
|
||||
return finder.foundTypeAnno;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -169,10 +169,26 @@ public class TreeMaker implements JCTree.Factory {
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
JCExpression defaultValue) {
|
||||
return MethodDef(
|
||||
mods, name, restype, typarams, null, params,
|
||||
thrown, body, defaultValue);
|
||||
}
|
||||
|
||||
public JCMethodDecl MethodDef(JCModifiers mods,
|
||||
Name name,
|
||||
JCExpression restype,
|
||||
List<JCTypeParameter> typarams,
|
||||
JCVariableDecl recvparam,
|
||||
List<JCVariableDecl> params,
|
||||
List<JCExpression> thrown,
|
||||
JCBlock body,
|
||||
JCExpression defaultValue)
|
||||
{
|
||||
JCMethodDecl tree = new JCMethodDecl(mods,
|
||||
name,
|
||||
restype,
|
||||
typarams,
|
||||
recvparam,
|
||||
params,
|
||||
thrown,
|
||||
body,
|
||||
@ -463,7 +479,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.<JCAnnotation>nil());
|
||||
}
|
||||
|
||||
public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) {
|
||||
JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
@ -481,7 +501,13 @@ public class TreeMaker implements JCTree.Factory {
|
||||
}
|
||||
|
||||
public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
|
||||
JCAnnotation tree = new JCAnnotation(annotationType, args);
|
||||
JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
|
||||
public JCAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
|
||||
JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
@ -497,6 +523,12 @@ public class TreeMaker implements JCTree.Factory {
|
||||
return Modifiers(flags, List.<JCAnnotation>nil());
|
||||
}
|
||||
|
||||
public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
|
||||
JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
|
||||
tree.pos = pos;
|
||||
return tree;
|
||||
}
|
||||
|
||||
public JCErroneous Erroneous() {
|
||||
return Erroneous(List.<JCTree>nil());
|
||||
}
|
||||
@ -755,7 +787,11 @@ public class TreeMaker implements JCTree.Factory {
|
||||
result = Erroneous();
|
||||
}
|
||||
public void visitCompound(Attribute.Compound compound) {
|
||||
result = visitCompoundInternal(compound);
|
||||
if (compound instanceof Attribute.TypeCompound) {
|
||||
result = visitTypeCompoundInternal((Attribute.TypeCompound) compound);
|
||||
} else {
|
||||
result = visitCompoundInternal(compound);
|
||||
}
|
||||
}
|
||||
public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
|
||||
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
|
||||
@ -766,6 +802,15 @@ public class TreeMaker implements JCTree.Factory {
|
||||
}
|
||||
return Annotation(Type(compound.type), args.toList());
|
||||
}
|
||||
public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) {
|
||||
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
|
||||
for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
|
||||
Pair<MethodSymbol,Attribute> pair = values.head;
|
||||
JCExpression valueTree = translate(pair.snd);
|
||||
args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
|
||||
}
|
||||
return TypeAnnotation(Type(compound.type), args.toList());
|
||||
}
|
||||
public void visitArray(Attribute.Array array) {
|
||||
ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
|
||||
for (int i = 0; i < array.values.length; i++)
|
||||
@ -779,7 +824,11 @@ public class TreeMaker implements JCTree.Factory {
|
||||
JCAnnotation translate(Attribute.Compound a) {
|
||||
return visitCompoundInternal(a);
|
||||
}
|
||||
JCAnnotation translate(Attribute.TypeCompound a) {
|
||||
return visitTypeCompoundInternal(a);
|
||||
}
|
||||
}
|
||||
|
||||
AnnotationBuilder annotationBuilder = new AnnotationBuilder();
|
||||
|
||||
/** Create an annotation tree from an attribute.
|
||||
@ -788,6 +837,10 @@ public class TreeMaker implements JCTree.Factory {
|
||||
return annotationBuilder.translate((Attribute.Compound)a);
|
||||
}
|
||||
|
||||
public JCAnnotation TypeAnnotation(Attribute a) {
|
||||
return annotationBuilder.translate((Attribute.TypeCompound) a);
|
||||
}
|
||||
|
||||
/** Create a method definition from a method symbol and a method body.
|
||||
*/
|
||||
public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
|
||||
@ -804,6 +857,7 @@ public class TreeMaker implements JCTree.Factory {
|
||||
m.name,
|
||||
Type(mtype.getReturnType()),
|
||||
TypeParams(mtype.getTypeArguments()),
|
||||
null, // receiver type
|
||||
Params(mtype.getParameterTypes(), m),
|
||||
Types(mtype.getThrownTypes()),
|
||||
body,
|
||||
@ -822,7 +876,6 @@ public class TreeMaker implements JCTree.Factory {
|
||||
*/
|
||||
public List<JCTypeParameter> TypeParams(List<Type> typarams) {
|
||||
ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
|
||||
int i = 0;
|
||||
for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
|
||||
tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
|
||||
return tparams.toList();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -84,6 +84,7 @@ public class TreeScanner extends Visitor {
|
||||
scan(tree.mods);
|
||||
scan(tree.restype);
|
||||
scan(tree.typarams);
|
||||
scan(tree.recvparam);
|
||||
scan(tree.params);
|
||||
scan(tree.thrown);
|
||||
scan(tree.defaultValue);
|
||||
@ -200,15 +201,18 @@ public class TreeScanner extends Visitor {
|
||||
|
||||
public void visitNewClass(JCNewClass tree) {
|
||||
scan(tree.encl);
|
||||
scan(tree.clazz);
|
||||
scan(tree.typeargs);
|
||||
scan(tree.clazz);
|
||||
scan(tree.args);
|
||||
scan(tree.def);
|
||||
}
|
||||
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
scan(tree.annotations);
|
||||
scan(tree.elemtype);
|
||||
scan(tree.dims);
|
||||
for (List<JCAnnotation> annos : tree.dimAnnotations)
|
||||
scan(annos);
|
||||
scan(tree.elems);
|
||||
}
|
||||
|
||||
@ -291,6 +295,7 @@ public class TreeScanner extends Visitor {
|
||||
}
|
||||
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
scan(tree.annotations);
|
||||
scan(tree.bounds);
|
||||
}
|
||||
|
||||
@ -314,6 +319,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) {
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -139,6 +139,7 @@ public class TreeTranslator extends JCTree.Visitor {
|
||||
tree.mods = translate(tree.mods);
|
||||
tree.restype = translate(tree.restype);
|
||||
tree.typarams = translateTypeParams(tree.typarams);
|
||||
tree.recvparam = translate(tree.recvparam);
|
||||
tree.params = translateVarDefs(tree.params);
|
||||
tree.thrown = translate(tree.thrown);
|
||||
tree.body = translate(tree.body);
|
||||
@ -289,6 +290,11 @@ public class TreeTranslator extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
tree.annotations = translate(tree.annotations);
|
||||
List<List<JCAnnotation>> dimAnnos = List.nil();
|
||||
for (List<JCAnnotation> 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);
|
||||
@ -385,6 +391,7 @@ public class TreeTranslator extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
tree.annotations = translate(tree.annotations);
|
||||
tree.bounds = translate(tree.bounds);
|
||||
result = tree;
|
||||
}
|
||||
@ -422,6 +429,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);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -388,7 +388,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
this.source = source;
|
||||
this.position = pos;
|
||||
this.key = key;
|
||||
this.args = args;
|
||||
this.args = args;
|
||||
|
||||
int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition());
|
||||
if (n == Position.NOPOS || source == null)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -217,7 +217,7 @@ public class Log extends AbstractLog {
|
||||
private JavacMessages messages;
|
||||
|
||||
/**
|
||||
+ * Handler for initial dispatch of diagnostics.
|
||||
* Handler for initial dispatch of diagnostics.
|
||||
*/
|
||||
private DiagnosticHandler diagnosticHandler;
|
||||
|
||||
@ -385,14 +385,17 @@ public class Log extends AbstractLog {
|
||||
noticeWriter = warnWriter = errWriter = pw;
|
||||
}
|
||||
|
||||
public void setWriters(Log other) {
|
||||
/**
|
||||
* Propagate the previous log's information.
|
||||
*/
|
||||
public void initRound(Log other) {
|
||||
this.noticeWriter = other.noticeWriter;
|
||||
this.warnWriter = other.warnWriter;
|
||||
this.errWriter = other.errWriter;
|
||||
}
|
||||
|
||||
public void setSourceMap(Log other) {
|
||||
this.sourceMap = other.sourceMap;
|
||||
this.recorded = other.recorded;
|
||||
this.nerrors = other.nerrors;
|
||||
this.nwarnings = other.nwarnings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -104,4 +104,8 @@ abstract class AbstractTypeImpl implements com.sun.javadoc.Type {
|
||||
public AnnotationTypeDoc asAnnotationTypeDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AnnotatedType asAnnotatedType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javadoc;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
/**
|
||||
* Implementation of <code>AnnotatedType</code>, which
|
||||
* represents an annotated type.
|
||||
*
|
||||
* @author Mahmood Ali
|
||||
* @since 1.8
|
||||
*/
|
||||
public class AnnotatedTypeImpl
|
||||
extends AbstractTypeImpl implements AnnotatedType {
|
||||
|
||||
AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type.AnnotatedType type) {
|
||||
super(env, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the annotations of this program element.
|
||||
* Return an empty array if there are none.
|
||||
*/
|
||||
@Override
|
||||
public AnnotationDesc[] annotations() {
|
||||
List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType)type).typeAnnotations;
|
||||
if (tas == null ||
|
||||
tas.isEmpty()) {
|
||||
return new AnnotationDesc[0];
|
||||
}
|
||||
AnnotationDesc res[] = new AnnotationDesc[tas.length()];
|
||||
int i = 0;
|
||||
for (Attribute.Compound a : tas) {
|
||||
res[i++] = new AnnotationDescImpl(env, a);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sun.javadoc.Type underlyingType() {
|
||||
return TypeMaker.getType(env, ((com.sun.tools.javac.code.Type.AnnotatedType)type).underlyingType, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedType asAnnotatedType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return typeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String typeName() {
|
||||
return this.underlyingType().typeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String qualifiedTypeName() {
|
||||
return this.underlyingType().qualifiedTypeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simpleTypeName() {
|
||||
return this.underlyingType().simpleTypeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dimension() {
|
||||
return this.underlyingType().dimension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrimitive() {
|
||||
return this.underlyingType().isPrimitive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDoc asClassDoc() {
|
||||
return this.underlyingType().asClassDoc();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeVariable asTypeVariable() {
|
||||
return this.underlyingType().asTypeVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WildcardType asWildcardType() {
|
||||
return this.underlyingType().asWildcardType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParameterizedType asParameterizedType() {
|
||||
return this.underlyingType().asParameterizedType();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1185,6 +1185,13 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null, as this is not an annotated type.
|
||||
*/
|
||||
public AnnotatedType asAnnotatedType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return false, as this is not a primitive type.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,10 +28,14 @@ package com.sun.tools.javadoc;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.text.CollationKey;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Attribute.Compound;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.util.List;
|
||||
@ -195,6 +199,24 @@ public abstract class ExecutableMemberDocImpl
|
||||
return result;
|
||||
}
|
||||
|
||||
public AnnotationDesc[] receiverAnnotations() {
|
||||
// TODO: change how receiver annotations are output!
|
||||
Type recvtype = sym.type.asMethodType().recvtype;
|
||||
if (recvtype == null) {
|
||||
return new AnnotationDesc[0];
|
||||
}
|
||||
if (recvtype.getKind() != TypeKind.ANNOTATED) {
|
||||
return new AnnotationDesc[0];
|
||||
}
|
||||
List<? extends Compound> typeAnnos = ((com.sun.tools.javac.code.Type.AnnotatedType)recvtype).typeAnnotations;
|
||||
AnnotationDesc result[] = new AnnotationDesc[typeAnnos.length()];
|
||||
int i = 0;
|
||||
for (Attribute.Compound a : typeAnnos) {
|
||||
result[i++] = new AnnotationDescImpl(env, a);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the formal type parameters of this method or constructor.
|
||||
* Return an empty array if there are none.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -121,12 +121,19 @@ class PrimitiveType implements com.sun.javadoc.Type {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return null, as this is not a wildcard type;
|
||||
* Return null, as this is not a wildcard type.
|
||||
*/
|
||||
public WildcardType asWildcardType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return null, as this is not an annotated type.
|
||||
*/
|
||||
public AnnotatedType asAnnotatedType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the type.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package com.sun.tools.javadoc;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
@ -51,12 +53,27 @@ public class TypeMaker {
|
||||
* @param errToClassDoc if true, ERROR type results in a ClassDoc;
|
||||
* false preserves legacy behavior
|
||||
*/
|
||||
public static com.sun.javadoc.Type getType(DocEnv env, Type t,
|
||||
boolean errorToClassDoc) {
|
||||
return getType(env, t, errorToClassDoc, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static com.sun.javadoc.Type getType(DocEnv env, Type t,
|
||||
boolean errToClassDoc) {
|
||||
boolean errToClassDoc, boolean considerAnnotations) {
|
||||
if (env.legacyDoclet) {
|
||||
t = env.types.erasure(t);
|
||||
}
|
||||
if (considerAnnotations
|
||||
&& t.getKind() == TypeKind.ANNOTATED) {
|
||||
return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t);
|
||||
}
|
||||
|
||||
if (t.getKind() == TypeKind.ANNOTATED) {
|
||||
Type.AnnotatedType at = (Type.AnnotatedType) t;
|
||||
return new AnnotatedTypeImpl(env, at);
|
||||
}
|
||||
|
||||
switch (t.getTag()) {
|
||||
case CLASS:
|
||||
if (ClassDocImpl.isGeneric((ClassSymbol)t.tsym)) {
|
||||
@ -129,6 +146,11 @@ public class TypeMaker {
|
||||
* Class names are qualified if "full" is true.
|
||||
*/
|
||||
static String getTypeString(DocEnv env, Type t, boolean full) {
|
||||
// TODO: should annotations be included here?
|
||||
if (t.getKind() == TypeKind.ANNOTATED) {
|
||||
Type.AnnotatedType at = (Type.AnnotatedType)t;
|
||||
t = at.underlyingType;
|
||||
}
|
||||
switch (t.getTag()) {
|
||||
case ARRAY:
|
||||
StringBuilder s = new StringBuilder();
|
||||
@ -281,6 +303,13 @@ public class TypeMaker {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return null, as there are no annotations of the type
|
||||
*/
|
||||
public AnnotatedType asAnnotatedType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this type as an <code>AnnotationTypeDoc</code> if it
|
||||
* represents an annotation type. Array dimensions are ignored.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,8 +25,12 @@
|
||||
|
||||
package com.sun.tools.javadoc;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
@ -120,11 +124,30 @@ public class TypeVariableImpl extends AbstractTypeImpl implements TypeVariable {
|
||||
* Get the bounds of a type variable as listed in the "extends" clause.
|
||||
*/
|
||||
private static List<Type> getBounds(TypeVar v, DocEnv env) {
|
||||
Name boundname = v.getUpperBound().tsym.getQualifiedName();
|
||||
if (boundname == boundname.table.names.java_lang_Object) {
|
||||
final Type upperBound = v.getUpperBound();
|
||||
Name boundname = upperBound.tsym.getQualifiedName();
|
||||
if (boundname == boundname.table.names.java_lang_Object
|
||||
&& upperBound.getKind() != TypeKind.ANNOTATED) {
|
||||
return List.nil();
|
||||
} else {
|
||||
return env.types.getBounds(v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the annotations of this program element.
|
||||
* Return an empty array if there are none.
|
||||
*/
|
||||
public AnnotationDesc[] annotations() {
|
||||
if (type.getKind() != TypeKind.ANNOTATED) {
|
||||
return new AnnotationDesc[0];
|
||||
}
|
||||
List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations;
|
||||
AnnotationDesc res[] = new AnnotationDesc[tas.length()];
|
||||
int i = 0;
|
||||
for (Attribute.Compound a : tas) {
|
||||
res[i++] = new AnnotationDescImpl(env, a);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,7 @@
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Annotation;
|
||||
import com.sun.tools.classfile.TypeAnnotation;
|
||||
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;
|
||||
@ -76,6 +77,124 @@ public class AnnotationWriter extends BasicWriter {
|
||||
print(")");
|
||||
}
|
||||
|
||||
public void write(TypeAnnotation annot) {
|
||||
write(annot, true, false);
|
||||
}
|
||||
|
||||
public void write(TypeAnnotation annot, boolean showOffsets, boolean resolveIndices) {
|
||||
write(annot.annotation, resolveIndices);
|
||||
print(": ");
|
||||
write(annot.position, showOffsets);
|
||||
}
|
||||
|
||||
public void write(TypeAnnotation.Position pos, boolean showOffsets) {
|
||||
print(pos.type);
|
||||
|
||||
switch (pos.type) {
|
||||
// type cast
|
||||
case CAST:
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
if (showOffsets) {
|
||||
print(", offset=");
|
||||
print(pos.offset);
|
||||
}
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
// resource variable
|
||||
case RESOURCE_VARIABLE:
|
||||
if (pos.lvarOffset == null) {
|
||||
print(", lvarOffset is Null!");
|
||||
break;
|
||||
}
|
||||
print(", {");
|
||||
for (int i = 0; i < pos.lvarOffset.length; ++i) {
|
||||
if (i != 0) print("; ");
|
||||
if (showOffsets) {
|
||||
print("start_pc=");
|
||||
print(pos.lvarOffset[i]);
|
||||
}
|
||||
print(", length=");
|
||||
print(pos.lvarLength[i]);
|
||||
print(", index=");
|
||||
print(pos.lvarIndex[i]);
|
||||
}
|
||||
print("}");
|
||||
break;
|
||||
// exception parameter
|
||||
case EXCEPTION_PARAMETER:
|
||||
print(", exception_index=");
|
||||
print(pos.exception_index);
|
||||
break;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameter
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
break;
|
||||
// type parameter bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
print(", bound_index=");
|
||||
print(pos.bound_index);
|
||||
break;
|
||||
// class extends or implements clause
|
||||
case CLASS_EXTENDS:
|
||||
print(", type_index=");
|
||||
print(pos.type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
print(", type_index=");
|
||||
print(pos.type_index);
|
||||
break;
|
||||
// method parameter
|
||||
case METHOD_FORMAL_PARAMETER:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
break;
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||
if (showOffsets) {
|
||||
print(", offset=");
|
||||
print(pos.offset);
|
||||
}
|
||||
print(", type_index=");
|
||||
print(pos.type_index);
|
||||
break;
|
||||
// We don't need to worry about these
|
||||
case METHOD_RETURN:
|
||||
case FIELD:
|
||||
break;
|
||||
// lambda formal parameter
|
||||
case LAMBDA_FORMAL_PARAMETER:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
|
||||
default:
|
||||
throw new AssertionError("AnnotationWriter: Unknown target type for position: " + pos);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (!pos.location.isEmpty()) {
|
||||
print(", location=");
|
||||
print(pos.location);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(Annotation.element_value_pair pair) {
|
||||
write(pair, false);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -49,8 +49,10 @@ import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
|
||||
import com.sun.tools.classfile.MethodParameters_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;
|
||||
@ -433,6 +435,30 @@ public class AttributeWriter extends BasicWriter
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
|
||||
println("RuntimeVisibleTypeAnnotations:");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
|
||||
println("RuntimeInvisibleTypeAnnotations:");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
|
||||
println("RuntimeVisibleParameterAnnotations:");
|
||||
indent(+1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,6 +64,7 @@ public class CodeWriter extends BasicWriter {
|
||||
stackMapWriter = StackMapWriter.instance(context);
|
||||
localVariableTableWriter = LocalVariableTableWriter.instance(context);
|
||||
localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context);
|
||||
typeAnnotationWriter = TypeAnnotationWriter.instance(context);
|
||||
options = Options.instance(context);
|
||||
}
|
||||
|
||||
@ -265,6 +266,11 @@ public class CodeWriter extends BasicWriter {
|
||||
detailWriters.add(tryBlockWriter);
|
||||
}
|
||||
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
|
||||
typeAnnotationWriter.reset(attr);
|
||||
detailWriters.add(typeAnnotationWriter);
|
||||
}
|
||||
|
||||
return detailWriters;
|
||||
}
|
||||
|
||||
@ -273,6 +279,7 @@ public class CodeWriter extends BasicWriter {
|
||||
private ConstantWriter constantWriter;
|
||||
private LocalVariableTableWriter localVariableTableWriter;
|
||||
private LocalVariableTypeTableWriter localVariableTypeTableWriter;
|
||||
private TypeAnnotationWriter typeAnnotationWriter;
|
||||
private SourceWriter sourceWriter;
|
||||
private StackMapWriter stackMapWriter;
|
||||
private TryBlockWriter tryBlockWriter;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,10 +42,13 @@ public abstract class InstructionDetailWriter extends BasicWriter {
|
||||
LOCAL_VAR_TYPES("localVariableTypes"),
|
||||
SOURCE("source"),
|
||||
STACKMAPS("stackMaps"),
|
||||
TRY_BLOCKS("tryBlocks");
|
||||
TRY_BLOCKS("tryBlocks"),
|
||||
TYPE_ANNOS("typeAnnotations");
|
||||
|
||||
Kind(String option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
final String option;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.TypeAnnotation;
|
||||
import com.sun.tools.classfile.TypeAnnotation.Position;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Annotate instructions with details about type annotations.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* 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 TypeAnnotationWriter extends InstructionDetailWriter {
|
||||
public enum NoteKind { VISIBLE, INVISIBLE };
|
||||
public static class Note {
|
||||
Note(NoteKind kind, TypeAnnotation anno) {
|
||||
this.kind = kind;
|
||||
this.anno = anno;
|
||||
}
|
||||
public final NoteKind kind;
|
||||
public final TypeAnnotation anno;
|
||||
}
|
||||
|
||||
static TypeAnnotationWriter instance(Context context) {
|
||||
TypeAnnotationWriter instance = context.get(TypeAnnotationWriter.class);
|
||||
if (instance == null)
|
||||
instance = new TypeAnnotationWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected TypeAnnotationWriter(Context context) {
|
||||
super(context);
|
||||
context.put(TypeAnnotationWriter.class, this);
|
||||
annotationWriter = AnnotationWriter.instance(context);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
}
|
||||
|
||||
public void reset(Code_attribute attr) {
|
||||
Method m = classWriter.getMethod();
|
||||
pcMap = new HashMap<Integer, List<Note>>();
|
||||
check(NoteKind.VISIBLE, (RuntimeVisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleTypeAnnotations));
|
||||
check(NoteKind.INVISIBLE, (RuntimeInvisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeInvisibleTypeAnnotations));
|
||||
}
|
||||
|
||||
private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) {
|
||||
if (attr == null)
|
||||
return;
|
||||
|
||||
for (TypeAnnotation anno: attr.annotations) {
|
||||
Position p = anno.position;
|
||||
Note note = null;
|
||||
if (p.offset != -1)
|
||||
addNote(p.offset, note = new Note(kind, anno));
|
||||
if (p.lvarOffset != null) {
|
||||
for (int i = 0; i < p.lvarOffset.length; i++) {
|
||||
if (note == null)
|
||||
note = new Note(kind, anno);
|
||||
addNote(p.lvarOffset[i], note);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addNote(int pc, Note note) {
|
||||
List<Note> list = pcMap.get(pc);
|
||||
if (list == null)
|
||||
pcMap.put(pc, list = new ArrayList<Note>());
|
||||
list.add(note);
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeDetails(Instruction instr) {
|
||||
String indent = space(2); // get from Options?
|
||||
int pc = instr.getPC();
|
||||
List<Note> notes = pcMap.get(pc);
|
||||
if (notes != null) {
|
||||
for (Note n: notes) {
|
||||
print(indent);
|
||||
print("@");
|
||||
annotationWriter.write(n.anno, false, true);
|
||||
print(", ");
|
||||
println(n.kind.toString().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationWriter annotationWriter;
|
||||
private ClassWriter classWriter;
|
||||
private Map<Integer, List<Note>> pcMap;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,7 +46,7 @@ import java.util.HashSet;
|
||||
*/
|
||||
public enum SourceVersion {
|
||||
/*
|
||||
* Summary of language evoluation
|
||||
* Summary of language evolution
|
||||
* 1.1: nested classes
|
||||
* 1.2: strictfp
|
||||
* 1.3: no changes
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.lang.model.type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
|
||||
/**
|
||||
* Represents an annotated type.
|
||||
*
|
||||
* As of the {@link javax.lang.model.SourceVersion#RELEASE_8
|
||||
* RELEASE_8} source version, annotated types can appear for all
|
||||
* type uses.
|
||||
*
|
||||
* @author Werner Dietl
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedType extends TypeMirror,
|
||||
DeclaredType, TypeVariable, WildcardType,
|
||||
PrimitiveType, ArrayType {
|
||||
|
||||
List<? extends AnnotationMirror> getAnnotations();
|
||||
TypeMirror getUnderlyingType();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -77,6 +77,14 @@ public interface ExecutableType extends TypeMirror {
|
||||
*/
|
||||
List<? extends TypeMirror> getParameterTypes();
|
||||
|
||||
/**
|
||||
* Returns the type of this executable's receiver parameter.
|
||||
*
|
||||
* @return the type of this executable's receiver parameter
|
||||
* TODO: null if none specified or always a valid value?
|
||||
*/
|
||||
TypeMirror getReceiverType();
|
||||
|
||||
/**
|
||||
* Returns the exceptions and other throwables listed in this
|
||||
* executable's {@code throws} clause.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -151,7 +151,14 @@ public enum TypeKind {
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
INTERSECTION;
|
||||
INTERSECTION,
|
||||
|
||||
/**
|
||||
* An annotated type.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
ANNOTATED;
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this kind corresponds to a primitive
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -182,4 +182,14 @@ public interface TypeVisitor<R, P> {
|
||||
* @since 1.8
|
||||
*/
|
||||
R visitIntersection(IntersectionType t, P p);
|
||||
|
||||
/**
|
||||
* Visits an annotated type.
|
||||
*
|
||||
* @param t the type to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @return a visitor-specified result
|
||||
* @since 1.8
|
||||
*/
|
||||
R visitAnnotated(AnnotatedType t, P p);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -124,6 +124,23 @@ public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {
|
||||
return visitUnknown(t, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an {@code AnnotatedType} element by calling {@code
|
||||
* visit} on the underlying type.
|
||||
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of calling {@code visit} on the underlying type
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* TODO: should xxxVisitor8 subclasses override this and call
|
||||
* the defaultAction?
|
||||
*/
|
||||
public R visitAnnotated(AnnotatedType t, P p) {
|
||||
return visit(t.getUnderlyingType(), p);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
package javax.lang.model.util;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.AnnotationTypeMismatchException;
|
||||
import java.lang.annotation.IncompleteAnnotationException;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.type.*;
|
||||
@ -298,4 +301,116 @@ public interface Types {
|
||||
* for the given type
|
||||
*/
|
||||
TypeMirror asMemberOf(DeclaredType containing, Element element);
|
||||
|
||||
/**
|
||||
* Returns the annotations targeting the type.
|
||||
*
|
||||
* @param type the targeted type
|
||||
* @return the type annotations targeting the type
|
||||
*/
|
||||
List<? extends AnnotationMirror> typeAnnotationsOf(TypeMirror type);
|
||||
|
||||
/**
|
||||
* Returns the type's annotation for the specified type if
|
||||
* such an annotation is present, else {@code null}. The
|
||||
* annotation has to be directly present on this
|
||||
* element.
|
||||
*
|
||||
* <p> The annotation returned by this method could contain an element
|
||||
* whose value is of type {@code Class}.
|
||||
* This value cannot be returned directly: information necessary to
|
||||
* locate and load a class (such as the class loader to use) is
|
||||
* not available, and the class might not be loadable at all.
|
||||
* Attempting to read a {@code Class} object by invoking the relevant
|
||||
* method on the returned annotation
|
||||
* will result in a {@link MirroredTypeException},
|
||||
* from which the corresponding {@link TypeMirror} may be extracted.
|
||||
* Similarly, attempting to read a {@code Class[]}-valued element
|
||||
* will result in a {@link MirroredTypesException}.
|
||||
*
|
||||
* <blockquote>
|
||||
* <i>Note:</i> This method is unlike others in this and related
|
||||
* interfaces. It operates on runtime reflective information —
|
||||
* representations of annotation types currently loaded into the
|
||||
* VM — rather than on the representations defined by and used
|
||||
* throughout these interfaces. Consequently, calling methods on
|
||||
* the returned annotation object can throw many of the exceptions
|
||||
* that can be thrown when calling methods on an annotation object
|
||||
* returned by core reflection. This method is intended for
|
||||
* callers that are written to operate on a known, fixed set of
|
||||
* annotation types.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param <A> the annotation type
|
||||
* @param type the targeted type
|
||||
* @param annotationType the {@code Class} object corresponding to
|
||||
* the annotation type
|
||||
* @return the type's annotation for the specified annotation
|
||||
* type if present on the type, else {@code null}
|
||||
*
|
||||
* @see Element#getAnnotationMirrors()
|
||||
* @see EnumConstantNotPresentException
|
||||
* @see AnnotationTypeMismatchException
|
||||
* @see IncompleteAnnotationException
|
||||
* @see MirroredTypeException
|
||||
* @see MirroredTypesException
|
||||
*/
|
||||
<A extends Annotation> A typeAnnotationOf(TypeMirror type, Class<A> annotationType);
|
||||
|
||||
/**
|
||||
* Returns the annotations targeting the method receiver type.
|
||||
*
|
||||
* @param type the targeted type
|
||||
* @return the receiver type of the executable type
|
||||
*/
|
||||
TypeMirror receiverTypeOf(ExecutableType type);
|
||||
|
||||
/**
|
||||
* Returns the type's annotation for the specified executable type
|
||||
* receiver if such an annotation is present, else {@code null}. The
|
||||
* annotation has to be directly present on this
|
||||
* element.
|
||||
*
|
||||
* <p> The annotation returned by this method could contain an element
|
||||
* whose value is of type {@code Class}.
|
||||
* This value cannot be returned directly: information necessary to
|
||||
* locate and load a class (such as the class loader to use) is
|
||||
* not available, and the class might not be loadable at all.
|
||||
* Attempting to read a {@code Class} object by invoking the relevant
|
||||
* method on the returned annotation
|
||||
* will result in a {@link MirroredTypeException},
|
||||
* from which the corresponding {@link TypeMirror} may be extracted.
|
||||
* Similarly, attempting to read a {@code Class[]}-valued element
|
||||
* will result in a {@link MirroredTypesException}.
|
||||
*
|
||||
* <blockquote>
|
||||
* <i>Note:</i> This method is unlike others in this and related
|
||||
* interfaces. It operates on runtime reflective information —
|
||||
* representations of annotation types currently loaded into the
|
||||
* VM — rather than on the representations defined by and used
|
||||
* throughout these interfaces. Consequently, calling methods on
|
||||
* the returned annotation object can throw many of the exceptions
|
||||
* that can be thrown when calling methods on an annotation object
|
||||
* returned by core reflection. This method is intended for
|
||||
* callers that are written to operate on a known, fixed set of
|
||||
* annotation types.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param <A> the annotation type
|
||||
* @param type the method type
|
||||
* @param annotationType the {@code Class} object corresponding to
|
||||
* the annotation type
|
||||
* @return the type's annotation for the specified annotation
|
||||
* type if present on the type, else {@code null}
|
||||
*
|
||||
* @see Element#getAnnotationMirrors()
|
||||
* @see EnumConstantNotPresentException
|
||||
* @see AnnotationTypeMismatchException
|
||||
* @see IncompleteAnnotationException
|
||||
* @see MirroredTypeException
|
||||
* @see MirroredTypesException
|
||||
*/
|
||||
// TODO: no longer needed?
|
||||
// <A extends Annotation> A receiverTypeAnnotationOf(ExecutableType type, Class<A> annotationType);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Make sure that annotations types with optional elements has
|
||||
* element headers
|
||||
* @author Mahmood Ali
|
||||
* @library ../lib/
|
||||
* @build JavadocTester
|
||||
* @build TestAnnotationOptional
|
||||
* @run main TestAnnotationOptional
|
||||
*/
|
||||
|
||||
public class TestAnnotationOptional extends JavadocTester {
|
||||
|
||||
//Test information.
|
||||
private static final String BUG_ID = "NO_BUG_ID_YET";
|
||||
|
||||
//Javadoc arguments.
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "-source", "1.5", "pkg"
|
||||
};
|
||||
|
||||
//Input for string search tests.
|
||||
private static final String[][] TEST = {
|
||||
{BUG_ID + FS + "pkg" + FS + "AnnotationOptional.html",
|
||||
"<a name=\"annotation_type_element_detail\">"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] NEGATED_TEST = NO_TEST;
|
||||
|
||||
/**
|
||||
* The entry point of the test.
|
||||
* @param args the array of command line arguments.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
TestAnnotationOptional tester = new TestAnnotationOptional();
|
||||
run(tester, ARGS, TEST, NEGATED_TEST);
|
||||
tester.printSummary();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getBugId() {
|
||||
return BUG_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getBugName() {
|
||||
return getClass().getName();
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package pkg;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* This is just a test annotation type with optional value element.
|
||||
*
|
||||
* @author Mahmood Ali
|
||||
* @since 1.5
|
||||
*/
|
||||
@Documented public @interface AnnotationOptional {
|
||||
String value() default "";
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8006735
|
||||
* @ignore
|
||||
* @summary Smoke test for ensuring that annotations are emited to javadoc
|
||||
*
|
||||
* @author Mahmood Ali <mali>
|
||||
* @library ../../lib/
|
||||
* @build JavadocTester
|
||||
* @build TestSmoke
|
||||
* @run main TestSmoke
|
||||
*/
|
||||
|
||||
public class TestSmoke extends JavadocTester {
|
||||
|
||||
//Test information.
|
||||
private static final String BUG_ID = "NOT_SPECIFIED_YET";
|
||||
|
||||
//Javadoc arguments.
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
|
||||
};
|
||||
|
||||
//Input for string search tests.
|
||||
private static final String[][] TEST = {
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x06.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x20.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x22.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x10.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x12.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x11.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x13.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x15.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x14.html", "@DA"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x16.html", "@DA"}
|
||||
};
|
||||
|
||||
private static final String[][] NEGATED_TEST = {
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x00.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x01.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x02.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x04.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x08.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x06.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x20.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x22.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x10.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x12.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x11.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x13.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x15.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x14.html", "@A"},
|
||||
{BUG_ID + FS + "pkg" + FS + "T0x16.html", "@A"}
|
||||
};
|
||||
|
||||
/**
|
||||
* The entry point of the test.
|
||||
* @param args the array of command line arguments.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
TestSmoke tester = new TestSmoke();
|
||||
run(tester, ARGS, TEST, NEGATED_TEST);
|
||||
tester.printSummary();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getBugId() {
|
||||
return BUG_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getBugName() {
|
||||
return getClass().getName();
|
||||
}
|
||||
}
|
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package pkg;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/*
|
||||
* @summary compiler accepts all values
|
||||
* @author Mahmood Ali
|
||||
* @author Yuri Gaevsky
|
||||
*/
|
||||
|
||||
@Target({TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface A {}
|
||||
|
||||
@Target({TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@interface DA {}
|
||||
|
||||
/** wildcard bound */
|
||||
class T0x1C {
|
||||
void m0x1C(List<? extends @A @DA String> lst) {}
|
||||
}
|
||||
|
||||
/** wildcard bound generic/array */
|
||||
class T0x1D<T> {
|
||||
void m0x1D(List<? extends @A @DA List<int[]>> lst) {}
|
||||
}
|
||||
|
||||
/** typecast */
|
||||
class T0x00 {
|
||||
void m0x00(Long l1) {
|
||||
Object l2 = (@A @DA Long) l1;
|
||||
}
|
||||
}
|
||||
|
||||
/** typecast generic/array */
|
||||
class T0x01<T> {
|
||||
void m0x01(List<T> list) {
|
||||
List<T> l = (List<@A @DA T>) list;
|
||||
}
|
||||
}
|
||||
|
||||
/** instanceof */
|
||||
class T0x02 {
|
||||
boolean m0x02(String s) {
|
||||
return (s instanceof @A @DA String);
|
||||
}
|
||||
}
|
||||
|
||||
/** object creation (new) */
|
||||
class T0x04 {
|
||||
void m0x04() {
|
||||
new @A @DA ArrayList<String>();
|
||||
}
|
||||
}
|
||||
|
||||
/** local variable */
|
||||
class T0x08 {
|
||||
void m0x08() {
|
||||
@A @DA String s = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** method parameter generic/array */
|
||||
class T0x0D {
|
||||
void m0x0D(HashMap<@A @DA Object, List<@A @DA List<@A @DA Class>>> s1) {}
|
||||
}
|
||||
|
||||
/** method receiver */
|
||||
class T0x06 {
|
||||
void m0x06(@A @DA T0x06 this) {}
|
||||
}
|
||||
|
||||
/** method return type generic/array */
|
||||
class T0x0B {
|
||||
Class<@A @DA Object> m0x0B() { return null; }
|
||||
}
|
||||
|
||||
/** field generic/array */
|
||||
class T0x0F {
|
||||
HashMap<@A @DA Object, @A @DA Object> c1;
|
||||
}
|
||||
|
||||
/** method type parameter */
|
||||
class T0x20<T, U> {
|
||||
<@A @DA T, @A @DA U> void m0x20() {}
|
||||
}
|
||||
|
||||
/** class type parameter */
|
||||
class T0x22<@A @DA T, @A @DA U> {
|
||||
}
|
||||
|
||||
/** class type parameter bound */
|
||||
class T0x10<T extends @A @DA Cloneable> {
|
||||
}
|
||||
|
||||
class T0x10A<T extends @A @DA Object> {
|
||||
}
|
||||
|
||||
/** method type parameter bound */
|
||||
class T0x12<T> {
|
||||
<T extends @A @DA Cloneable> void m0x12() {}
|
||||
}
|
||||
|
||||
/** class type parameter bound generic/array */
|
||||
class T0x11<T extends List<@A @DA T>> {
|
||||
}
|
||||
|
||||
/** method type parameter bound generic/array */
|
||||
class T0x13 {
|
||||
static <T extends Comparable<@A @DA T>> T m0x13() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** class extends/implements generic/array */
|
||||
class T0x15<T> extends ArrayList<@A @DA T> {
|
||||
}
|
||||
|
||||
/** type test (instanceof) generic/array */
|
||||
class T0x03<T> {
|
||||
void m0x03(T typeObj, Object obj) {
|
||||
boolean ok = obj instanceof String @A @DA [];
|
||||
}
|
||||
}
|
||||
|
||||
/** object creation (new) generic/array */
|
||||
class T0x05<T> {
|
||||
void m0x05() {
|
||||
new ArrayList<@A @DA T>();
|
||||
}
|
||||
}
|
||||
|
||||
/** local variable generic/array */
|
||||
class T0x09<T> {
|
||||
void g() {
|
||||
List<@A @DA String> l = null;
|
||||
}
|
||||
|
||||
void a() {
|
||||
String @A @DA [] as = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** type argument in constructor call generic/array */
|
||||
class T0x19 {
|
||||
<T> T0x19() {}
|
||||
|
||||
void g() {
|
||||
new <List<@A @DA String>> T0x19();
|
||||
}
|
||||
}
|
||||
|
||||
/** type argument in method call generic/array */
|
||||
class T0x1B<T> {
|
||||
void m0x1B() {
|
||||
Collections.<T @A @DA []>emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/** type argument in constructor call */
|
||||
class T0x18<T> {
|
||||
<T> T0x18() {}
|
||||
|
||||
void m() {
|
||||
new <@A @DA Integer> T0x18();
|
||||
}
|
||||
}
|
||||
|
||||
/** type argument in method call */
|
||||
class T0x1A<T,U> {
|
||||
public static <T, U> T m() { return null; }
|
||||
static void m0x1A() {
|
||||
T0x1A.<@A @DA Integer, @A @DA Short>m();
|
||||
}
|
||||
}
|
||||
|
||||
/** class extends/implements */
|
||||
class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable {
|
||||
}
|
||||
|
||||
/** exception type in throws */
|
||||
class T0x16 {
|
||||
void m0x16() throws @A @DA Exception {}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,7 @@
|
||||
* @build JavacTestingAbstractProcessor
|
||||
* @compile/fail/ref=NegTest.ref -XDrawDiagnostics TestImportStar.java
|
||||
* @compile Anno.java AnnoProcessor.java
|
||||
* @compile/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java
|
||||
* @compile/fail/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java
|
||||
*/
|
||||
|
||||
//The @compile/fail... verifies that the fix doesn't break the normal compilation of import xxx.*
|
||||
|
@ -1,3 +1,4 @@
|
||||
- compiler.note.proc.messager: RUNNING - lastRound = false
|
||||
TestImportStar.java:39:1: compiler.err.doesnt.exist: xxx
|
||||
- compiler.note.proc.messager: RUNNING - lastRound = true
|
||||
1 error
|
@ -19,8 +19,8 @@ public class T6873845 {
|
||||
if (out.contains("sunapi"))
|
||||
throw new Exception("unexpected output for -X");
|
||||
|
||||
String warn1 = "T6873845.java:72:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
|
||||
String warn2 = "T6873845.java:77:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
|
||||
String warn1 = "T6873845.java:73:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
|
||||
String warn2 = "T6873845.java:78:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
|
||||
String note1 = "- compiler.note.sunapi.filename: T6873845.java" + newline;
|
||||
String note2 = "- compiler.note.sunapi.recompile" + newline;
|
||||
|
||||
@ -52,7 +52,8 @@ public class T6873845 {
|
||||
args.add(0, "-XDrawDiagnostics");
|
||||
String out = compile(args);
|
||||
if (!out.equals(expect))
|
||||
throw new Exception("unexpected output from compiler");
|
||||
throw new Exception("unexpected output from compiler; expected: " + expect +
|
||||
"\n found: " + out);
|
||||
}
|
||||
|
||||
String compile(List<String> args) throws Exception{
|
||||
|
88
langtools/test/tools/javac/T6985181.java
Normal file
88
langtools/test/tools/javac/T6985181.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6985181
|
||||
* @summary Annotations lost from classfile
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class T6985181 {
|
||||
public static void main(String... args) throws Exception{
|
||||
new T6985181().run();
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
String code = "@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_PARAMETER)\n" +
|
||||
"@interface Simple { }\n" +
|
||||
"interface Test<@Simple T> { }";
|
||||
|
||||
File srcFile = writeFile("Test.java", code);
|
||||
File classesDir = new File("classes");
|
||||
classesDir.mkdirs();
|
||||
compile("-d", classesDir.getPath(), srcFile.getPath());
|
||||
String out = javap(new File(classesDir, srcFile.getName().replace(".java", ".class")));
|
||||
if (!out.contains("RuntimeInvisibleTypeAnnotations"))
|
||||
throw new Exception("RuntimeInvisibleTypeAnnotations not found");
|
||||
}
|
||||
|
||||
void compile(String... args) throws Exception {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javac.Main.compile(args, pw);
|
||||
pw.close();
|
||||
String out = sw.toString();
|
||||
if (out.length() > 0)
|
||||
System.err.println(out);
|
||||
if (rc != 0)
|
||||
throw new Exception("Compilation failed: rc=" + rc);
|
||||
}
|
||||
|
||||
String javap(File classFile) throws Exception {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
String[] args = { "-v", classFile.getPath() };
|
||||
int rc = com.sun.tools.javap.Main.run(args, pw);
|
||||
pw.close();
|
||||
String out = sw.toString();
|
||||
if (out.length() > 0)
|
||||
System.err.println(out);
|
||||
if (rc != 0)
|
||||
throw new Exception("javap failed: rc=" + rc);
|
||||
return out;
|
||||
}
|
||||
|
||||
File writeFile(String path, String body) throws IOException {
|
||||
File f = new File(path);
|
||||
FileWriter out = new FileWriter(f);
|
||||
try {
|
||||
out.write(body);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6881115 6976649
|
||||
@ -6,15 +9,18 @@
|
||||
* @compile/fail/ref=T6881115.out -XDrawDiagnostics T6881115.java
|
||||
*/
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.TYPE_PARAMETER, ElementType.ANNOTATION_TYPE})
|
||||
@interface A {
|
||||
B b() default @B(b2 = 1, b2 = 2);
|
||||
B[] b_arr() default {@B(), @B(b2 = 1, b2 = 2)};
|
||||
}
|
||||
|
||||
@interface B {
|
||||
String b1();
|
||||
int b2();
|
||||
}
|
||||
|
||||
@A(b = @B(b2 = 1, b2 = 2),
|
||||
b_arr = {@B(), @B(b2 = 1, b2 = 2)})
|
||||
class T6881115</*308 @A(b = @B(b2 = 1, b2 = 2),
|
||||
b_arr = {@B(), @B(b2 = 1, b2 = 2)})*/ X> {}
|
||||
class T6881115<@A(b = @B(b2 = 1, b2 = 2),
|
||||
b_arr = {@B(), @B(b2 = 1, b2 = 2)}) X> {}
|
||||
|
@ -1,11 +1,16 @@
|
||||
T6881115.java:10:30: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:10:19: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:11:26: compiler.err.annotation.missing.default.value.1: B, b1,b2
|
||||
T6881115.java:11:43: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:11:32: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:17:19: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:17:8: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:18:13: compiler.err.annotation.missing.default.value.1: B, b1,b2
|
||||
T6881115.java:18:30: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:18:19: compiler.err.annotation.missing.default.value: B, b1
|
||||
10 errors
|
||||
T6881115.java:14:30: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:14:19: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:15:26: compiler.err.annotation.missing.default.value.1: B, b1,b2
|
||||
T6881115.java:15:43: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:15:32: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:23:19: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:23:8: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:24:13: compiler.err.annotation.missing.default.value.1: B, b1,b2
|
||||
T6881115.java:24:30: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:24:19: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:25:34: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:25:23: compiler.err.annotation.missing.default.value: B, b1
|
||||
T6881115.java:26:28: compiler.err.annotation.missing.default.value.1: B, b1,b2
|
||||
T6881115.java:26:45: compiler.err.duplicate.annotation.member.value: b2, B
|
||||
T6881115.java:26:34: compiler.err.annotation.missing.default.value: B, b1
|
||||
15 errors
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user