feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
249
jdkSrc/jdk8/com/sun/tools/javac/code/AnnoConstruct.java
Normal file
249
jdkSrc/jdk8/com/sun/tools/javac/code/AnnoConstruct.java
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.javac.code;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.lang.model.AnnotatedConstruct;
|
||||
|
||||
import com.sun.tools.javac.model.AnnotationProxyMaker;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
|
||||
/**
|
||||
* Common super type for annotated constructs such as Types and Symbols.
|
||||
*
|
||||
* This class should *not* contain any fields since it would have a significant
|
||||
* impact on the javac memory footprint.
|
||||
*
|
||||
* <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></p>
|
||||
*/
|
||||
public abstract class AnnoConstruct implements AnnotatedConstruct {
|
||||
|
||||
|
||||
// Override to enforce a narrower return type.
|
||||
@Override
|
||||
public abstract List<? extends Attribute.Compound> getAnnotationMirrors();
|
||||
|
||||
|
||||
// This method is part of the javax.lang.model API, do not use this in javac code.
|
||||
protected <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) {
|
||||
String name = annoType.getName();
|
||||
|
||||
for (Attribute.Compound anno : getAnnotationMirrors()) {
|
||||
if (name.equals(anno.type.tsym.flatName().toString()))
|
||||
return anno;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
|
||||
return (A[]) java.lang.reflect.Array.newInstance(annoType, 0); // annoType is the Class for A
|
||||
}
|
||||
|
||||
|
||||
// This method is part of the javax.lang.model API, do not use this in javac code.
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annoType) {
|
||||
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
// If annoType does not declare a container this is equivalent to wrapping
|
||||
// getAnnotation(...) in an array.
|
||||
Class <? extends Annotation> containerType = getContainer(annoType);
|
||||
if (containerType == null) {
|
||||
A res = getAnnotation(annoType);
|
||||
int size = res == null ? 0 : 1;
|
||||
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
if (res != null)
|
||||
arr[0] = res;
|
||||
return arr;
|
||||
}
|
||||
|
||||
// So we have a containing type
|
||||
String annoTypeName = annoType.getName();
|
||||
String containerTypeName = containerType.getName();
|
||||
int directIndex = -1, containerIndex = -1;
|
||||
Attribute.Compound direct = null, container = null;
|
||||
// Find directly (explicit or implicit) present annotations
|
||||
int index = -1;
|
||||
for (Attribute.Compound attribute : getAnnotationMirrors()) {
|
||||
index++;
|
||||
if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) {
|
||||
directIndex = index;
|
||||
direct = attribute;
|
||||
} else if(containerTypeName != null &&
|
||||
attribute.type.tsym.flatName().contentEquals(containerTypeName)) {
|
||||
containerIndex = index;
|
||||
container = attribute;
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with inherited annotations
|
||||
if (direct == null && container == null &&
|
||||
annoType.isAnnotationPresent(Inherited.class))
|
||||
return getInheritedAnnotations(annoType);
|
||||
|
||||
Attribute.Compound[] contained = unpackContained(container);
|
||||
|
||||
// In case of an empty legacy container we might need to look for
|
||||
// inherited annos as well
|
||||
if (direct == null && contained.length == 0 &&
|
||||
annoType.isAnnotationPresent(Inherited.class))
|
||||
return getInheritedAnnotations(annoType);
|
||||
|
||||
int size = (direct == null ? 0 : 1) + contained.length;
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
|
||||
// if direct && container, which is first?
|
||||
int insert = -1;
|
||||
int length = arr.length;
|
||||
if (directIndex >= 0 && containerIndex >= 0) {
|
||||
if (directIndex < containerIndex) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 1;
|
||||
} else {
|
||||
arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 0;
|
||||
length--;
|
||||
}
|
||||
} else if (directIndex >= 0) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
return arr;
|
||||
} else {
|
||||
// Only container
|
||||
insert = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i + insert < length; i++)
|
||||
arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
private Attribute.Compound[] unpackContained(Attribute.Compound container) {
|
||||
// Pack them in an array
|
||||
Attribute[] contained0 = null;
|
||||
if (container != null)
|
||||
contained0 = unpackAttributes(container);
|
||||
ListBuffer<Attribute.Compound> compounds = new ListBuffer<>();
|
||||
if (contained0 != null) {
|
||||
for (Attribute a : contained0)
|
||||
if (a instanceof Attribute.Compound)
|
||||
compounds = compounds.append((Attribute.Compound)a);
|
||||
}
|
||||
return compounds.toArray(new Attribute.Compound[compounds.size()]);
|
||||
}
|
||||
|
||||
// This method is part of the javax.lang.model API, do not use this in javac code.
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annoType) {
|
||||
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: " + annoType);
|
||||
|
||||
Attribute.Compound c = getAttribute(annoType);
|
||||
return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
|
||||
}
|
||||
|
||||
// Needed to unpack the runtime view of containing annotations
|
||||
private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
|
||||
private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
|
||||
|
||||
private static Class<? extends Annotation> initRepeatable() {
|
||||
try {
|
||||
// Repeatable will not be available when bootstrapping on
|
||||
// JDK 7 so use a reflective lookup instead of a class
|
||||
// literal for Repeatable.class.
|
||||
return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
|
||||
} catch (ClassNotFoundException | SecurityException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method initValueElementMethod() {
|
||||
if (REPEATABLE_CLASS == null)
|
||||
return null;
|
||||
|
||||
Method m = null;
|
||||
try {
|
||||
m = REPEATABLE_CLASS.getMethod("value");
|
||||
if (m != null)
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Helper to getAnnotationsByType
|
||||
private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
|
||||
// Since we can not refer to java.lang.annotation.Repeatable until we are
|
||||
// bootstrapping with java 8 we need to get the Repeatable annotation using
|
||||
// reflective invocations instead of just using its type and element method.
|
||||
if (REPEATABLE_CLASS != null &&
|
||||
VALUE_ELEMENT_METHOD != null) {
|
||||
// Get the Repeatable instance on the annotations declaration
|
||||
Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
|
||||
if (repeatable != null) {
|
||||
try {
|
||||
// Get the value element, it should be a class
|
||||
// indicating the containing annotation type
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
|
||||
if (containerType == null)
|
||||
return null;
|
||||
|
||||
return containerType;
|
||||
} catch (ClassCastException | IllegalAccessException | InvocationTargetException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Helper to getAnnotationsByType
|
||||
private static Attribute[] unpackAttributes(Attribute.Compound container) {
|
||||
// We now have an instance of the container,
|
||||
// unpack it returning an instance of the
|
||||
// contained type or null
|
||||
return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
|
||||
}
|
||||
|
||||
}
|
401
jdkSrc/jdk8/com/sun/tools/javac/code/Attribute.java
Normal file
401
jdkSrc/jdk8/com/sun/tools/javac/code/Attribute.java
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.AnnotationValueVisitor;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
/** An annotation value.
|
||||
*
|
||||
* <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 Attribute implements AnnotationValue {
|
||||
|
||||
/** The type of the annotation element. */
|
||||
public Type type;
|
||||
|
||||
public Attribute(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public abstract void accept(Visitor v);
|
||||
|
||||
public Object getValue() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isSynthesized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public TypeAnnotationPosition getPosition() { return null; };
|
||||
|
||||
/** The value for an annotation element of primitive type or String. */
|
||||
public static class Constant extends Attribute {
|
||||
public final Object value;
|
||||
public void accept(Visitor v) { v.visitConstant(this); }
|
||||
public Constant(Type type, Object value) {
|
||||
super(type);
|
||||
this.value = value;
|
||||
}
|
||||
public String toString() {
|
||||
return Constants.format(value, type);
|
||||
}
|
||||
public Object getValue() {
|
||||
return Constants.decode(value, type);
|
||||
}
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
if (value instanceof String)
|
||||
return v.visitString((String) value, p);
|
||||
if (value instanceof Integer) {
|
||||
int i = (Integer) value;
|
||||
switch (type.getTag()) {
|
||||
case BOOLEAN: return v.visitBoolean(i != 0, p);
|
||||
case CHAR: return v.visitChar((char) i, p);
|
||||
case BYTE: return v.visitByte((byte) i, p);
|
||||
case SHORT: return v.visitShort((short) i, p);
|
||||
case INT: return v.visitInt(i, p);
|
||||
}
|
||||
}
|
||||
switch (type.getTag()) {
|
||||
case LONG: return v.visitLong((Long) value, p);
|
||||
case FLOAT: return v.visitFloat((Float) value, p);
|
||||
case DOUBLE: return v.visitDouble((Double) value, p);
|
||||
}
|
||||
throw new AssertionError("Bad annotation element value: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
/** The value for an annotation element of type java.lang.Class,
|
||||
* represented as a ClassSymbol.
|
||||
*/
|
||||
public static class Class extends Attribute {
|
||||
public final Type classType;
|
||||
public void accept(Visitor v) { v.visitClass(this); }
|
||||
public Class(Types types, Type type) {
|
||||
super(makeClassType(types, type));
|
||||
this.classType = type;
|
||||
}
|
||||
static Type makeClassType(Types types, Type type) {
|
||||
Type arg = type.isPrimitive()
|
||||
? types.boxedClass(type).type
|
||||
: types.erasure(type);
|
||||
return new Type.ClassType(types.syms.classType.getEnclosingType(),
|
||||
List.of(arg),
|
||||
types.syms.classType.tsym);
|
||||
}
|
||||
public String toString() {
|
||||
return classType + ".class";
|
||||
}
|
||||
public Type getValue() {
|
||||
return classType;
|
||||
}
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
return v.visitType(classType, p);
|
||||
}
|
||||
}
|
||||
|
||||
/** A compound annotation element value, the type of which is an
|
||||
* attribute interface.
|
||||
*/
|
||||
public static class Compound extends Attribute implements AnnotationMirror {
|
||||
/** The attributes values, as pairs. Each pair contains a
|
||||
* reference to the accessing method in the attribute interface
|
||||
* and the value to be returned when that method is called to
|
||||
* access this attribute.
|
||||
*/
|
||||
public final List<Pair<MethodSymbol,Attribute>> values;
|
||||
|
||||
private boolean synthesized = false;
|
||||
|
||||
@Override
|
||||
public boolean isSynthesized() {
|
||||
return synthesized;
|
||||
}
|
||||
|
||||
public void setSynthesized(boolean synthesized) {
|
||||
this.synthesized = synthesized;
|
||||
}
|
||||
|
||||
public Compound(Type type,
|
||||
List<Pair<MethodSymbol,Attribute>> values) {
|
||||
super(type);
|
||||
this.values = values;
|
||||
}
|
||||
public void accept(Visitor v) { v.visitCompound(this); }
|
||||
|
||||
/**
|
||||
* Returns a string representation of this annotation.
|
||||
* String is of one of the forms:
|
||||
* @com.example.foo(name1=val1, name2=val2)
|
||||
* @com.example.foo(val)
|
||||
* @com.example.foo
|
||||
* Omit parens for marker annotations, and omit "value=" when allowed.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("@");
|
||||
buf.append(type);
|
||||
int len = values.length();
|
||||
if (len > 0) {
|
||||
buf.append('(');
|
||||
boolean first = true;
|
||||
for (Pair<MethodSymbol, Attribute> value : values) {
|
||||
if (!first) buf.append(", ");
|
||||
first = false;
|
||||
|
||||
Name name = value.fst.name;
|
||||
if (len > 1 || name != name.table.names.value) {
|
||||
buf.append(name);
|
||||
buf.append('=');
|
||||
}
|
||||
buf.append(value.snd);
|
||||
}
|
||||
buf.append(')');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public Attribute member(Name member) {
|
||||
Pair<MethodSymbol,Attribute> res = getElemPair(member);
|
||||
return res == null ? null : res.snd;
|
||||
}
|
||||
|
||||
private Pair<MethodSymbol, Attribute> getElemPair(Name member) {
|
||||
for (Pair<MethodSymbol,Attribute> pair : values)
|
||||
if (pair.fst.name == member) return pair;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Attribute.Compound getValue() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
return v.visitAnnotation(this, p);
|
||||
}
|
||||
|
||||
public DeclaredType getAnnotationType() {
|
||||
return (DeclaredType) type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeAnnotationPosition getPosition() {
|
||||
if (values.size() != 0) {
|
||||
Name valueName = values.head.fst.name.table.names.value;
|
||||
Pair<MethodSymbol, Attribute> res = getElemPair(valueName);
|
||||
return res == null ? null : res.snd.getPosition();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<MethodSymbol, Attribute> getElementValues() {
|
||||
Map<MethodSymbol, Attribute> valmap =
|
||||
new LinkedHashMap<MethodSymbol, Attribute>();
|
||||
for (Pair<MethodSymbol, Attribute> value : values)
|
||||
valmap.put(value.fst, value.snd);
|
||||
return valmap;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeAnnotationPosition getPosition() {
|
||||
if (hasUnknownPosition()) {
|
||||
position = super.getPosition();
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
public boolean hasUnknownPosition() {
|
||||
return position.type == TargetType.UNKNOWN;
|
||||
}
|
||||
|
||||
public boolean isContainerTypeCompound() {
|
||||
if (isSynthesized() && values.size() == 1)
|
||||
return getFirstEmbeddedTC() != null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private TypeCompound getFirstEmbeddedTC() {
|
||||
if (values.size() == 1) {
|
||||
Pair<MethodSymbol, Attribute> val = values.get(0);
|
||||
if (val.fst.getSimpleName().contentEquals("value")
|
||||
&& val.snd instanceof Array) {
|
||||
Array arr = (Array) val.snd;
|
||||
if (arr.values.length != 0
|
||||
&& arr.values[0] instanceof Attribute.TypeCompound)
|
||||
return (Attribute.TypeCompound) arr.values[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean tryFixPosition() {
|
||||
if (!isContainerTypeCompound())
|
||||
return false;
|
||||
|
||||
TypeCompound from = getFirstEmbeddedTC();
|
||||
if (from != null && from.position != null &&
|
||||
from.position.type != TargetType.UNKNOWN) {
|
||||
position = from.position;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** The value for an annotation element of an array type.
|
||||
*/
|
||||
public static class Array extends Attribute {
|
||||
public final Attribute[] values;
|
||||
public Array(Type type, Attribute[] values) {
|
||||
super(type);
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Array(Type type, List<Attribute> values) {
|
||||
super(type);
|
||||
this.values = values.toArray(new Attribute[values.size()]);
|
||||
}
|
||||
|
||||
public void accept(Visitor v) { v.visitArray(this); }
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('{');
|
||||
boolean first = true;
|
||||
for (Attribute value : values) {
|
||||
if (!first)
|
||||
buf.append(", ");
|
||||
first = false;
|
||||
buf.append(value);
|
||||
}
|
||||
buf.append('}');
|
||||
return buf.toString();
|
||||
}
|
||||
public List<Attribute> getValue() {
|
||||
return List.from(values);
|
||||
}
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
return v.visitArray(getValue(), p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeAnnotationPosition getPosition() {
|
||||
if (values.length != 0)
|
||||
return values[0].getPosition();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** The value for an annotation element of an enum type.
|
||||
*/
|
||||
public static class Enum extends Attribute {
|
||||
public VarSymbol value;
|
||||
public Enum(Type type, VarSymbol value) {
|
||||
super(type);
|
||||
this.value = Assert.checkNonNull(value);
|
||||
}
|
||||
public void accept(Visitor v) { v.visitEnum(this); }
|
||||
public String toString() {
|
||||
return value.enclClass() + "." + value; // qualified name
|
||||
}
|
||||
public VarSymbol getValue() {
|
||||
return value;
|
||||
}
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
return v.visitEnumConstant(value, p);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Error extends Attribute {
|
||||
public Error(Type type) {
|
||||
super(type);
|
||||
}
|
||||
public void accept(Visitor v) { v.visitError(this); }
|
||||
public String toString() {
|
||||
return "<error>";
|
||||
}
|
||||
public String getValue() {
|
||||
return toString();
|
||||
}
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
return v.visitString(toString(), p);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnresolvedClass extends Error {
|
||||
public Type classType;
|
||||
public UnresolvedClass(Type type, Type classType) {
|
||||
super(type);
|
||||
this.classType = classType;
|
||||
}
|
||||
}
|
||||
|
||||
/** A visitor type for dynamic dispatch on the kind of attribute value. */
|
||||
public static interface Visitor {
|
||||
void visitConstant(Attribute.Constant value);
|
||||
void visitClass(Attribute.Class clazz);
|
||||
void visitCompound(Attribute.Compound compound);
|
||||
void visitArray(Attribute.Array array);
|
||||
void visitEnum(Attribute.Enum e);
|
||||
void visitError(Attribute.Error e);
|
||||
}
|
||||
|
||||
/** A mirror of java.lang.annotation.RetentionPolicy. */
|
||||
public static enum RetentionPolicy {
|
||||
SOURCE,
|
||||
CLASS,
|
||||
RUNTIME
|
||||
}
|
||||
}
|
47
jdkSrc/jdk8/com/sun/tools/javac/code/BoundKind.java
Normal file
47
jdkSrc/jdk8/com/sun/tools/javac/code/BoundKind.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, 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.javac.code;
|
||||
|
||||
/**
|
||||
*
|
||||
* <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 enum BoundKind {
|
||||
EXTENDS("? extends "),
|
||||
SUPER("? super "),
|
||||
UNBOUND("?");
|
||||
|
||||
private final String name;
|
||||
|
||||
BoundKind(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() { return name; }
|
||||
}
|
144
jdkSrc/jdk8/com/sun/tools/javac/code/DeferredLintHandler.java
Normal file
144
jdkSrc/jdk8/com/sun/tools/javac/code/DeferredLintHandler.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* <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 DeferredLintHandler {
|
||||
protected static final Context.Key<DeferredLintHandler> deferredLintHandlerKey =
|
||||
new Context.Key<DeferredLintHandler>();
|
||||
|
||||
public static DeferredLintHandler instance(Context context) {
|
||||
DeferredLintHandler instance = context.get(deferredLintHandlerKey);
|
||||
if (instance == null)
|
||||
instance = new DeferredLintHandler(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected DeferredLintHandler(Context context) {
|
||||
context.put(deferredLintHandlerKey, this);
|
||||
this.currentPos = IMMEDIATE_POSITION;
|
||||
}
|
||||
|
||||
/**An interface for deferred lint reporting - loggers passed to
|
||||
* {@link #report(LintLogger) } will be called when
|
||||
* {@link #flush(DiagnosticPosition) } is invoked.
|
||||
*/
|
||||
public interface LintLogger {
|
||||
void report();
|
||||
}
|
||||
|
||||
private DiagnosticPosition currentPos;
|
||||
private Map<DiagnosticPosition, ListBuffer<LintLogger>> loggersQueue = new HashMap<DiagnosticPosition, ListBuffer<LintLogger>>();
|
||||
|
||||
/**Associate the given logger with the current position as set by {@link #setPos(DiagnosticPosition) }.
|
||||
* Will be invoked when {@link #flush(DiagnosticPosition) } will be invoked with the same position.
|
||||
* <br>
|
||||
* Will invoke the logger synchronously if {@link #immediate() } was called
|
||||
* instead of {@link #setPos(DiagnosticPosition) }.
|
||||
*/
|
||||
public void report(LintLogger logger) {
|
||||
if (currentPos == IMMEDIATE_POSITION) {
|
||||
logger.report();
|
||||
} else {
|
||||
ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
|
||||
if (loggers == null) {
|
||||
loggersQueue.put(currentPos, loggers = new ListBuffer<>());
|
||||
}
|
||||
loggers.append(logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**Invoke all {@link LintLogger}s that were associated with the provided {@code pos}.
|
||||
*/
|
||||
public void flush(DiagnosticPosition pos) {
|
||||
ListBuffer<LintLogger> loggers = loggersQueue.get(pos);
|
||||
if (loggers != null) {
|
||||
for (LintLogger lintLogger : loggers) {
|
||||
lintLogger.report();
|
||||
}
|
||||
loggersQueue.remove(pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**Sets the current position to the provided {@code currentPos}. {@link LintLogger}s
|
||||
* passed to subsequent invocations of {@link #report(LintLogger) } will be associated
|
||||
* with the given position.
|
||||
*/
|
||||
public DiagnosticPosition setPos(DiagnosticPosition currentPos) {
|
||||
DiagnosticPosition prevPosition = this.currentPos;
|
||||
this.currentPos = currentPos;
|
||||
return prevPosition;
|
||||
}
|
||||
|
||||
/**{@link LintLogger}s passed to subsequent invocations of
|
||||
* {@link #report(LintLogger) } will be invoked immediately.
|
||||
*/
|
||||
public DiagnosticPosition immediate() {
|
||||
return setPos(IMMEDIATE_POSITION);
|
||||
}
|
||||
|
||||
private static final DiagnosticPosition IMMEDIATE_POSITION = new DiagnosticPosition() {
|
||||
@Override
|
||||
public JCTree getTree() {
|
||||
Assert.error();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartPosition() {
|
||||
Assert.error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredPosition() {
|
||||
Assert.error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndPosition(EndPosTable endPosTable) {
|
||||
Assert.error();
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
}
|
411
jdkSrc/jdk8/com/sun/tools/javac/code/Flags.java
Normal file
411
jdkSrc/jdk8/com/sun/tools/javac/code/Flags.java
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, 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.javac.code;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.StringUtils;
|
||||
|
||||
/** Access flags and other modifiers for Java classes and members.
|
||||
*
|
||||
* <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 Flags {
|
||||
|
||||
private Flags() {} // uninstantiable
|
||||
|
||||
public static String toString(long flags) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String sep = "";
|
||||
for (Flag flag : asFlagSet(flags)) {
|
||||
buf.append(sep);
|
||||
buf.append(flag);
|
||||
sep = " ";
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static EnumSet<Flag> asFlagSet(long flags) {
|
||||
EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class);
|
||||
for (Flag flag : Flag.values()) {
|
||||
if ((flags & flag.value) != 0) {
|
||||
flagSet.add(flag);
|
||||
flags &= ~flag.value;
|
||||
}
|
||||
}
|
||||
Assert.check(flags == 0, "Flags parameter contains unknown flags " + flags);
|
||||
return flagSet;
|
||||
}
|
||||
|
||||
/* Standard Java flags.
|
||||
*/
|
||||
public static final int PUBLIC = 1;
|
||||
public static final int PRIVATE = 1<<1;
|
||||
public static final int PROTECTED = 1<<2;
|
||||
public static final int STATIC = 1<<3;
|
||||
public static final int FINAL = 1<<4;
|
||||
public static final int SYNCHRONIZED = 1<<5;
|
||||
public static final int VOLATILE = 1<<6;
|
||||
public static final int TRANSIENT = 1<<7;
|
||||
public static final int NATIVE = 1<<8;
|
||||
public static final int INTERFACE = 1<<9;
|
||||
public static final int ABSTRACT = 1<<10;
|
||||
public static final int STRICTFP = 1<<11;
|
||||
|
||||
/* Flag that marks a symbol synthetic, added in classfile v49.0. */
|
||||
public static final int SYNTHETIC = 1<<12;
|
||||
|
||||
/** Flag that marks attribute interfaces, added in classfile v49.0. */
|
||||
public static final int ANNOTATION = 1<<13;
|
||||
|
||||
/** An enumeration type or an enumeration constant, added in
|
||||
* classfile v49.0. */
|
||||
public static final int ENUM = 1<<14;
|
||||
|
||||
/** Added in SE8, represents constructs implicitly declared in source. */
|
||||
public static final int MANDATED = 1<<15;
|
||||
|
||||
public static final int StandardFlags = 0x0fff;
|
||||
|
||||
// Because the following access flags are overloaded with other
|
||||
// bit positions, we translate them when reading and writing class
|
||||
// files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC,
|
||||
// for example.
|
||||
public static final int ACC_SUPER = 0x0020;
|
||||
public static final int ACC_BRIDGE = 0x0040;
|
||||
public static final int ACC_VARARGS = 0x0080;
|
||||
|
||||
/*****************************************
|
||||
* Internal compiler flags (no bits in the lower 16).
|
||||
*****************************************/
|
||||
|
||||
/** Flag is set if symbol is deprecated.
|
||||
*/
|
||||
public static final int DEPRECATED = 1<<17;
|
||||
|
||||
/** Flag is set for a variable symbol if the variable's definition
|
||||
* has an initializer part.
|
||||
*/
|
||||
public static final int HASINIT = 1<<18;
|
||||
|
||||
/** Flag is set for compiler-generated anonymous method symbols
|
||||
* that `own' an initializer block.
|
||||
*/
|
||||
public static final int BLOCK = 1<<20;
|
||||
|
||||
/** Flag is set for compiler-generated abstract methods that implement
|
||||
* an interface method (Miranda methods).
|
||||
*/
|
||||
public static final int IPROXY = 1<<21;
|
||||
|
||||
/** Flag is set for nested classes that do not access instance members
|
||||
* or `this' of an outer class and therefore don't need to be passed
|
||||
* a this$n reference. This value is currently set only for anonymous
|
||||
* classes in superclass constructor calls and only for pre 1.4 targets.
|
||||
* todo: use this value for optimizing away this$n parameters in
|
||||
* other cases.
|
||||
*/
|
||||
public static final int NOOUTERTHIS = 1<<22;
|
||||
|
||||
/** Flag is set for package symbols if a package has a member or
|
||||
* directory and therefore exists.
|
||||
*/
|
||||
public static final int EXISTS = 1<<23;
|
||||
|
||||
/** Flag is set for compiler-generated compound classes
|
||||
* representing multiple variable bounds
|
||||
*/
|
||||
public static final int COMPOUND = 1<<24;
|
||||
|
||||
/** Flag is set for class symbols if a class file was found for this class.
|
||||
*/
|
||||
public static final int CLASS_SEEN = 1<<25;
|
||||
|
||||
/** Flag is set for class symbols if a source file was found for this
|
||||
* class.
|
||||
*/
|
||||
public static final int SOURCE_SEEN = 1<<26;
|
||||
|
||||
/* State flags (are reset during compilation).
|
||||
*/
|
||||
|
||||
/** Flag for class symbols is set and later re-set as a lock in
|
||||
* Enter to detect cycles in the superclass/superinterface
|
||||
* relations. Similarly for constructor call cycle detection in
|
||||
* Attr.
|
||||
*/
|
||||
public static final int LOCKED = 1<<27;
|
||||
|
||||
/** Flag for class symbols is set and later re-set to indicate that a class
|
||||
* has been entered but has not yet been attributed.
|
||||
*/
|
||||
public static final int UNATTRIBUTED = 1<<28;
|
||||
|
||||
/** Flag for synthesized default constructors of anonymous classes.
|
||||
*/
|
||||
public static final int ANONCONSTR = 1<<29;
|
||||
|
||||
/** Flag for class symbols to indicate it has been checked and found
|
||||
* acyclic.
|
||||
*/
|
||||
public static final int ACYCLIC = 1<<30;
|
||||
|
||||
/** Flag that marks bridge methods.
|
||||
*/
|
||||
public static final long BRIDGE = 1L<<31;
|
||||
|
||||
/** Flag that marks formal parameters.
|
||||
*/
|
||||
public static final long PARAMETER = 1L<<33;
|
||||
|
||||
/** Flag that marks varargs methods.
|
||||
*/
|
||||
public static final long VARARGS = 1L<<34;
|
||||
|
||||
/** Flag for annotation type symbols to indicate it has been
|
||||
* checked and found acyclic.
|
||||
*/
|
||||
public static final long ACYCLIC_ANN = 1L<<35;
|
||||
|
||||
/** Flag that marks a generated default constructor.
|
||||
*/
|
||||
public static final long GENERATEDCONSTR = 1L<<36;
|
||||
|
||||
/** Flag that marks a hypothetical method that need not really be
|
||||
* generated in the binary, but is present in the symbol table to
|
||||
* simplify checking for erasure clashes - also used for 292 poly sig methods.
|
||||
*/
|
||||
public static final long HYPOTHETICAL = 1L<<37;
|
||||
|
||||
/**
|
||||
* Flag that marks an internal proprietary class.
|
||||
*/
|
||||
public static final long PROPRIETARY = 1L<<38;
|
||||
|
||||
/**
|
||||
* Flag that marks a multi-catch parameter.
|
||||
*/
|
||||
public static final long UNION = 1L<<39;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static final long EFFECTIVELY_FINAL = 1L<<41;
|
||||
|
||||
/**
|
||||
* Flag that marks non-override equivalent methods with the same signature.
|
||||
*/
|
||||
public static final long CLASH = 1L<<42;
|
||||
|
||||
/**
|
||||
* Flag that marks either a default method or an interface containing default methods.
|
||||
*/
|
||||
public static final long DEFAULT = 1L<<43;
|
||||
|
||||
/**
|
||||
* Flag that marks class as auxiliary, ie a non-public class following
|
||||
* the public class in a source file, that could block implicit compilation.
|
||||
*/
|
||||
public static final long AUXILIARY = 1L<<44;
|
||||
|
||||
/**
|
||||
* Flag that marks that a symbol is not available in the current profile
|
||||
*/
|
||||
public static final long NOT_IN_PROFILE = 1L<<45;
|
||||
|
||||
/**
|
||||
* Flag that indicates that an override error has been detected by Check.
|
||||
*/
|
||||
public static final long BAD_OVERRIDE = 1L<<45;
|
||||
|
||||
/**
|
||||
* Flag that indicates a signature polymorphic method (292).
|
||||
*/
|
||||
public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
|
||||
|
||||
/**
|
||||
* Flag that indicates that an inference variable is used in a 'throws' clause.
|
||||
*/
|
||||
public static final long THROWS = 1L<<47;
|
||||
|
||||
/**
|
||||
* Flag that marks potentially ambiguous overloads
|
||||
*/
|
||||
public static final long POTENTIALLY_AMBIGUOUS = 1L<<48;
|
||||
|
||||
/**
|
||||
* Flag that marks a synthetic method body for a lambda expression
|
||||
*/
|
||||
public static final long LAMBDA_METHOD = 1L<<49;
|
||||
|
||||
/**
|
||||
* Flag to control recursion in TransTypes
|
||||
*/
|
||||
public static final long TYPE_TRANSLATED = 1L<<50;
|
||||
|
||||
/** Modifier masks.
|
||||
*/
|
||||
public static final int
|
||||
AccessFlags = PUBLIC | PROTECTED | PRIVATE,
|
||||
LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
|
||||
MemberClassFlags = LocalClassFlags | INTERFACE | AccessFlags,
|
||||
ClassFlags = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
|
||||
InterfaceVarFlags = FINAL | STATIC | PUBLIC,
|
||||
VarFlags = AccessFlags | FINAL | STATIC |
|
||||
VOLATILE | TRANSIENT | ENUM,
|
||||
ConstructorFlags = AccessFlags,
|
||||
InterfaceMethodFlags = ABSTRACT | PUBLIC,
|
||||
MethodFlags = AccessFlags | ABSTRACT | STATIC | NATIVE |
|
||||
SYNCHRONIZED | FINAL | STRICTFP;
|
||||
public static final long
|
||||
ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
|
||||
ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
|
||||
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
|
||||
AnnotationTypeElementMask = ABSTRACT | PUBLIC,
|
||||
LocalVarFlags = FINAL | PARAMETER,
|
||||
ReceiverParamFlags = PARAMETER;
|
||||
|
||||
|
||||
public static Set<Modifier> asModifierSet(long flags) {
|
||||
Set<Modifier> modifiers = modifierSets.get(flags);
|
||||
if (modifiers == null) {
|
||||
modifiers = java.util.EnumSet.noneOf(Modifier.class);
|
||||
if (0 != (flags & PUBLIC)) modifiers.add(Modifier.PUBLIC);
|
||||
if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED);
|
||||
if (0 != (flags & PRIVATE)) modifiers.add(Modifier.PRIVATE);
|
||||
if (0 != (flags & ABSTRACT)) modifiers.add(Modifier.ABSTRACT);
|
||||
if (0 != (flags & STATIC)) modifiers.add(Modifier.STATIC);
|
||||
if (0 != (flags & FINAL)) modifiers.add(Modifier.FINAL);
|
||||
if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT);
|
||||
if (0 != (flags & VOLATILE)) modifiers.add(Modifier.VOLATILE);
|
||||
if (0 != (flags & SYNCHRONIZED))
|
||||
modifiers.add(Modifier.SYNCHRONIZED);
|
||||
if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE);
|
||||
if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP);
|
||||
if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT);
|
||||
modifiers = Collections.unmodifiableSet(modifiers);
|
||||
modifierSets.put(flags, modifiers);
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
// Cache of modifier sets.
|
||||
private static final Map<Long, Set<Modifier>> modifierSets =
|
||||
new java.util.concurrent.ConcurrentHashMap<Long, Set<Modifier>>(64);
|
||||
|
||||
public static boolean isStatic(Symbol symbol) {
|
||||
return (symbol.flags() & STATIC) != 0;
|
||||
}
|
||||
|
||||
public static boolean isEnum(Symbol symbol) {
|
||||
return (symbol.flags() & ENUM) != 0;
|
||||
}
|
||||
|
||||
public static boolean isConstant(Symbol.VarSymbol symbol) {
|
||||
return symbol.getConstValue() != null;
|
||||
}
|
||||
|
||||
|
||||
public enum Flag {
|
||||
PUBLIC(Flags.PUBLIC),
|
||||
PRIVATE(Flags.PRIVATE),
|
||||
PROTECTED(Flags.PROTECTED),
|
||||
STATIC(Flags.STATIC),
|
||||
FINAL(Flags.FINAL),
|
||||
SYNCHRONIZED(Flags.SYNCHRONIZED),
|
||||
VOLATILE(Flags.VOLATILE),
|
||||
TRANSIENT(Flags.TRANSIENT),
|
||||
NATIVE(Flags.NATIVE),
|
||||
INTERFACE(Flags.INTERFACE),
|
||||
ABSTRACT(Flags.ABSTRACT),
|
||||
DEFAULT(Flags.DEFAULT),
|
||||
STRICTFP(Flags.STRICTFP),
|
||||
BRIDGE(Flags.BRIDGE),
|
||||
SYNTHETIC(Flags.SYNTHETIC),
|
||||
ANNOTATION(Flags.ANNOTATION),
|
||||
DEPRECATED(Flags.DEPRECATED),
|
||||
HASINIT(Flags.HASINIT),
|
||||
BLOCK(Flags.BLOCK),
|
||||
ENUM(Flags.ENUM),
|
||||
MANDATED(Flags.MANDATED),
|
||||
IPROXY(Flags.IPROXY),
|
||||
NOOUTERTHIS(Flags.NOOUTERTHIS),
|
||||
EXISTS(Flags.EXISTS),
|
||||
COMPOUND(Flags.COMPOUND),
|
||||
CLASS_SEEN(Flags.CLASS_SEEN),
|
||||
SOURCE_SEEN(Flags.SOURCE_SEEN),
|
||||
LOCKED(Flags.LOCKED),
|
||||
UNATTRIBUTED(Flags.UNATTRIBUTED),
|
||||
ANONCONSTR(Flags.ANONCONSTR),
|
||||
ACYCLIC(Flags.ACYCLIC),
|
||||
PARAMETER(Flags.PARAMETER),
|
||||
VARARGS(Flags.VARARGS),
|
||||
ACYCLIC_ANN(Flags.ACYCLIC_ANN),
|
||||
GENERATEDCONSTR(Flags.GENERATEDCONSTR),
|
||||
HYPOTHETICAL(Flags.HYPOTHETICAL),
|
||||
PROPRIETARY(Flags.PROPRIETARY),
|
||||
UNION(Flags.UNION),
|
||||
OVERRIDE_BRIDGE(Flags.OVERRIDE_BRIDGE),
|
||||
EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL),
|
||||
CLASH(Flags.CLASH),
|
||||
AUXILIARY(Flags.AUXILIARY),
|
||||
NOT_IN_PROFILE(Flags.NOT_IN_PROFILE),
|
||||
BAD_OVERRIDE(Flags.BAD_OVERRIDE),
|
||||
SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
|
||||
THROWS(Flags.THROWS),
|
||||
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
|
||||
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED);
|
||||
|
||||
Flag(long flag) {
|
||||
this.value = flag;
|
||||
this.lowercaseName = StringUtils.toLowerCase(name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return lowercaseName;
|
||||
}
|
||||
|
||||
final long value;
|
||||
final String lowercaseName;
|
||||
}
|
||||
|
||||
}
|
250
jdkSrc/jdk8/com/sun/tools/javac/code/Kinds.java
Normal file
250
jdkSrc/jdk8/com/sun/tools/javac/code/Kinds.java
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.sun.source.tree.MemberReferenceTree;
|
||||
import com.sun.tools.javac.api.Formattable;
|
||||
import com.sun.tools.javac.api.Messages;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.TypeTag.CLASS;
|
||||
import static com.sun.tools.javac.code.TypeTag.PACKAGE;
|
||||
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
|
||||
|
||||
/** Internal symbol kinds, which distinguish between elements of
|
||||
* different subclasses of Symbol. Symbol kinds are organized so they can be
|
||||
* or'ed to sets.
|
||||
*
|
||||
* <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 Kinds {
|
||||
|
||||
private Kinds() {} // uninstantiable
|
||||
|
||||
/** The empty set of kinds.
|
||||
*/
|
||||
public final static int NIL = 0;
|
||||
|
||||
/** The kind of package symbols.
|
||||
*/
|
||||
public final static int PCK = 1 << 0;
|
||||
|
||||
/** The kind of type symbols (classes, interfaces and type variables).
|
||||
*/
|
||||
public final static int TYP = 1 << 1;
|
||||
|
||||
/** The kind of variable symbols.
|
||||
*/
|
||||
public final static int VAR = 1 << 2;
|
||||
|
||||
/** The kind of values (variables or non-variable expressions), includes VAR.
|
||||
*/
|
||||
public final static int VAL = (1 << 3) | VAR;
|
||||
|
||||
/** The kind of methods.
|
||||
*/
|
||||
public final static int MTH = 1 << 4;
|
||||
|
||||
/** Poly kind, for deferred types.
|
||||
*/
|
||||
public final static int POLY = 1 << 5;
|
||||
|
||||
/** The error kind, which includes all other kinds.
|
||||
*/
|
||||
public final static int ERR = (1 << 6) - 1;
|
||||
|
||||
/** The set of all kinds.
|
||||
*/
|
||||
public final static int AllKinds = ERR;
|
||||
|
||||
/** Kinds for erroneous symbols that complement the above
|
||||
*/
|
||||
public static final int ERRONEOUS = 1 << 7;
|
||||
public static final int AMBIGUOUS = ERRONEOUS + 1; // ambiguous reference
|
||||
public static final int HIDDEN = ERRONEOUS + 2; // hidden method or field
|
||||
public static final int STATICERR = ERRONEOUS + 3; // nonstatic member from static context
|
||||
public static final int MISSING_ENCL = ERRONEOUS + 4; // missing enclosing class
|
||||
public static final int ABSENT_VAR = ERRONEOUS + 5; // missing variable
|
||||
public static final int WRONG_MTHS = ERRONEOUS + 6; // methods with wrong arguments
|
||||
public static final int WRONG_MTH = ERRONEOUS + 7; // one method with wrong arguments
|
||||
public static final int ABSENT_MTH = ERRONEOUS + 8; // missing method
|
||||
public static final int ABSENT_TYP = ERRONEOUS + 9; // missing type
|
||||
public static final int WRONG_STATICNESS = ERRONEOUS + 10; // wrong staticness for method references
|
||||
|
||||
public enum KindName implements Formattable {
|
||||
ANNOTATION("kindname.annotation"),
|
||||
CONSTRUCTOR("kindname.constructor"),
|
||||
INTERFACE("kindname.interface"),
|
||||
ENUM("kindname.enum"),
|
||||
STATIC("kindname.static"),
|
||||
TYPEVAR("kindname.type.variable"),
|
||||
BOUND("kindname.type.variable.bound"),
|
||||
VAR("kindname.variable"),
|
||||
VAL("kindname.value"),
|
||||
METHOD("kindname.method"),
|
||||
CLASS("kindname.class"),
|
||||
STATIC_INIT("kindname.static.init"),
|
||||
INSTANCE_INIT("kindname.instance.init"),
|
||||
PACKAGE("kindname.package");
|
||||
|
||||
private final String name;
|
||||
|
||||
KindName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getKind() {
|
||||
return "Kindname";
|
||||
}
|
||||
|
||||
public String toString(Locale locale, Messages messages) {
|
||||
String s = toString();
|
||||
return messages.getLocalizedString(locale, "compiler.misc." + s);
|
||||
}
|
||||
}
|
||||
|
||||
/** A KindName representing a given symbol kind
|
||||
*/
|
||||
public static KindName kindName(int kind) {
|
||||
switch (kind) {
|
||||
case PCK: return KindName.PACKAGE;
|
||||
case TYP: return KindName.CLASS;
|
||||
case VAR: return KindName.VAR;
|
||||
case VAL: return KindName.VAL;
|
||||
case MTH: return KindName.METHOD;
|
||||
default : throw new AssertionError("Unexpected kind: "+kind);
|
||||
}
|
||||
}
|
||||
|
||||
public static KindName kindName(MemberReferenceTree.ReferenceMode mode) {
|
||||
switch (mode) {
|
||||
case INVOKE: return KindName.METHOD;
|
||||
case NEW: return KindName.CONSTRUCTOR;
|
||||
default : throw new AssertionError("Unexpected mode: "+ mode);
|
||||
}
|
||||
}
|
||||
|
||||
/** A KindName representing a given symbol
|
||||
*/
|
||||
public static KindName kindName(Symbol sym) {
|
||||
switch (sym.getKind()) {
|
||||
case PACKAGE:
|
||||
return KindName.PACKAGE;
|
||||
|
||||
case ENUM:
|
||||
return KindName.ENUM;
|
||||
|
||||
case ANNOTATION_TYPE:
|
||||
case CLASS:
|
||||
return KindName.CLASS;
|
||||
|
||||
case INTERFACE:
|
||||
return KindName.INTERFACE;
|
||||
|
||||
case TYPE_PARAMETER:
|
||||
return KindName.TYPEVAR;
|
||||
|
||||
case ENUM_CONSTANT:
|
||||
case FIELD:
|
||||
case PARAMETER:
|
||||
case LOCAL_VARIABLE:
|
||||
case EXCEPTION_PARAMETER:
|
||||
case RESOURCE_VARIABLE:
|
||||
return KindName.VAR;
|
||||
|
||||
case CONSTRUCTOR:
|
||||
return KindName.CONSTRUCTOR;
|
||||
|
||||
case METHOD:
|
||||
return KindName.METHOD;
|
||||
case STATIC_INIT:
|
||||
return KindName.STATIC_INIT;
|
||||
case INSTANCE_INIT:
|
||||
return KindName.INSTANCE_INIT;
|
||||
|
||||
default:
|
||||
if (sym.kind == VAL)
|
||||
// I don't think this can happen but it can't harm
|
||||
// playing it safe --ahe
|
||||
return KindName.VAL;
|
||||
else
|
||||
throw new AssertionError("Unexpected kind: "+sym.getKind());
|
||||
}
|
||||
}
|
||||
|
||||
/** A set of KindName(s) representing a set of symbol's kinds.
|
||||
*/
|
||||
public static EnumSet<KindName> kindNames(int kind) {
|
||||
EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class);
|
||||
if ((kind & VAL) != 0)
|
||||
kinds.add(((kind & VAL) == VAR) ? KindName.VAR : KindName.VAL);
|
||||
if ((kind & MTH) != 0) kinds.add(KindName.METHOD);
|
||||
if ((kind & TYP) != 0) kinds.add(KindName.CLASS);
|
||||
if ((kind & PCK) != 0) kinds.add(KindName.PACKAGE);
|
||||
return kinds;
|
||||
}
|
||||
|
||||
/** A KindName representing the kind of a given class/interface type.
|
||||
*/
|
||||
public static KindName typeKindName(Type t) {
|
||||
if (t.hasTag(TYPEVAR) ||
|
||||
t.hasTag(CLASS) && (t.tsym.flags() & COMPOUND) != 0)
|
||||
return KindName.BOUND;
|
||||
else if (t.hasTag(PACKAGE))
|
||||
return KindName.PACKAGE;
|
||||
else if ((t.tsym.flags_field & ANNOTATION) != 0)
|
||||
return KindName.ANNOTATION;
|
||||
else if ((t.tsym.flags_field & INTERFACE) != 0)
|
||||
return KindName.INTERFACE;
|
||||
else
|
||||
return KindName.CLASS;
|
||||
}
|
||||
|
||||
/** A KindName representing the kind of a missing symbol, given an
|
||||
* error kind.
|
||||
* */
|
||||
public static KindName absentKind(int kind) {
|
||||
switch (kind) {
|
||||
case ABSENT_VAR:
|
||||
return KindName.VAR;
|
||||
case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: case WRONG_STATICNESS:
|
||||
return KindName.METHOD;
|
||||
case ABSENT_TYP:
|
||||
return KindName.CLASS;
|
||||
default:
|
||||
throw new AssertionError("Unexpected kind: "+kind);
|
||||
}
|
||||
}
|
||||
}
|
345
jdkSrc/jdk8/com/sun/tools/javac/code/Lint.java
Normal file
345
jdkSrc/jdk8/com/sun/tools/javac/code/Lint.java
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
import com.sun.tools.javac.util.Pair;
|
||||
|
||||
/**
|
||||
* A class for handling -Xlint suboptions and @SuppresssWarnings.
|
||||
*
|
||||
* <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 Lint
|
||||
{
|
||||
/** The context key for the root Lint object. */
|
||||
protected static final Context.Key<Lint> lintKey = new Context.Key<Lint>();
|
||||
|
||||
/** Get the root Lint instance. */
|
||||
public static Lint instance(Context context) {
|
||||
Lint instance = context.get(lintKey);
|
||||
if (instance == null)
|
||||
instance = new Lint(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of combining the values in this object with
|
||||
* the given annotation.
|
||||
*/
|
||||
public Lint augment(Attribute.Compound attr) {
|
||||
return augmentor.augment(this, attr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the result of combining the values in this object with
|
||||
* the metadata on the given symbol.
|
||||
*/
|
||||
public Lint augment(Symbol sym) {
|
||||
Lint l = augmentor.augment(this, sym.getDeclarationAttributes());
|
||||
if (sym.isDeprecated()) {
|
||||
if (l == this)
|
||||
l = new Lint(this);
|
||||
l.values.remove(LintCategory.DEPRECATION);
|
||||
l.suppressedValues.add(LintCategory.DEPRECATION);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
private final AugmentVisitor augmentor;
|
||||
|
||||
private final EnumSet<LintCategory> values;
|
||||
private final EnumSet<LintCategory> suppressedValues;
|
||||
|
||||
private static final Map<String, LintCategory> map =
|
||||
new java.util.concurrent.ConcurrentHashMap<String, LintCategory>(20);
|
||||
|
||||
protected Lint(Context context) {
|
||||
// initialize values according to the lint options
|
||||
Options options = Options.instance(context);
|
||||
values = EnumSet.noneOf(LintCategory.class);
|
||||
for (Map.Entry<String, LintCategory> e: map.entrySet()) {
|
||||
if (options.lint(e.getKey()))
|
||||
values.add(e.getValue());
|
||||
}
|
||||
|
||||
suppressedValues = EnumSet.noneOf(LintCategory.class);
|
||||
|
||||
context.put(lintKey, this);
|
||||
augmentor = new AugmentVisitor(context);
|
||||
}
|
||||
|
||||
protected Lint(Lint other) {
|
||||
this.augmentor = other.augmentor;
|
||||
this.values = other.values.clone();
|
||||
this.suppressedValues = other.suppressedValues.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Lint:[values" + values + " suppressedValues" + suppressedValues + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Categories of warnings that can be generated by the compiler.
|
||||
*/
|
||||
public enum LintCategory {
|
||||
/**
|
||||
* Warn when code refers to a auxiliary class that is hidden in a source file (ie source file name is
|
||||
* different from the class name, and the type is not properly nested) and the referring code
|
||||
* is not located in the same source file.
|
||||
*/
|
||||
AUXILIARYCLASS("auxiliaryclass"),
|
||||
|
||||
/**
|
||||
* Warn about use of unnecessary casts.
|
||||
*/
|
||||
CAST("cast"),
|
||||
|
||||
/**
|
||||
* Warn about issues related to classfile contents
|
||||
*/
|
||||
CLASSFILE("classfile"),
|
||||
|
||||
/**
|
||||
* Warn about use of deprecated items.
|
||||
*/
|
||||
DEPRECATION("deprecation"),
|
||||
|
||||
/**
|
||||
* Warn about items which are documented with an {@code @deprecated} JavaDoc
|
||||
* comment, but which do not have {@code @Deprecated} annotation.
|
||||
*/
|
||||
DEP_ANN("dep-ann"),
|
||||
|
||||
/**
|
||||
* Warn about division by constant integer 0.
|
||||
*/
|
||||
DIVZERO("divzero"),
|
||||
|
||||
/**
|
||||
* Warn about empty statement after if.
|
||||
*/
|
||||
EMPTY("empty"),
|
||||
|
||||
/**
|
||||
* Warn about falling through from one case of a switch statement to the next.
|
||||
*/
|
||||
FALLTHROUGH("fallthrough"),
|
||||
|
||||
/**
|
||||
* Warn about finally clauses that do not terminate normally.
|
||||
*/
|
||||
FINALLY("finally"),
|
||||
|
||||
/**
|
||||
* Warn about issues relating to use of command line options
|
||||
*/
|
||||
OPTIONS("options"),
|
||||
|
||||
/**
|
||||
* Warn about issues regarding method overloads.
|
||||
*/
|
||||
OVERLOADS("overloads"),
|
||||
|
||||
/**
|
||||
* Warn about issues regarding method overrides.
|
||||
*/
|
||||
OVERRIDES("overrides"),
|
||||
|
||||
/**
|
||||
* Warn about invalid path elements on the command line.
|
||||
* Such warnings cannot be suppressed with the SuppressWarnings
|
||||
* annotation.
|
||||
*/
|
||||
PATH("path"),
|
||||
|
||||
/**
|
||||
* Warn about issues regarding annotation processing.
|
||||
*/
|
||||
PROCESSING("processing"),
|
||||
|
||||
/**
|
||||
* Warn about unchecked operations on raw types.
|
||||
*/
|
||||
RAW("rawtypes"),
|
||||
|
||||
/**
|
||||
* Warn about Serializable classes that do not provide a serial version ID.
|
||||
*/
|
||||
SERIAL("serial"),
|
||||
|
||||
/**
|
||||
* Warn about issues relating to use of statics
|
||||
*/
|
||||
STATIC("static"),
|
||||
|
||||
/**
|
||||
* Warn about proprietary API that may be removed in a future release.
|
||||
*/
|
||||
SUNAPI("sunapi", true),
|
||||
|
||||
/**
|
||||
* Warn about issues relating to use of try blocks (i.e. try-with-resources)
|
||||
*/
|
||||
TRY("try"),
|
||||
|
||||
/**
|
||||
* Warn about unchecked operations on raw types.
|
||||
*/
|
||||
UNCHECKED("unchecked"),
|
||||
|
||||
/**
|
||||
* Warn about potentially unsafe vararg methods
|
||||
*/
|
||||
VARARGS("varargs");
|
||||
|
||||
LintCategory(String option) {
|
||||
this(option, false);
|
||||
}
|
||||
|
||||
LintCategory(String option, boolean hidden) {
|
||||
this.option = option;
|
||||
this.hidden = hidden;
|
||||
map.put(option, this);
|
||||
}
|
||||
|
||||
static LintCategory get(String option) {
|
||||
return map.get(option);
|
||||
}
|
||||
|
||||
public final String option;
|
||||
public final boolean hidden;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a warning category is enabled. A warning category may be enabled
|
||||
* on the command line, or by default, and can be temporarily disabled with
|
||||
* the SuppressWarnings annotation.
|
||||
*/
|
||||
public boolean isEnabled(LintCategory lc) {
|
||||
return values.contains(lc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks is a warning category has been specifically suppressed, by means
|
||||
* of the SuppressWarnings annotation, or, in the case of the deprecated
|
||||
* category, whether it has been implicitly suppressed by virtue of the
|
||||
* current entity being itself deprecated.
|
||||
*/
|
||||
public boolean isSuppressed(LintCategory lc) {
|
||||
return suppressedValues.contains(lc);
|
||||
}
|
||||
|
||||
protected static class AugmentVisitor implements Attribute.Visitor {
|
||||
private final Context context;
|
||||
private Symtab syms;
|
||||
private Lint parent;
|
||||
private Lint lint;
|
||||
|
||||
AugmentVisitor(Context context) {
|
||||
// to break an ugly sequence of initialization dependencies,
|
||||
// we defer the initialization of syms until it is needed
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
Lint augment(Lint parent, Attribute.Compound attr) {
|
||||
initSyms();
|
||||
this.parent = parent;
|
||||
lint = null;
|
||||
attr.accept(this);
|
||||
return (lint == null ? parent : lint);
|
||||
}
|
||||
|
||||
Lint augment(Lint parent, List<Attribute.Compound> attrs) {
|
||||
initSyms();
|
||||
this.parent = parent;
|
||||
lint = null;
|
||||
for (Attribute.Compound a: attrs) {
|
||||
a.accept(this);
|
||||
}
|
||||
return (lint == null ? parent : lint);
|
||||
}
|
||||
|
||||
private void initSyms() {
|
||||
if (syms == null)
|
||||
syms = Symtab.instance(context);
|
||||
}
|
||||
|
||||
private void suppress(LintCategory lc) {
|
||||
if (lint == null)
|
||||
lint = new Lint(parent);
|
||||
lint.suppressedValues.add(lc);
|
||||
lint.values.remove(lc);
|
||||
}
|
||||
|
||||
public void visitConstant(Attribute.Constant value) {
|
||||
if (value.type.tsym == syms.stringType.tsym) {
|
||||
LintCategory lc = LintCategory.get((String) (value.value));
|
||||
if (lc != null)
|
||||
suppress(lc);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitClass(Attribute.Class clazz) {
|
||||
}
|
||||
|
||||
// If we find a @SuppressWarnings annotation, then we continue
|
||||
// walking the tree, in order to suppress the individual warnings
|
||||
// specified in the @SuppressWarnings annotation.
|
||||
public void visitCompound(Attribute.Compound compound) {
|
||||
if (compound.type.tsym == syms.suppressWarningsType.tsym) {
|
||||
for (List<Pair<MethodSymbol,Attribute>> v = compound.values;
|
||||
v.nonEmpty(); v = v.tail) {
|
||||
Pair<MethodSymbol,Attribute> value = v.head;
|
||||
if (value.fst.name.toString().equals("value"))
|
||||
value.snd.accept(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void visitArray(Attribute.Array array) {
|
||||
for (Attribute value : array.values)
|
||||
value.accept(this);
|
||||
}
|
||||
|
||||
public void visitEnum(Attribute.Enum e) {
|
||||
}
|
||||
|
||||
public void visitError(Attribute.Error e) {
|
||||
}
|
||||
};
|
||||
}
|
417
jdkSrc/jdk8/com/sun/tools/javac/code/Printer.java
Normal file
417
jdkSrc/jdk8/com/sun/tools/javac/code/Printer.java
Normal file
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.sun.tools.javac.api.Messages;
|
||||
import com.sun.tools.javac.code.Type.AnnotatedType;
|
||||
import com.sun.tools.javac.code.Type.ArrayType;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
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.CLASS;
|
||||
import static com.sun.tools.javac.code.TypeTag.FORALL;
|
||||
|
||||
/**
|
||||
* A combined type/symbol visitor for generating non-trivial localized string
|
||||
* representation of types and symbols.
|
||||
*
|
||||
* <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 Printer implements Type.Visitor<String, Locale>, Symbol.Visitor<String, Locale> {
|
||||
|
||||
List<Type> seenCaptured = List.nil();
|
||||
static final int PRIME = 997; // largest prime less than 1000
|
||||
|
||||
protected Printer() { }
|
||||
|
||||
/**
|
||||
* This method should be overriden in order to provide proper i18n support.
|
||||
*
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @param key the key corresponding to the message to be displayed
|
||||
* @param args a list of optional arguments
|
||||
* @return localized string representation
|
||||
*/
|
||||
protected abstract String localize(Locale locale, String key, Object... args);
|
||||
|
||||
/**
|
||||
* Maps a captured type into an unique identifier.
|
||||
*
|
||||
* @param t the captured type for which an id is to be retrieved
|
||||
* @param locale locale settings
|
||||
* @return unique id representing this captured type
|
||||
*/
|
||||
protected abstract String capturedVarId(CapturedType t, Locale locale);
|
||||
|
||||
/**
|
||||
* Create a printer with default i18n support provided by Messages. By default,
|
||||
* captured types ids are generated using hashcode.
|
||||
*
|
||||
* @param messages Messages class to be used for i18n
|
||||
* @return printer visitor instance
|
||||
*/
|
||||
public static Printer createStandardPrinter(final Messages messages) {
|
||||
return new Printer() {
|
||||
@Override
|
||||
protected String localize(Locale locale, String key, Object... args) {
|
||||
return messages.getLocalizedString(locale, key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String capturedVarId(CapturedType t, Locale locale) {
|
||||
return (t.hashCode() & 0xFFFFFFFFL) % PRIME + "";
|
||||
}};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a localized string representation for all the types in the input list.
|
||||
*
|
||||
* @param ts types to be displayed
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @return localized string representation
|
||||
*/
|
||||
public String visitTypes(List<Type> ts, Locale locale) {
|
||||
ListBuffer<String> sbuf = new ListBuffer<>();
|
||||
for (Type t : ts) {
|
||||
sbuf.append(visit(t, locale));
|
||||
}
|
||||
return sbuf.toList().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* * Get a localized string representation for all the symbols in the input list.
|
||||
*
|
||||
* @param ts symbols to be displayed
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @return localized string representation
|
||||
*/
|
||||
public String visitSymbols(List<Symbol> ts, Locale locale) {
|
||||
ListBuffer<String> sbuf = new ListBuffer<>();
|
||||
for (Symbol t : ts) {
|
||||
sbuf.append(visit(t, locale));
|
||||
}
|
||||
return sbuf.toList().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a localized string representation for a given type.
|
||||
*
|
||||
* @param t type to be displayed
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @return localized string representation
|
||||
*/
|
||||
public String visit(Type t, Locale locale) {
|
||||
return t.accept(this, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a localized string representation for a given symbol.
|
||||
*
|
||||
* @param s symbol to be displayed
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @return localized string representation
|
||||
*/
|
||||
public String visit(Symbol s, Locale locale) {
|
||||
return s.accept(this, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
||||
if (seenCaptured.contains(t))
|
||||
return localize(locale, "compiler.misc.type.captureof.1",
|
||||
capturedVarId(t, locale));
|
||||
else {
|
||||
try {
|
||||
seenCaptured = seenCaptured.prepend(t);
|
||||
return localize(locale, "compiler.misc.type.captureof",
|
||||
capturedVarId(t, locale),
|
||||
visit(t.wildcard, locale));
|
||||
}
|
||||
finally {
|
||||
seenCaptured = seenCaptured.tail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitForAll(ForAll t, Locale locale) {
|
||||
return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitUndetVar(UndetVar t, Locale locale) {
|
||||
if (t.inst != null) {
|
||||
return visit(t.inst, locale);
|
||||
} else {
|
||||
return visit(t.qtype, locale) + "?";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitArrayType(ArrayType t, Locale locale) {
|
||||
StringBuilder res = new StringBuilder();
|
||||
printBaseElementType(t, res, locale);
|
||||
printBrackets(t, res, locale);
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
|
||||
Type arrel = t;
|
||||
while (arrel.hasTag(TypeTag.ARRAY)) {
|
||||
arrel = arrel.unannotatedType();
|
||||
arrel = ((ArrayType) arrel).elemtype;
|
||||
}
|
||||
sb.append(visit(arrel, locale));
|
||||
}
|
||||
|
||||
void printBrackets(Type t, StringBuilder sb, Locale locale) {
|
||||
Type arrel = t;
|
||||
while (arrel.hasTag(TypeTag.ARRAY)) {
|
||||
if (arrel.isAnnotated()) {
|
||||
sb.append(' ');
|
||||
sb.append(arrel.getAnnotationMirrors());
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append("[]");
|
||||
arrel = arrel.unannotatedType();
|
||||
arrel = ((ArrayType) arrel).elemtype;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClassType(ClassType t, Locale locale) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (t.getEnclosingType().hasTag(CLASS) && t.tsym.owner.kind == Kinds.TYP) {
|
||||
buf.append(visit(t.getEnclosingType(), locale));
|
||||
buf.append('.');
|
||||
buf.append(className(t, false, locale));
|
||||
} else {
|
||||
buf.append(className(t, true, locale));
|
||||
}
|
||||
if (t.getTypeArguments().nonEmpty()) {
|
||||
buf.append('<');
|
||||
buf.append(visitTypes(t.getTypeArguments(), locale));
|
||||
buf.append('>');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitMethodType(MethodType t, Locale locale) {
|
||||
return "(" + printMethodArgs(t.argtypes, false, locale) + ")" + visit(t.restype, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPackageType(PackageType t, Locale locale) {
|
||||
return t.tsym.getQualifiedName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitWildcardType(WildcardType t, Locale locale) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(t.kind);
|
||||
if (t.kind != UNBOUND) {
|
||||
s.append(visit(t.type, locale));
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitErrorType(ErrorType t, Locale locale) {
|
||||
return visitType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeVar(TypeVar t, Locale locale) {
|
||||
return visitType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
|
||||
if (t.getAnnotationMirrors().nonEmpty()) {
|
||||
if (t.unannotatedType().hasTag(TypeTag.ARRAY)) {
|
||||
StringBuilder res = new StringBuilder();
|
||||
printBaseElementType(t, res, locale);
|
||||
printBrackets(t, res, locale);
|
||||
return res.toString();
|
||||
} else if (t.unannotatedType().hasTag(TypeTag.CLASS) &&
|
||||
t.unannotatedType().getEnclosingType() != Type.noType) {
|
||||
return visit(t.unannotatedType().getEnclosingType(), locale) +
|
||||
". " +
|
||||
t.getAnnotationMirrors() +
|
||||
" " + className((ClassType)t.unannotatedType(), false, locale);
|
||||
} else {
|
||||
return t.getAnnotationMirrors() + " " + visit(t.unannotatedType(), locale);
|
||||
}
|
||||
} else {
|
||||
return visit(t.unannotatedType(), locale);
|
||||
}
|
||||
}
|
||||
|
||||
public String visitType(Type t, Locale locale) {
|
||||
String s = (t.tsym == null || t.tsym.name == null)
|
||||
? localize(locale, "compiler.misc.type.none")
|
||||
: t.tsym.name.toString();
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a class name into a (possibly localized) string. Anonymous
|
||||
* inner classes get converted into a localized string.
|
||||
*
|
||||
* @param t the type of the class whose name is to be rendered
|
||||
* @param longform if set, the class' fullname is displayed - if unset the
|
||||
* short name is chosen (w/o package)
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @return localized string representation
|
||||
*/
|
||||
protected String className(ClassType t, boolean longform, Locale locale) {
|
||||
Symbol sym = t.tsym;
|
||||
if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
|
||||
StringBuilder s = new StringBuilder(visit(t.supertype_field, locale));
|
||||
for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
|
||||
s.append('&');
|
||||
s.append(visit(is.head, locale));
|
||||
}
|
||||
return s.toString();
|
||||
} else if (sym.name.length() == 0) {
|
||||
String s;
|
||||
ClassType norm = (ClassType) t.tsym.type;
|
||||
if (norm == null) {
|
||||
s = localize(locale, "compiler.misc.anonymous.class", (Object) null);
|
||||
} else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
|
||||
s = localize(locale, "compiler.misc.anonymous.class",
|
||||
visit(norm.interfaces_field.head, locale));
|
||||
} else {
|
||||
s = localize(locale, "compiler.misc.anonymous.class",
|
||||
visit(norm.supertype_field, locale));
|
||||
}
|
||||
return s;
|
||||
} else if (longform) {
|
||||
return sym.getQualifiedName().toString();
|
||||
} else {
|
||||
return sym.name.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a set of method argument types into their corresponding
|
||||
* localized string representation.
|
||||
*
|
||||
* @param args arguments to be rendered
|
||||
* @param varArgs if true, the last method argument is regarded as a vararg
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
* @return localized string representation
|
||||
*/
|
||||
protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
|
||||
if (!varArgs) {
|
||||
return visitTypes(args, locale);
|
||||
} else {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
while (args.tail.nonEmpty()) {
|
||||
buf.append(visit(args.head, locale));
|
||||
args = args.tail;
|
||||
buf.append(',');
|
||||
}
|
||||
if (args.head.unannotatedType().hasTag(TypeTag.ARRAY)) {
|
||||
buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
|
||||
if (args.head.getAnnotationMirrors().nonEmpty()) {
|
||||
buf.append(' ');
|
||||
buf.append(args.head.getAnnotationMirrors());
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append("...");
|
||||
} else {
|
||||
buf.append(visit(args.head, locale));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClassSymbol(ClassSymbol sym, Locale locale) {
|
||||
return sym.name.isEmpty()
|
||||
? localize(locale, "compiler.misc.anonymous.class", sym.flatname)
|
||||
: sym.fullname.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitMethodSymbol(MethodSymbol s, Locale locale) {
|
||||
if (s.isStaticOrInstanceInit()) {
|
||||
return s.owner.name.toString();
|
||||
} else {
|
||||
String ms = (s.name == s.name.table.names.init)
|
||||
? s.owner.name.toString()
|
||||
: s.name.toString();
|
||||
if (s.type != null) {
|
||||
if (s.type.hasTag(FORALL)) {
|
||||
ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
|
||||
}
|
||||
ms += "(" + printMethodArgs(
|
||||
s.type.getParameterTypes(),
|
||||
(s.flags() & VARARGS) != 0,
|
||||
locale) + ")";
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitOperatorSymbol(OperatorSymbol s, Locale locale) {
|
||||
return visitMethodSymbol(s, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPackageSymbol(PackageSymbol s, Locale locale) {
|
||||
return s.isUnnamed()
|
||||
? localize(locale, "compiler.misc.unnamed.package")
|
||||
: s.fullname.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeSymbol(TypeSymbol s, Locale locale) {
|
||||
return visitSymbol(s, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitVarSymbol(VarSymbol s, Locale locale) {
|
||||
return visitSymbol(s, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitSymbol(Symbol s, Locale locale) {
|
||||
return s.name.toString();
|
||||
}
|
||||
}
|
766
jdkSrc/jdk8/com/sun/tools/javac/code/Scope.java
Normal file
766
jdkSrc/jdk8/com/sun/tools/javac/code/Scope.java
Normal file
@@ -0,0 +1,766 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, 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.javac.code;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
/** A scope represents an area of visibility in a Java program. The
|
||||
* Scope class is a container for symbols which provides
|
||||
* efficient access to symbols given their names. Scopes are implemented
|
||||
* as hash tables with "open addressing" and "double hashing".
|
||||
* Scopes can be nested; the next field of a scope points
|
||||
* to its next outer scope. Nested scopes can share their hash tables.
|
||||
*
|
||||
* <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 Scope {
|
||||
|
||||
/** The number of scopes that share this scope's hash table.
|
||||
*/
|
||||
private int shared;
|
||||
|
||||
/** Next enclosing scope (with whom this scope may share a hashtable)
|
||||
*/
|
||||
public Scope next;
|
||||
|
||||
/** The scope's owner.
|
||||
*/
|
||||
public Symbol owner;
|
||||
|
||||
/** A hash table for the scope's entries.
|
||||
*/
|
||||
Entry[] table;
|
||||
|
||||
/** Mask for hash codes, always equal to (table.length - 1).
|
||||
*/
|
||||
int hashMask;
|
||||
|
||||
/** A linear list that also contains all entries in
|
||||
* reverse order of appearance (i.e later entries are pushed on top).
|
||||
*/
|
||||
public Entry elems;
|
||||
|
||||
/** The number of elements in this scope.
|
||||
* This includes deleted elements, whose value is the sentinel.
|
||||
*/
|
||||
int nelems = 0;
|
||||
|
||||
/** A list of scopes to be notified if items are to be removed from this scope.
|
||||
*/
|
||||
List<ScopeListener> listeners = List.nil();
|
||||
|
||||
/** Use as a "not-found" result for lookup.
|
||||
* Also used to mark deleted entries in the table.
|
||||
*/
|
||||
private static final Entry sentinel = new Entry(null, null, null, null);
|
||||
|
||||
/** The hash table's initial size.
|
||||
*/
|
||||
private static final int INITIAL_SIZE = 0x10;
|
||||
|
||||
/** A value for the empty scope.
|
||||
*/
|
||||
public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
|
||||
|
||||
/** Construct a new scope, within scope next, with given owner, using
|
||||
* given table. The table's length must be an exponent of 2.
|
||||
*/
|
||||
private Scope(Scope next, Symbol owner, Entry[] table) {
|
||||
this.next = next;
|
||||
Assert.check(emptyScope == null || owner != null);
|
||||
this.owner = owner;
|
||||
this.table = table;
|
||||
this.hashMask = table.length - 1;
|
||||
}
|
||||
|
||||
/** Convenience constructor used for dup and dupUnshared. */
|
||||
private Scope(Scope next, Symbol owner, Entry[] table, int nelems) {
|
||||
this(next, owner, table);
|
||||
this.nelems = nelems;
|
||||
}
|
||||
|
||||
/** Construct a new scope, within scope next, with given owner,
|
||||
* using a fresh table of length INITIAL_SIZE.
|
||||
*/
|
||||
public Scope(Symbol owner) {
|
||||
this(null, owner, new Entry[INITIAL_SIZE]);
|
||||
}
|
||||
|
||||
/** Construct a fresh scope within this scope, with same owner,
|
||||
* which shares its table with the outer scope. Used in connection with
|
||||
* method leave if scope access is stack-like in order to avoid allocation
|
||||
* of fresh tables.
|
||||
*/
|
||||
public Scope dup() {
|
||||
return dup(this.owner);
|
||||
}
|
||||
|
||||
/** Construct a fresh scope within this scope, with new owner,
|
||||
* which shares its table with the outer scope. Used in connection with
|
||||
* method leave if scope access is stack-like in order to avoid allocation
|
||||
* of fresh tables.
|
||||
*/
|
||||
public Scope dup(Symbol newOwner) {
|
||||
Scope result = new Scope(this, newOwner, this.table, this.nelems);
|
||||
shared++;
|
||||
// System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
|
||||
// new Error().printStackTrace(System.out);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Construct a fresh scope within this scope, with same owner,
|
||||
* with a new hash table, whose contents initially are those of
|
||||
* the table of its outer scope.
|
||||
*/
|
||||
public Scope dupUnshared() {
|
||||
return new Scope(this, this.owner, this.table.clone(), this.nelems);
|
||||
}
|
||||
|
||||
/** Remove all entries of this scope from its table, if shared
|
||||
* with next.
|
||||
*/
|
||||
public Scope leave() {
|
||||
Assert.check(shared == 0);
|
||||
if (table != next.table) return next;
|
||||
while (elems != null) {
|
||||
int hash = getIndex(elems.sym.name);
|
||||
Entry e = table[hash];
|
||||
Assert.check(e == elems, elems.sym);
|
||||
table[hash] = elems.shadowed;
|
||||
elems = elems.sibling;
|
||||
}
|
||||
Assert.check(next.shared > 0);
|
||||
next.shared--;
|
||||
next.nelems = nelems;
|
||||
// System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
|
||||
// new Error().printStackTrace(System.out);
|
||||
return next;
|
||||
}
|
||||
|
||||
/** Double size of hash table.
|
||||
*/
|
||||
private void dble() {
|
||||
Assert.check(shared == 0);
|
||||
Entry[] oldtable = table;
|
||||
Entry[] newtable = new Entry[oldtable.length * 2];
|
||||
for (Scope s = this; s != null; s = s.next) {
|
||||
if (s.table == oldtable) {
|
||||
Assert.check(s == this || s.shared != 0);
|
||||
s.table = newtable;
|
||||
s.hashMask = newtable.length - 1;
|
||||
}
|
||||
}
|
||||
int n = 0;
|
||||
for (int i = oldtable.length; --i >= 0; ) {
|
||||
Entry e = oldtable[i];
|
||||
if (e != null && e != sentinel) {
|
||||
table[getIndex(e.sym.name)] = e;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
// We don't need to update nelems for shared inherited scopes,
|
||||
// since that gets handled by leave().
|
||||
nelems = n;
|
||||
}
|
||||
|
||||
/** Enter symbol sym in this scope.
|
||||
*/
|
||||
public void enter(Symbol sym) {
|
||||
Assert.check(shared == 0);
|
||||
enter(sym, this);
|
||||
}
|
||||
|
||||
public void enter(Symbol sym, Scope s) {
|
||||
enter(sym, s, s, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter symbol sym in this scope, but mark that it comes from
|
||||
* given scope `s' accessed through `origin'. The last two
|
||||
* arguments are only used in import scopes.
|
||||
*/
|
||||
public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
|
||||
Assert.check(shared == 0);
|
||||
if (nelems * 3 >= hashMask * 2)
|
||||
dble();
|
||||
int hash = getIndex(sym.name);
|
||||
Entry old = table[hash];
|
||||
if (old == null) {
|
||||
old = sentinel;
|
||||
nelems++;
|
||||
}
|
||||
Entry e = makeEntry(sym, old, elems, s, origin, staticallyImported);
|
||||
table[hash] = e;
|
||||
elems = e;
|
||||
|
||||
//notify listeners
|
||||
for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
|
||||
l.head.symbolAdded(sym, this);
|
||||
}
|
||||
}
|
||||
|
||||
Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin, boolean staticallyImported) {
|
||||
return new Entry(sym, shadowed, sibling, scope);
|
||||
}
|
||||
|
||||
|
||||
public interface ScopeListener {
|
||||
public void symbolAdded(Symbol sym, Scope s);
|
||||
public void symbolRemoved(Symbol sym, Scope s);
|
||||
}
|
||||
|
||||
public void addScopeListener(ScopeListener sl) {
|
||||
listeners = listeners.prepend(sl);
|
||||
}
|
||||
|
||||
/** Remove symbol from this scope.
|
||||
*/
|
||||
public void remove(final Symbol sym) {
|
||||
Assert.check(shared == 0);
|
||||
Entry e = lookup(sym.name, new Filter<Symbol>() {
|
||||
@Override
|
||||
public boolean accepts(Symbol candidate) {
|
||||
return candidate == sym;
|
||||
}
|
||||
});
|
||||
if (e.scope == null) return;
|
||||
|
||||
// remove e from table and shadowed list;
|
||||
int i = getIndex(sym.name);
|
||||
Entry te = table[i];
|
||||
if (te == e)
|
||||
table[i] = e.shadowed;
|
||||
else while (true) {
|
||||
if (te.shadowed == e) {
|
||||
te.shadowed = e.shadowed;
|
||||
break;
|
||||
}
|
||||
te = te.shadowed;
|
||||
}
|
||||
|
||||
// remove e from elems and sibling list
|
||||
te = elems;
|
||||
if (te == e)
|
||||
elems = e.sibling;
|
||||
else while (true) {
|
||||
if (te.sibling == e) {
|
||||
te.sibling = e.sibling;
|
||||
break;
|
||||
}
|
||||
te = te.sibling;
|
||||
}
|
||||
|
||||
//notify listeners
|
||||
for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
|
||||
l.head.symbolRemoved(sym, this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Enter symbol sym in this scope if not already there.
|
||||
*/
|
||||
public void enterIfAbsent(Symbol sym) {
|
||||
Assert.check(shared == 0);
|
||||
Entry e = lookup(sym.name);
|
||||
while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
|
||||
if (e.scope != this) enter(sym);
|
||||
}
|
||||
|
||||
/** Given a class, is there already a class with same fully
|
||||
* qualified name in this (import) scope?
|
||||
*/
|
||||
public boolean includes(Symbol c) {
|
||||
for (Scope.Entry e = lookup(c.name);
|
||||
e.scope == this;
|
||||
e = e.next()) {
|
||||
if (e.sym == c) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static final Filter<Symbol> noFilter = new Filter<Symbol>() {
|
||||
public boolean accepts(Symbol s) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** Return the entry associated with given name, starting in
|
||||
* this scope and proceeding outwards. If no entry was found,
|
||||
* return the sentinel, which is characterized by having a null in
|
||||
* both its scope and sym fields, whereas both fields are non-null
|
||||
* for regular entries.
|
||||
*/
|
||||
public Entry lookup(Name name) {
|
||||
return lookup(name, noFilter);
|
||||
}
|
||||
|
||||
public Entry lookup(Name name, Filter<Symbol> sf) {
|
||||
Entry e = table[getIndex(name)];
|
||||
if (e == null || e == sentinel)
|
||||
return sentinel;
|
||||
while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
|
||||
e = e.shadowed;
|
||||
return e;
|
||||
}
|
||||
|
||||
/*void dump (java.io.PrintStream out) {
|
||||
out.println(this);
|
||||
for (int l=0; l < table.length; l++) {
|
||||
Entry le = table[l];
|
||||
out.print("#"+l+": ");
|
||||
if (le==sentinel) out.println("sentinel");
|
||||
else if(le == null) out.println("null");
|
||||
else out.println(""+le+" s:"+le.sym);
|
||||
}
|
||||
}*/
|
||||
|
||||
/** Look for slot in the table.
|
||||
* We use open addressing with double hashing.
|
||||
*/
|
||||
int getIndex (Name name) {
|
||||
int h = name.hashCode();
|
||||
int i = h & hashMask;
|
||||
// The expression below is always odd, so it is guaranteed
|
||||
// to be mutually prime with table.length, a power of 2.
|
||||
int x = hashMask - ((h + (h >> 16)) << 1);
|
||||
int d = -1; // Index of a deleted item.
|
||||
for (;;) {
|
||||
Entry e = table[i];
|
||||
if (e == null)
|
||||
return d >= 0 ? d : i;
|
||||
if (e == sentinel) {
|
||||
// We have to keep searching even if we see a deleted item.
|
||||
// However, remember the index in case we fail to find the name.
|
||||
if (d < 0)
|
||||
d = i;
|
||||
} else if (e.sym.name == name)
|
||||
return i;
|
||||
i = (i + x) & hashMask;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean anyMatch(Filter<Symbol> sf) {
|
||||
return getElements(sf).iterator().hasNext();
|
||||
}
|
||||
|
||||
public Iterable<Symbol> getElements() {
|
||||
return getElements(noFilter);
|
||||
}
|
||||
|
||||
public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
|
||||
return new Iterable<Symbol>() {
|
||||
public Iterator<Symbol> iterator() {
|
||||
return new Iterator<Symbol>() {
|
||||
private Scope currScope = Scope.this;
|
||||
private Scope.Entry currEntry = elems;
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return currEntry != null;
|
||||
}
|
||||
|
||||
public Symbol next() {
|
||||
Symbol sym = (currEntry == null ? null : currEntry.sym);
|
||||
if (currEntry != null) {
|
||||
currEntry = currEntry.sibling;
|
||||
}
|
||||
update();
|
||||
return sym;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
skipToNextMatchingEntry();
|
||||
while (currEntry == null && currScope.next != null) {
|
||||
currScope = currScope.next;
|
||||
currEntry = currScope.elems;
|
||||
skipToNextMatchingEntry();
|
||||
}
|
||||
}
|
||||
|
||||
void skipToNextMatchingEntry() {
|
||||
while (currEntry != null && !sf.accepts(currEntry.sym)) {
|
||||
currEntry = currEntry.sibling;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Iterable<Symbol> getElementsByName(Name name) {
|
||||
return getElementsByName(name, noFilter);
|
||||
}
|
||||
|
||||
public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
|
||||
return new Iterable<Symbol>() {
|
||||
public Iterator<Symbol> iterator() {
|
||||
return new Iterator<Symbol>() {
|
||||
Scope.Entry currentEntry = lookup(name, sf);
|
||||
|
||||
public boolean hasNext() {
|
||||
return currentEntry.scope != null;
|
||||
}
|
||||
public Symbol next() {
|
||||
Scope.Entry prevEntry = currentEntry;
|
||||
currentEntry = currentEntry.next(sf);
|
||||
return prevEntry.sym;
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("Scope[");
|
||||
for (Scope s = this; s != null ; s = s.next) {
|
||||
if (s != this) result.append(" | ");
|
||||
for (Entry e = s.elems; e != null; e = e.sibling) {
|
||||
if (e != s.elems) result.append(", ");
|
||||
result.append(e.sym);
|
||||
}
|
||||
}
|
||||
result.append("]");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/** A class for scope entries.
|
||||
*/
|
||||
public static class Entry {
|
||||
|
||||
/** The referenced symbol.
|
||||
* sym == null iff this == sentinel
|
||||
*/
|
||||
public Symbol sym;
|
||||
|
||||
/** An entry with the same hash code, or sentinel.
|
||||
*/
|
||||
private Entry shadowed;
|
||||
|
||||
/** Next entry in same scope.
|
||||
*/
|
||||
public Entry sibling;
|
||||
|
||||
/** The entry's scope.
|
||||
* scope == null iff this == sentinel
|
||||
* for an entry in an import scope, this is the scope
|
||||
* where the entry came from (i.e. was imported from).
|
||||
*/
|
||||
public Scope scope;
|
||||
|
||||
public Entry(Symbol sym, Entry shadowed, Entry sibling, Scope scope) {
|
||||
this.sym = sym;
|
||||
this.shadowed = shadowed;
|
||||
this.sibling = sibling;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/** Return next entry with the same name as this entry, proceeding
|
||||
* outwards if not found in this scope.
|
||||
*/
|
||||
public Entry next() {
|
||||
return shadowed;
|
||||
}
|
||||
|
||||
public Entry next(Filter<Symbol> sf) {
|
||||
if (shadowed.sym == null || sf.accepts(shadowed.sym)) return shadowed;
|
||||
else return shadowed.next(sf);
|
||||
}
|
||||
|
||||
public boolean isStaticallyImported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Scope getOrigin() {
|
||||
// The origin is only recorded for import scopes. For all
|
||||
// other scope entries, the "enclosing" type is available
|
||||
// from other sources. See Attr.visitSelect and
|
||||
// Attr.visitIdent. Rather than throwing an assertion
|
||||
// error, we return scope which will be the same as origin
|
||||
// in many cases.
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ImportScope extends Scope {
|
||||
|
||||
public ImportScope(Symbol owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope,
|
||||
final Scope origin, final boolean staticallyImported) {
|
||||
return new Entry(sym, shadowed, sibling, scope) {
|
||||
@Override
|
||||
public Scope getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStaticallyImported() {
|
||||
return staticallyImported;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class StarImportScope extends ImportScope implements ScopeListener {
|
||||
|
||||
public StarImportScope(Symbol owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
public void importAll (Scope fromScope) {
|
||||
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
|
||||
if (e.sym.kind == Kinds.TYP && !includes(e.sym))
|
||||
enter(e.sym, fromScope);
|
||||
}
|
||||
// Register to be notified when imported items are removed
|
||||
fromScope.addScopeListener(this);
|
||||
}
|
||||
|
||||
public void symbolRemoved(Symbol sym, Scope s) {
|
||||
remove(sym);
|
||||
}
|
||||
public void symbolAdded(Symbol sym, Scope s) { }
|
||||
}
|
||||
|
||||
/** An empty scope, into which you can't place anything. Used for
|
||||
* the scope for a variable initializer.
|
||||
*/
|
||||
public static class DelegatedScope extends Scope {
|
||||
Scope delegatee;
|
||||
public static final Entry[] emptyTable = new Entry[0];
|
||||
|
||||
public DelegatedScope(Scope outer) {
|
||||
super(outer, outer.owner, emptyTable);
|
||||
delegatee = outer;
|
||||
}
|
||||
public Scope dup() {
|
||||
return new DelegatedScope(next);
|
||||
}
|
||||
public Scope dupUnshared() {
|
||||
return new DelegatedScope(next);
|
||||
}
|
||||
public Scope leave() {
|
||||
return next;
|
||||
}
|
||||
public void enter(Symbol sym) {
|
||||
// only anonymous classes could be put here
|
||||
}
|
||||
public void enter(Symbol sym, Scope s) {
|
||||
// only anonymous classes could be put here
|
||||
}
|
||||
public void remove(Symbol sym) {
|
||||
throw new AssertionError(sym);
|
||||
}
|
||||
public Entry lookup(Name name) {
|
||||
return delegatee.lookup(name);
|
||||
}
|
||||
}
|
||||
|
||||
/** A class scope adds capabilities to keep track of changes in related
|
||||
* class scopes - this allows client to realize whether a class scope
|
||||
* has changed, either directly (because a new member has been added/removed
|
||||
* to this scope) or indirectly (i.e. because a new member has been
|
||||
* added/removed into a supertype scope)
|
||||
*/
|
||||
public static class CompoundScope extends Scope implements ScopeListener {
|
||||
|
||||
public static final Entry[] emptyTable = new Entry[0];
|
||||
|
||||
private List<Scope> subScopes = List.nil();
|
||||
private int mark = 0;
|
||||
|
||||
public CompoundScope(Symbol owner) {
|
||||
super(null, owner, emptyTable);
|
||||
}
|
||||
|
||||
public void addSubScope(Scope that) {
|
||||
if (that != null) {
|
||||
subScopes = subScopes.prepend(that);
|
||||
that.addScopeListener(this);
|
||||
mark++;
|
||||
for (ScopeListener sl : listeners) {
|
||||
sl.symbolAdded(null, this); //propagate upwards in case of nested CompoundScopes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void symbolAdded(Symbol sym, Scope s) {
|
||||
mark++;
|
||||
for (ScopeListener sl : listeners) {
|
||||
sl.symbolAdded(sym, s);
|
||||
}
|
||||
}
|
||||
|
||||
public void symbolRemoved(Symbol sym, Scope s) {
|
||||
mark++;
|
||||
for (ScopeListener sl : listeners) {
|
||||
sl.symbolRemoved(sym, s);
|
||||
}
|
||||
}
|
||||
|
||||
public int getMark() {
|
||||
return mark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("CompoundScope{");
|
||||
String sep = "";
|
||||
for (Scope s : subScopes) {
|
||||
buf.append(sep);
|
||||
buf.append(s);
|
||||
sep = ",";
|
||||
}
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
|
||||
return new Iterable<Symbol>() {
|
||||
public Iterator<Symbol> iterator() {
|
||||
return new CompoundScopeIterator(subScopes) {
|
||||
Iterator<Symbol> nextIterator(Scope s) {
|
||||
return s.getElements(sf).iterator();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
|
||||
return new Iterable<Symbol>() {
|
||||
public Iterator<Symbol> iterator() {
|
||||
return new CompoundScopeIterator(subScopes) {
|
||||
Iterator<Symbol> nextIterator(Scope s) {
|
||||
return s.getElementsByName(name, sf).iterator();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
abstract class CompoundScopeIterator implements Iterator<Symbol> {
|
||||
|
||||
private Iterator<Symbol> currentIterator;
|
||||
private List<Scope> scopesToScan;
|
||||
|
||||
public CompoundScopeIterator(List<Scope> scopesToScan) {
|
||||
this.scopesToScan = scopesToScan;
|
||||
update();
|
||||
}
|
||||
|
||||
abstract Iterator<Symbol> nextIterator(Scope s);
|
||||
|
||||
public boolean hasNext() {
|
||||
return currentIterator != null;
|
||||
}
|
||||
|
||||
public Symbol next() {
|
||||
Symbol sym = currentIterator.next();
|
||||
if (!currentIterator.hasNext()) {
|
||||
update();
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
while (scopesToScan.nonEmpty()) {
|
||||
currentIterator = nextIterator(scopesToScan.head);
|
||||
scopesToScan = scopesToScan.tail;
|
||||
if (currentIterator.hasNext()) return;
|
||||
}
|
||||
currentIterator = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry lookup(Name name, Filter<Symbol> sf) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope dup(Symbol newOwner) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Symbol sym) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/** An error scope, for which the owner should be an error symbol. */
|
||||
public static class ErrorScope extends Scope {
|
||||
ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
|
||||
super(next, /*owner=*/errSymbol, table);
|
||||
}
|
||||
public ErrorScope(Symbol errSymbol) {
|
||||
super(errSymbol);
|
||||
}
|
||||
public Scope dup() {
|
||||
return new ErrorScope(this, owner, table);
|
||||
}
|
||||
public Scope dupUnshared() {
|
||||
return new ErrorScope(this, owner, table.clone());
|
||||
}
|
||||
public Entry lookup(Name name) {
|
||||
Entry e = super.lookup(name);
|
||||
if (e.scope == null)
|
||||
return new Entry(owner, null, null, null);
|
||||
else
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
259
jdkSrc/jdk8/com/sun/tools/javac/code/Source.java
Normal file
259
jdkSrc/jdk8/com/sun/tools/javac/code/Source.java
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2014, 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.javac.code;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
import static javax.lang.model.SourceVersion.*;
|
||||
|
||||
import com.sun.tools.javac.jvm.Target;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
|
||||
/** The source language version accepted.
|
||||
*
|
||||
* <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 enum Source {
|
||||
/** 1.0 had no inner classes, and so could not pass the JCK. */
|
||||
// public static final Source JDK1_0 = new Source("1.0");
|
||||
|
||||
/** 1.1 did not have strictfp, and so could not pass the JCK. */
|
||||
// public static final Source JDK1_1 = new Source("1.1");
|
||||
|
||||
/** 1.2 introduced strictfp. */
|
||||
JDK1_2("1.2"),
|
||||
|
||||
/** 1.3 is the same language as 1.2. */
|
||||
JDK1_3("1.3"),
|
||||
|
||||
/** 1.4 introduced assert. */
|
||||
JDK1_4("1.4"),
|
||||
|
||||
/** 1.5 introduced generics, attributes, foreach, boxing, static import,
|
||||
* covariant return, enums, varargs, et al. */
|
||||
JDK1_5("1.5"),
|
||||
|
||||
/** 1.6 reports encoding problems as errors instead of warnings. */
|
||||
JDK1_6("1.6"),
|
||||
|
||||
/** 1.7 introduced try-with-resources, multi-catch, string switch, etc. */
|
||||
JDK1_7("1.7"),
|
||||
|
||||
/** 1.8 covers the to be determined language features that will be added in JDK 8. */
|
||||
JDK1_8("1.8");
|
||||
|
||||
private static final Context.Key<Source> sourceKey
|
||||
= new Context.Key<Source>();
|
||||
|
||||
public static Source instance(Context context) {
|
||||
Source instance = context.get(sourceKey);
|
||||
if (instance == null) {
|
||||
Options options = Options.instance(context);
|
||||
String sourceString = options.get(SOURCE);
|
||||
if (sourceString != null) instance = lookup(sourceString);
|
||||
if (instance == null) instance = DEFAULT;
|
||||
context.put(sourceKey, instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public final String name;
|
||||
|
||||
private static final Map<String,Source> tab = new HashMap<String,Source>();
|
||||
static {
|
||||
for (Source s : values()) {
|
||||
tab.put(s.name, s);
|
||||
}
|
||||
tab.put("5", JDK1_5); // Make 5 an alias for 1.5
|
||||
tab.put("6", JDK1_6); // Make 6 an alias for 1.6
|
||||
tab.put("7", JDK1_7); // Make 7 an alias for 1.7
|
||||
tab.put("8", JDK1_8); // Make 8 an alias for 1.8
|
||||
}
|
||||
|
||||
private Source(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static final Source DEFAULT = JDK1_8;
|
||||
|
||||
public static Source lookup(String name) {
|
||||
return tab.get(name);
|
||||
}
|
||||
|
||||
public Target requiredTarget() {
|
||||
if (this.compareTo(JDK1_8) >= 0) return Target.JDK1_8;
|
||||
if (this.compareTo(JDK1_7) >= 0) return Target.JDK1_7;
|
||||
if (this.compareTo(JDK1_6) >= 0) return Target.JDK1_6;
|
||||
if (this.compareTo(JDK1_5) >= 0) return Target.JDK1_5;
|
||||
if (this.compareTo(JDK1_4) >= 0) return Target.JDK1_4;
|
||||
return Target.JDK1_1;
|
||||
}
|
||||
|
||||
/** Allow encoding errors, giving only warnings. */
|
||||
public boolean allowEncodingErrors() {
|
||||
return compareTo(JDK1_6) < 0;
|
||||
}
|
||||
public boolean allowAsserts() {
|
||||
return compareTo(JDK1_4) >= 0;
|
||||
}
|
||||
public boolean allowCovariantReturns() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowGenerics() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowDiamond() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowMulticatch() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowImprovedRethrowAnalysis() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowImprovedCatchAnalysis() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowEnums() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowForeach() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowStaticImport() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowBoxing() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowVarargs() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowAnnotations() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
// hex floating-point literals supported?
|
||||
public boolean allowHexFloats() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowAnonOuterThis() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean addBridges() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean enforceMandatoryWarnings() {
|
||||
return compareTo(JDK1_5) >= 0;
|
||||
}
|
||||
public boolean allowTryWithResources() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowBinaryLiterals() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowUnderscoresInLiterals() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowStringsInSwitch() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowSimplifiedVarargs() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowObjectToPrimitiveCast() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean enforceThisDotInit() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowPoly() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowLambda() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowMethodReferences() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowDefaultMethods() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowStaticInterfaceMethods() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowStrictMethodClashCheck() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowEffectivelyFinalInInnerClasses() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowTypeAnnotations() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowAnnotationsAfterTypeParams() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowRepeatedAnnotations() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowIntersectionTypesInCast() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowGraphInference() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowFunctionalInterfaceMostSpecific() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public boolean allowPostApplicabilityVarargsAccessCheck() {
|
||||
return compareTo(JDK1_8) >= 0;
|
||||
}
|
||||
public static SourceVersion toSourceVersion(Source source) {
|
||||
switch(source) {
|
||||
case JDK1_2:
|
||||
return RELEASE_2;
|
||||
case JDK1_3:
|
||||
return RELEASE_3;
|
||||
case JDK1_4:
|
||||
return RELEASE_4;
|
||||
case JDK1_5:
|
||||
return RELEASE_5;
|
||||
case JDK1_6:
|
||||
return RELEASE_6;
|
||||
case JDK1_7:
|
||||
return RELEASE_7;
|
||||
case JDK1_8:
|
||||
return RELEASE_8;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
1780
jdkSrc/jdk8/com/sun/tools/javac/code/Symbol.java
Normal file
1780
jdkSrc/jdk8/com/sun/tools/javac/code/Symbol.java
Normal file
File diff suppressed because it is too large
Load Diff
467
jdkSrc/jdk8/com/sun/tools/javac/code/SymbolMetadata.java
Normal file
467
jdkSrc/jdk8/com/sun/tools/javac/code/SymbolMetadata.java
Normal file
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* 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 com.sun.tools.javac.code;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.comp.Annotate;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Pair;
|
||||
import static com.sun.tools.javac.code.Kinds.PCK;
|
||||
|
||||
/**
|
||||
* Container for all annotations (attributes in javac) on a Symbol.
|
||||
*
|
||||
* This class is explicitly mutable. Its contents will change when attributes
|
||||
* are annotated onto the Symbol. However this class depends on the facts that
|
||||
* List (in javac) is immutable.
|
||||
*
|
||||
* An instance of this class can be in one of three states:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* IN_PROGRESS annotations have been found on the declaration. Will be processed
|
||||
* later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
|
||||
* of attributes (and this moves out of the IN_PROGRESS state).
|
||||
*
|
||||
* "unnamed" this SymbolMetadata 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 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
|
||||
* are subject to change or deletion without notice.</b>
|
||||
*/
|
||||
public class SymbolMetadata {
|
||||
|
||||
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 = DECL_NOT_STARTED;
|
||||
|
||||
/*
|
||||
* Type attributes for this symbol.
|
||||
* This field should never be null.
|
||||
*/
|
||||
private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
|
||||
|
||||
/*
|
||||
* Type attributes of initializers in this class.
|
||||
* Unused if the current symbol is not a ClassSymbol.
|
||||
*/
|
||||
private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
|
||||
|
||||
/*
|
||||
* Type attributes of class initializers in this class.
|
||||
* Unused if the current symbol is not a ClassSymbol.
|
||||
*/
|
||||
private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
|
||||
|
||||
/*
|
||||
* The Symbol this SymbolMetadata instance belongs to
|
||||
*/
|
||||
private final Symbol sym;
|
||||
|
||||
public SymbolMetadata(Symbol sym) {
|
||||
this.sym = sym;
|
||||
}
|
||||
|
||||
public List<Attribute.Compound> getDeclarationAttributes() {
|
||||
return filterDeclSentinels(attributes);
|
||||
}
|
||||
|
||||
public List<Attribute.TypeCompound> getTypeAttributes() {
|
||||
return type_attributes;
|
||||
}
|
||||
|
||||
public List<Attribute.TypeCompound> getInitTypeAttributes() {
|
||||
return init_type_attributes;
|
||||
}
|
||||
|
||||
public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
|
||||
return clinit_type_attributes;
|
||||
}
|
||||
|
||||
public void setDeclarationAttributes(List<Attribute.Compound> a) {
|
||||
Assert.check(pendingCompletion() || !isStarted());
|
||||
if (a == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
attributes = a;
|
||||
}
|
||||
|
||||
public void setTypeAttributes(List<Attribute.TypeCompound> a) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
type_attributes = a;
|
||||
}
|
||||
|
||||
public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
init_type_attributes = a;
|
||||
}
|
||||
|
||||
public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
|
||||
if (a == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
clinit_type_attributes = a;
|
||||
}
|
||||
|
||||
public void setAttributes(SymbolMetadata other) {
|
||||
if (other == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
setDeclarationAttributes(other.getDeclarationAttributes());
|
||||
if ((sym.flags() & Flags.BRIDGE) != 0) {
|
||||
Assert.check(other.sym.kind == Kinds.MTH);
|
||||
ListBuffer<TypeCompound> typeAttributes = new ListBuffer<>();
|
||||
for (TypeCompound tc : other.getTypeAttributes()) {
|
||||
// Carry over only contractual type annotations: i.e nothing interior to method body.
|
||||
if (!tc.position.type.isLocal())
|
||||
typeAttributes.append(tc);
|
||||
}
|
||||
setTypeAttributes(typeAttributes.toList());
|
||||
} else {
|
||||
setTypeAttributes(other.getTypeAttributes());
|
||||
}
|
||||
if (sym.kind == Kinds.TYP) {
|
||||
setInitTypeAttributes(other.getInitTypeAttributes());
|
||||
setClassInitTypeAttributes(other.getClassInitTypeAttributes());
|
||||
}
|
||||
}
|
||||
|
||||
public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
|
||||
Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
|
||||
this.setDeclarationAttributes(getAttributesForCompletion(ctx));
|
||||
}
|
||||
|
||||
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<T> buf = List.<T>nil();
|
||||
for (ListBuffer<T> lb : annotated.values()) {
|
||||
if (lb.size() == 1) {
|
||||
buf = buf.prepend(lb.first());
|
||||
} else { // repeated
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (atLeastOneRepeated) {
|
||||
// The Symbol s is now annotated with a combination of
|
||||
// finished non-repeating annotations and placeholders for
|
||||
// repeating annotations.
|
||||
//
|
||||
// We need to do this in two passes because when creating
|
||||
// a container for a repeating annotation we must
|
||||
// guarantee that the @Repeatable on the
|
||||
// contained annotation is fully annotated
|
||||
//
|
||||
// The way we force this order is to do all repeating
|
||||
// annotations in a pass after all non-repeating are
|
||||
// finished. This will work because @Repeatable
|
||||
// is non-repeating and therefore will be annotated in the
|
||||
// fist pass.
|
||||
|
||||
// Queue a pass that will replace Attribute.Placeholders
|
||||
// with Attribute.Compound (made from synthesized containers).
|
||||
ctx.annotateRepeated(new Annotate.Worker() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "repeated annotation pass of: " + sym + " in: " + sym.owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
complete(ctx);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Add non-repeating attributes
|
||||
return buf.reverse();
|
||||
}
|
||||
|
||||
public SymbolMetadata reset() {
|
||||
attributes = DECL_IN_PROGRESS;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return !isStarted()
|
||||
|| pendingCompletion()
|
||||
|| attributes.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isTypesEmpty() {
|
||||
return type_attributes.isEmpty();
|
||||
}
|
||||
|
||||
public boolean pendingCompletion() {
|
||||
return attributes == DECL_IN_PROGRESS;
|
||||
}
|
||||
|
||||
public SymbolMetadata append(List<Attribute.Compound> l) {
|
||||
attributes = filterDeclSentinels(attributes);
|
||||
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
} else if (attributes.isEmpty()) {
|
||||
attributes = l;
|
||||
} else {
|
||||
attributes = attributes.appendList(l);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SymbolMetadata 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 SymbolMetadata appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
} else if (init_type_attributes.isEmpty()) {
|
||||
init_type_attributes = l;
|
||||
} else {
|
||||
init_type_attributes = init_type_attributes.appendList(l);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SymbolMetadata appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
} else if (clinit_type_attributes.isEmpty()) {
|
||||
clinit_type_attributes = l;
|
||||
} else {
|
||||
clinit_type_attributes = clinit_type_attributes.appendList(l);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SymbolMetadata prepend(List<Attribute.Compound> l) {
|
||||
attributes = filterDeclSentinels(attributes);
|
||||
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
} else if (attributes.isEmpty()) {
|
||||
attributes = l;
|
||||
} else {
|
||||
attributes = attributes.prependList(l);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
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 != DECL_NOT_STARTED;
|
||||
}
|
||||
|
||||
private List<Attribute.Compound> getPlaceholders() {
|
||||
List<Attribute.Compound> res = List.<Attribute.Compound>nil();
|
||||
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);
|
||||
}
|
||||
}
|
||||
return res.reverse();
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace Placeholders for repeating annotations with their containers
|
||||
*/
|
||||
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 (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(SymbolMetadata.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(SymbolMetadata.this.getPlaceholders().isEmpty());
|
||||
}
|
||||
} finally {
|
||||
log.useSource(oldSource);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
|
||||
Log log = ctx.log;
|
||||
|
||||
// Process repeated annotations
|
||||
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<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);
|
||||
}
|
||||
}
|
||||
|
||||
// A null return will delete the Placeholder
|
||||
return validRepeated;
|
||||
}
|
||||
|
||||
private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
|
||||
|
||||
private final Annotate.AnnotateRepeatedContext<T> ctx;
|
||||
private final List<T> placeholderFor;
|
||||
private final Symbol on;
|
||||
|
||||
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 :
|
||||
new TypeAnnotationPosition());
|
||||
this.ctx = ctx;
|
||||
this.placeholderFor = placeholderFor;
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<placeholder: " + placeholderFor + " on: " + on + ">";
|
||||
}
|
||||
|
||||
public List<T> getPlaceholderFor() {
|
||||
return placeholderFor;
|
||||
}
|
||||
|
||||
public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
}
|
723
jdkSrc/jdk8/com/sun/tools/javac/code/Symtab.java
Normal file
723
jdkSrc/jdk8/com/sun/tools/javac/code/Symtab.java
Normal file
@@ -0,0 +1,723 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.jvm.ByteCodes.*;
|
||||
import static com.sun.tools.javac.code.TypeTag.*;
|
||||
|
||||
/** A class that defines all predefined constants and operators
|
||||
* as well as special classes such as java.lang.Object, which need
|
||||
* to be known to the compiler. All symbols are held in instance
|
||||
* fields. This makes it possible to work in multiple concurrent
|
||||
* projects, which might use different class files for library classes.
|
||||
*
|
||||
* <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 Symtab {
|
||||
/** The context key for the symbol table. */
|
||||
protected static final Context.Key<Symtab> symtabKey =
|
||||
new Context.Key<Symtab>();
|
||||
|
||||
/** Get the symbol table instance. */
|
||||
public static Symtab instance(Context context) {
|
||||
Symtab instance = context.get(symtabKey);
|
||||
if (instance == null)
|
||||
instance = new Symtab(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** Builtin types.
|
||||
*/
|
||||
public final JCPrimitiveType byteType = new JCPrimitiveType(BYTE, null);
|
||||
public final JCPrimitiveType charType = new JCPrimitiveType(CHAR, null);
|
||||
public final JCPrimitiveType shortType = new JCPrimitiveType(SHORT, null);
|
||||
public final JCPrimitiveType intType = new JCPrimitiveType(INT, null);
|
||||
public final JCPrimitiveType longType = new JCPrimitiveType(LONG, null);
|
||||
public final JCPrimitiveType floatType = new JCPrimitiveType(FLOAT, null);
|
||||
public final JCPrimitiveType doubleType = new JCPrimitiveType(DOUBLE, null);
|
||||
public final JCPrimitiveType booleanType = new JCPrimitiveType(BOOLEAN, null);
|
||||
public final Type botType = new BottomType();
|
||||
public final JCVoidType voidType = new JCVoidType();
|
||||
|
||||
private final Names names;
|
||||
private final ClassReader reader;
|
||||
private final Target target;
|
||||
|
||||
/** A symbol for the root package.
|
||||
*/
|
||||
public final PackageSymbol rootPackage;
|
||||
|
||||
/** A symbol for the unnamed package.
|
||||
*/
|
||||
public final PackageSymbol unnamedPackage;
|
||||
|
||||
/** A symbol that stands for a missing symbol.
|
||||
*/
|
||||
public final TypeSymbol noSymbol;
|
||||
|
||||
/** The error symbol.
|
||||
*/
|
||||
public final ClassSymbol errSymbol;
|
||||
|
||||
/** The unknown symbol.
|
||||
*/
|
||||
public final ClassSymbol unknownSymbol;
|
||||
|
||||
/** A value for the errType, with a originalType of noType */
|
||||
public final Type errType;
|
||||
|
||||
/** A value for the unknown type. */
|
||||
public final Type unknownType;
|
||||
|
||||
/** The builtin type of all arrays. */
|
||||
public final ClassSymbol arrayClass;
|
||||
public final MethodSymbol arrayCloneMethod;
|
||||
|
||||
/** VGJ: The (singleton) type of all bound types. */
|
||||
public final ClassSymbol boundClass;
|
||||
|
||||
/** The builtin type of all methods. */
|
||||
public final ClassSymbol methodClass;
|
||||
|
||||
/** Predefined types.
|
||||
*/
|
||||
public final Type objectType;
|
||||
public final Type classType;
|
||||
public final Type classLoaderType;
|
||||
public final Type stringType;
|
||||
public final Type stringBufferType;
|
||||
public final Type stringBuilderType;
|
||||
public final Type cloneableType;
|
||||
public final Type serializableType;
|
||||
public final Type serializedLambdaType;
|
||||
public final Type methodHandleType;
|
||||
public final Type methodHandleLookupType;
|
||||
public final Type methodTypeType;
|
||||
public final Type nativeHeaderType;
|
||||
public final Type throwableType;
|
||||
public final Type errorType;
|
||||
public final Type interruptedExceptionType;
|
||||
public final Type illegalArgumentExceptionType;
|
||||
public final Type exceptionType;
|
||||
public final Type runtimeExceptionType;
|
||||
public final Type classNotFoundExceptionType;
|
||||
public final Type noClassDefFoundErrorType;
|
||||
public final Type noSuchFieldErrorType;
|
||||
public final Type assertionErrorType;
|
||||
public final Type cloneNotSupportedExceptionType;
|
||||
public final Type annotationType;
|
||||
public final TypeSymbol enumSym;
|
||||
public final Type listType;
|
||||
public final Type collectionsType;
|
||||
public final Type comparableType;
|
||||
public final Type comparatorType;
|
||||
public final Type arraysType;
|
||||
public final Type iterableType;
|
||||
public final Type iteratorType;
|
||||
public final Type annotationTargetType;
|
||||
public final Type overrideType;
|
||||
public final Type retentionType;
|
||||
public final Type deprecatedType;
|
||||
public final Type suppressWarningsType;
|
||||
public final Type inheritedType;
|
||||
public final Type profileType;
|
||||
public final Type proprietaryType;
|
||||
public final Type systemType;
|
||||
public final Type autoCloseableType;
|
||||
public final Type trustMeType;
|
||||
public final Type lambdaMetafactory;
|
||||
public final Type repeatableType;
|
||||
public final Type documentedType;
|
||||
public final Type elementTypeType;
|
||||
public final Type functionalInterfaceType;
|
||||
|
||||
/** The symbol representing the length field of an array.
|
||||
*/
|
||||
public final VarSymbol lengthVar;
|
||||
|
||||
/** The null check operator. */
|
||||
public final OperatorSymbol nullcheck;
|
||||
|
||||
/** The symbol representing the final finalize method on enums */
|
||||
public final MethodSymbol enumFinalFinalize;
|
||||
|
||||
/** The symbol representing the close method on TWR AutoCloseable type */
|
||||
public final MethodSymbol autoCloseableClose;
|
||||
|
||||
/** The predefined type that belongs to a tag.
|
||||
*/
|
||||
public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()];
|
||||
|
||||
/** The name of the class that belongs to a basix type tag.
|
||||
*/
|
||||
public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()];
|
||||
|
||||
/** A set containing all operator names.
|
||||
*/
|
||||
public final Set<Name> operatorNames = new HashSet<Name>();
|
||||
|
||||
/** A hashtable containing the encountered top-level and member classes,
|
||||
* indexed by flat names. The table does not contain local classes.
|
||||
* It should be updated from the outside to reflect classes defined
|
||||
* by compiled source files.
|
||||
*/
|
||||
public final Map<Name, ClassSymbol> classes = new HashMap<Name, ClassSymbol>();
|
||||
|
||||
/** A hashtable containing the encountered packages.
|
||||
* the table should be updated from outside to reflect packages defined
|
||||
* by compiled source files.
|
||||
*/
|
||||
public final Map<Name, PackageSymbol> packages = new HashMap<Name, PackageSymbol>();
|
||||
|
||||
public void initType(Type type, ClassSymbol c) {
|
||||
type.tsym = c;
|
||||
typeOfTag[type.getTag().ordinal()] = type;
|
||||
}
|
||||
|
||||
public void initType(Type type, String name) {
|
||||
initType(
|
||||
type,
|
||||
new ClassSymbol(
|
||||
PUBLIC, names.fromString(name), type, rootPackage));
|
||||
}
|
||||
|
||||
public void initType(Type type, String name, String bname) {
|
||||
initType(type, name);
|
||||
boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname);
|
||||
}
|
||||
|
||||
/** The class symbol that owns all predefined symbols.
|
||||
*/
|
||||
public final ClassSymbol predefClass;
|
||||
|
||||
/** Enter a constant into symbol table.
|
||||
* @param name The constant's name.
|
||||
* @param type The constant's type.
|
||||
*/
|
||||
private VarSymbol enterConstant(String name, Type type) {
|
||||
VarSymbol c = new VarSymbol(
|
||||
PUBLIC | STATIC | FINAL,
|
||||
names.fromString(name),
|
||||
type,
|
||||
predefClass);
|
||||
c.setData(type.constValue());
|
||||
predefClass.members().enter(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Enter a binary operation into symbol table.
|
||||
* @param name The name of the operator.
|
||||
* @param left The type of the left operand.
|
||||
* @param right The type of the left operand.
|
||||
* @param res The operation's result type.
|
||||
* @param opcode The operation's bytecode instruction.
|
||||
*/
|
||||
private void enterBinop(String name,
|
||||
Type left, Type right, Type res,
|
||||
int opcode) {
|
||||
predefClass.members().enter(
|
||||
new OperatorSymbol(
|
||||
makeOperatorName(name),
|
||||
new MethodType(List.of(left, right), res,
|
||||
List.<Type>nil(), methodClass),
|
||||
opcode,
|
||||
predefClass));
|
||||
}
|
||||
|
||||
/** Enter a binary operation, as above but with two opcodes,
|
||||
* which get encoded as
|
||||
* {@code (opcode1 << ByteCodeTags.preShift) + opcode2 }.
|
||||
* @param opcode1 First opcode.
|
||||
* @param opcode2 Second opcode.
|
||||
*/
|
||||
private void enterBinop(String name,
|
||||
Type left, Type right, Type res,
|
||||
int opcode1, int opcode2) {
|
||||
enterBinop(
|
||||
name, left, right, res, (opcode1 << ByteCodes.preShift) | opcode2);
|
||||
}
|
||||
|
||||
/** Enter a unary operation into symbol table.
|
||||
* @param name The name of the operator.
|
||||
* @param arg The type of the operand.
|
||||
* @param res The operation's result type.
|
||||
* @param opcode The operation's bytecode instruction.
|
||||
*/
|
||||
private OperatorSymbol enterUnop(String name,
|
||||
Type arg,
|
||||
Type res,
|
||||
int opcode) {
|
||||
OperatorSymbol sym =
|
||||
new OperatorSymbol(makeOperatorName(name),
|
||||
new MethodType(List.of(arg),
|
||||
res,
|
||||
List.<Type>nil(),
|
||||
methodClass),
|
||||
opcode,
|
||||
predefClass);
|
||||
predefClass.members().enter(sym);
|
||||
return sym;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new operator name from corresponding String representation
|
||||
* and add the name to the set of known operator names.
|
||||
*/
|
||||
private Name makeOperatorName(String name) {
|
||||
Name opName = names.fromString(name);
|
||||
operatorNames.add(opName);
|
||||
return opName;
|
||||
}
|
||||
|
||||
/** Enter a class into symbol table.
|
||||
* @param s The name of the class.
|
||||
*/
|
||||
private Type enterClass(String s) {
|
||||
return reader.enterClass(names.fromString(s)).type;
|
||||
}
|
||||
|
||||
public void synthesizeEmptyInterfaceIfMissing(final Type type) {
|
||||
final Completer completer = type.tsym.completer;
|
||||
if (completer != null) {
|
||||
type.tsym.completer = new Completer() {
|
||||
public void complete(Symbol sym) throws CompletionFailure {
|
||||
try {
|
||||
completer.complete(sym);
|
||||
} catch (CompletionFailure e) {
|
||||
sym.flags_field |= (PUBLIC | INTERFACE);
|
||||
((ClassType) sym.type).supertype_field = objectType;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void synthesizeBoxTypeIfMissing(final Type type) {
|
||||
ClassSymbol sym = reader.enterClass(boxedName[type.getTag().ordinal()]);
|
||||
final Completer completer = sym.completer;
|
||||
if (completer != null) {
|
||||
sym.completer = new Completer() {
|
||||
public void complete(Symbol sym) throws CompletionFailure {
|
||||
try {
|
||||
completer.complete(sym);
|
||||
} catch (CompletionFailure e) {
|
||||
sym.flags_field |= PUBLIC;
|
||||
((ClassType) sym.type).supertype_field = objectType;
|
||||
Name n = target.boxWithConstructors() ? names.init : names.valueOf;
|
||||
MethodSymbol boxMethod =
|
||||
new MethodSymbol(PUBLIC | STATIC,
|
||||
n,
|
||||
new MethodType(List.of(type), sym.type,
|
||||
List.<Type>nil(), methodClass),
|
||||
sym);
|
||||
sym.members().enter(boxMethod);
|
||||
MethodSymbol unboxMethod =
|
||||
new MethodSymbol(PUBLIC,
|
||||
type.tsym.name.append(names.Value), // x.intValue()
|
||||
new MethodType(List.<Type>nil(), type,
|
||||
List.<Type>nil(), methodClass),
|
||||
sym);
|
||||
sym.members().enter(unboxMethod);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Enter a synthetic class that is used to mark classes in ct.sym.
|
||||
// This class does not have a class file.
|
||||
private Type enterSyntheticAnnotation(String name) {
|
||||
ClassType type = (ClassType)enterClass(name);
|
||||
ClassSymbol sym = (ClassSymbol)type.tsym;
|
||||
sym.completer = null;
|
||||
sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
|
||||
sym.erasure_field = type;
|
||||
sym.members_field = new Scope(sym);
|
||||
type.typarams_field = List.nil();
|
||||
type.allparams_field = List.nil();
|
||||
type.supertype_field = annotationType;
|
||||
type.interfaces_field = List.nil();
|
||||
return type;
|
||||
}
|
||||
|
||||
/** Constructor; enters all predefined identifiers and operators
|
||||
* into symbol table.
|
||||
*/
|
||||
protected Symtab(Context context) throws CompletionFailure {
|
||||
context.put(symtabKey, this);
|
||||
|
||||
names = Names.instance(context);
|
||||
target = Target.instance(context);
|
||||
|
||||
// Create the unknown type
|
||||
unknownType = new UnknownType();
|
||||
|
||||
// create the basic builtin symbols
|
||||
rootPackage = new PackageSymbol(names.empty, null);
|
||||
final JavacMessages messages = JavacMessages.instance(context);
|
||||
unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
|
||||
public String toString() {
|
||||
return messages.getLocalizedString("compiler.misc.unnamed.package");
|
||||
}
|
||||
};
|
||||
noSymbol = new TypeSymbol(Kinds.NIL, 0, names.empty, Type.noType, rootPackage) {
|
||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||
return v.visitUnknown(this, p);
|
||||
}
|
||||
};
|
||||
|
||||
// create the error symbols
|
||||
errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage);
|
||||
errType = new ErrorType(errSymbol, Type.noType);
|
||||
|
||||
unknownSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.fromString("<any?>"), null, rootPackage);
|
||||
unknownSymbol.members_field = new Scope.ErrorScope(unknownSymbol);
|
||||
unknownSymbol.type = unknownType;
|
||||
|
||||
// initialize builtin types
|
||||
initType(byteType, "byte", "Byte");
|
||||
initType(shortType, "short", "Short");
|
||||
initType(charType, "char", "Character");
|
||||
initType(intType, "int", "Integer");
|
||||
initType(longType, "long", "Long");
|
||||
initType(floatType, "float", "Float");
|
||||
initType(doubleType, "double", "Double");
|
||||
initType(booleanType, "boolean", "Boolean");
|
||||
initType(voidType, "void", "Void");
|
||||
initType(botType, "<nulltype>");
|
||||
initType(errType, errSymbol);
|
||||
initType(unknownType, unknownSymbol);
|
||||
|
||||
// the builtin class of all arrays
|
||||
arrayClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Array, noSymbol);
|
||||
|
||||
// VGJ
|
||||
boundClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Bound, noSymbol);
|
||||
boundClass.members_field = new Scope.ErrorScope(boundClass);
|
||||
|
||||
// the builtin class of all methods
|
||||
methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol);
|
||||
methodClass.members_field = new Scope.ErrorScope(boundClass);
|
||||
|
||||
// Create class to hold all predefined constants and operations.
|
||||
predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
|
||||
Scope scope = new Scope(predefClass);
|
||||
predefClass.members_field = scope;
|
||||
|
||||
// Enter symbols for basic types.
|
||||
scope.enter(byteType.tsym);
|
||||
scope.enter(shortType.tsym);
|
||||
scope.enter(charType.tsym);
|
||||
scope.enter(intType.tsym);
|
||||
scope.enter(longType.tsym);
|
||||
scope.enter(floatType.tsym);
|
||||
scope.enter(doubleType.tsym);
|
||||
scope.enter(booleanType.tsym);
|
||||
scope.enter(errType.tsym);
|
||||
|
||||
// Enter symbol for the errSymbol
|
||||
scope.enter(errSymbol);
|
||||
|
||||
classes.put(predefClass.fullname, predefClass);
|
||||
|
||||
reader = ClassReader.instance(context);
|
||||
reader.init(this);
|
||||
|
||||
// Enter predefined classes.
|
||||
objectType = enterClass("java.lang.Object");
|
||||
classType = enterClass("java.lang.Class");
|
||||
stringType = enterClass("java.lang.String");
|
||||
stringBufferType = enterClass("java.lang.StringBuffer");
|
||||
stringBuilderType = enterClass("java.lang.StringBuilder");
|
||||
cloneableType = enterClass("java.lang.Cloneable");
|
||||
throwableType = enterClass("java.lang.Throwable");
|
||||
serializableType = enterClass("java.io.Serializable");
|
||||
serializedLambdaType = enterClass("java.lang.invoke.SerializedLambda");
|
||||
methodHandleType = enterClass("java.lang.invoke.MethodHandle");
|
||||
methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup");
|
||||
methodTypeType = enterClass("java.lang.invoke.MethodType");
|
||||
errorType = enterClass("java.lang.Error");
|
||||
illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
|
||||
interruptedExceptionType = enterClass("java.lang.InterruptedException");
|
||||
exceptionType = enterClass("java.lang.Exception");
|
||||
runtimeExceptionType = enterClass("java.lang.RuntimeException");
|
||||
classNotFoundExceptionType = enterClass("java.lang.ClassNotFoundException");
|
||||
noClassDefFoundErrorType = enterClass("java.lang.NoClassDefFoundError");
|
||||
noSuchFieldErrorType = enterClass("java.lang.NoSuchFieldError");
|
||||
assertionErrorType = enterClass("java.lang.AssertionError");
|
||||
cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException");
|
||||
annotationType = enterClass("java.lang.annotation.Annotation");
|
||||
classLoaderType = enterClass("java.lang.ClassLoader");
|
||||
enumSym = reader.enterClass(names.java_lang_Enum);
|
||||
enumFinalFinalize =
|
||||
new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL,
|
||||
names.finalize,
|
||||
new MethodType(List.<Type>nil(), voidType,
|
||||
List.<Type>nil(), methodClass),
|
||||
enumSym);
|
||||
listType = enterClass("java.util.List");
|
||||
collectionsType = enterClass("java.util.Collections");
|
||||
comparableType = enterClass("java.lang.Comparable");
|
||||
comparatorType = enterClass("java.util.Comparator");
|
||||
arraysType = enterClass("java.util.Arrays");
|
||||
iterableType = target.hasIterable()
|
||||
? enterClass("java.lang.Iterable")
|
||||
: enterClass("java.util.Collection");
|
||||
iteratorType = enterClass("java.util.Iterator");
|
||||
annotationTargetType = enterClass("java.lang.annotation.Target");
|
||||
overrideType = enterClass("java.lang.Override");
|
||||
retentionType = enterClass("java.lang.annotation.Retention");
|
||||
deprecatedType = enterClass("java.lang.Deprecated");
|
||||
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
|
||||
inheritedType = enterClass("java.lang.annotation.Inherited");
|
||||
repeatableType = enterClass("java.lang.annotation.Repeatable");
|
||||
documentedType = enterClass("java.lang.annotation.Documented");
|
||||
elementTypeType = enterClass("java.lang.annotation.ElementType");
|
||||
systemType = enterClass("java.lang.System");
|
||||
autoCloseableType = enterClass("java.lang.AutoCloseable");
|
||||
autoCloseableClose = new MethodSymbol(PUBLIC,
|
||||
names.close,
|
||||
new MethodType(List.<Type>nil(), voidType,
|
||||
List.of(exceptionType), methodClass),
|
||||
autoCloseableType.tsym);
|
||||
trustMeType = enterClass("java.lang.SafeVarargs");
|
||||
nativeHeaderType = enterClass("java.lang.annotation.Native");
|
||||
lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
|
||||
functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
|
||||
|
||||
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
|
||||
synthesizeEmptyInterfaceIfMissing(cloneableType);
|
||||
synthesizeEmptyInterfaceIfMissing(serializableType);
|
||||
synthesizeEmptyInterfaceIfMissing(lambdaMetafactory);
|
||||
synthesizeEmptyInterfaceIfMissing(serializedLambdaType);
|
||||
synthesizeBoxTypeIfMissing(doubleType);
|
||||
synthesizeBoxTypeIfMissing(floatType);
|
||||
synthesizeBoxTypeIfMissing(voidType);
|
||||
|
||||
// Enter a synthetic class that is used to mark internal
|
||||
// proprietary classes in ct.sym. This class does not have a
|
||||
// class file.
|
||||
proprietaryType = enterSyntheticAnnotation("sun.Proprietary+Annotation");
|
||||
|
||||
// Enter a synthetic class that is used to provide profile info for
|
||||
// classes in ct.sym. This class does not have a class file.
|
||||
profileType = enterSyntheticAnnotation("jdk.Profile+Annotation");
|
||||
MethodSymbol m = new MethodSymbol(PUBLIC | ABSTRACT, names.value, intType, profileType.tsym);
|
||||
profileType.tsym.members().enter(m);
|
||||
|
||||
// Enter a class for arrays.
|
||||
// The class implements java.lang.Cloneable and java.io.Serializable.
|
||||
// It has a final length field and a clone method.
|
||||
ClassType arrayClassType = (ClassType)arrayClass.type;
|
||||
arrayClassType.supertype_field = objectType;
|
||||
arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
|
||||
arrayClass.members_field = new Scope(arrayClass);
|
||||
lengthVar = new VarSymbol(
|
||||
PUBLIC | FINAL,
|
||||
names.length,
|
||||
intType,
|
||||
arrayClass);
|
||||
arrayClass.members().enter(lengthVar);
|
||||
arrayCloneMethod = new MethodSymbol(
|
||||
PUBLIC,
|
||||
names.clone,
|
||||
new MethodType(List.<Type>nil(), objectType,
|
||||
List.<Type>nil(), methodClass),
|
||||
arrayClass);
|
||||
arrayClass.members().enter(arrayCloneMethod);
|
||||
|
||||
// Enter operators.
|
||||
/* Internally we use +++, --- for unary +, - to reduce +, - operators
|
||||
* overloading
|
||||
*/
|
||||
enterUnop("+++", doubleType, doubleType, nop);
|
||||
enterUnop("+++", floatType, floatType, nop);
|
||||
enterUnop("+++", longType, longType, nop);
|
||||
enterUnop("+++", intType, intType, nop);
|
||||
|
||||
enterUnop("---", doubleType, doubleType, dneg);
|
||||
enterUnop("---", floatType, floatType, fneg);
|
||||
enterUnop("---", longType, longType, lneg);
|
||||
enterUnop("---", intType, intType, ineg);
|
||||
|
||||
enterUnop("~", longType, longType, lxor);
|
||||
enterUnop("~", intType, intType, ixor);
|
||||
|
||||
enterUnop("++", doubleType, doubleType, dadd);
|
||||
enterUnop("++", floatType, floatType, fadd);
|
||||
enterUnop("++", longType, longType, ladd);
|
||||
enterUnop("++", intType, intType, iadd);
|
||||
enterUnop("++", charType, charType, iadd);
|
||||
enterUnop("++", shortType, shortType, iadd);
|
||||
enterUnop("++", byteType, byteType, iadd);
|
||||
|
||||
enterUnop("--", doubleType, doubleType, dsub);
|
||||
enterUnop("--", floatType, floatType, fsub);
|
||||
enterUnop("--", longType, longType, lsub);
|
||||
enterUnop("--", intType, intType, isub);
|
||||
enterUnop("--", charType, charType, isub);
|
||||
enterUnop("--", shortType, shortType, isub);
|
||||
enterUnop("--", byteType, byteType, isub);
|
||||
|
||||
enterUnop("!", booleanType, booleanType, bool_not);
|
||||
nullcheck = enterUnop("<*nullchk*>", objectType, objectType, nullchk);
|
||||
|
||||
// string concatenation
|
||||
enterBinop("+", stringType, objectType, stringType, string_add);
|
||||
enterBinop("+", objectType, stringType, stringType, string_add);
|
||||
enterBinop("+", stringType, stringType, stringType, string_add);
|
||||
enterBinop("+", stringType, intType, stringType, string_add);
|
||||
enterBinop("+", stringType, longType, stringType, string_add);
|
||||
enterBinop("+", stringType, floatType, stringType, string_add);
|
||||
enterBinop("+", stringType, doubleType, stringType, string_add);
|
||||
enterBinop("+", stringType, booleanType, stringType, string_add);
|
||||
enterBinop("+", stringType, botType, stringType, string_add);
|
||||
enterBinop("+", intType, stringType, stringType, string_add);
|
||||
enterBinop("+", longType, stringType, stringType, string_add);
|
||||
enterBinop("+", floatType, stringType, stringType, string_add);
|
||||
enterBinop("+", doubleType, stringType, stringType, string_add);
|
||||
enterBinop("+", booleanType, stringType, stringType, string_add);
|
||||
enterBinop("+", botType, stringType, stringType, string_add);
|
||||
|
||||
// these errors would otherwise be matched as string concatenation
|
||||
enterBinop("+", botType, botType, botType, error);
|
||||
enterBinop("+", botType, intType, botType, error);
|
||||
enterBinop("+", botType, longType, botType, error);
|
||||
enterBinop("+", botType, floatType, botType, error);
|
||||
enterBinop("+", botType, doubleType, botType, error);
|
||||
enterBinop("+", botType, booleanType, botType, error);
|
||||
enterBinop("+", botType, objectType, botType, error);
|
||||
enterBinop("+", intType, botType, botType, error);
|
||||
enterBinop("+", longType, botType, botType, error);
|
||||
enterBinop("+", floatType, botType, botType, error);
|
||||
enterBinop("+", doubleType, botType, botType, error);
|
||||
enterBinop("+", booleanType, botType, botType, error);
|
||||
enterBinop("+", objectType, botType, botType, error);
|
||||
|
||||
enterBinop("+", doubleType, doubleType, doubleType, dadd);
|
||||
enterBinop("+", floatType, floatType, floatType, fadd);
|
||||
enterBinop("+", longType, longType, longType, ladd);
|
||||
enterBinop("+", intType, intType, intType, iadd);
|
||||
|
||||
enterBinop("-", doubleType, doubleType, doubleType, dsub);
|
||||
enterBinop("-", floatType, floatType, floatType, fsub);
|
||||
enterBinop("-", longType, longType, longType, lsub);
|
||||
enterBinop("-", intType, intType, intType, isub);
|
||||
|
||||
enterBinop("*", doubleType, doubleType, doubleType, dmul);
|
||||
enterBinop("*", floatType, floatType, floatType, fmul);
|
||||
enterBinop("*", longType, longType, longType, lmul);
|
||||
enterBinop("*", intType, intType, intType, imul);
|
||||
|
||||
enterBinop("/", doubleType, doubleType, doubleType, ddiv);
|
||||
enterBinop("/", floatType, floatType, floatType, fdiv);
|
||||
enterBinop("/", longType, longType, longType, ldiv);
|
||||
enterBinop("/", intType, intType, intType, idiv);
|
||||
|
||||
enterBinop("%", doubleType, doubleType, doubleType, dmod);
|
||||
enterBinop("%", floatType, floatType, floatType, fmod);
|
||||
enterBinop("%", longType, longType, longType, lmod);
|
||||
enterBinop("%", intType, intType, intType, imod);
|
||||
|
||||
enterBinop("&", booleanType, booleanType, booleanType, iand);
|
||||
enterBinop("&", longType, longType, longType, land);
|
||||
enterBinop("&", intType, intType, intType, iand);
|
||||
|
||||
enterBinop("|", booleanType, booleanType, booleanType, ior);
|
||||
enterBinop("|", longType, longType, longType, lor);
|
||||
enterBinop("|", intType, intType, intType, ior);
|
||||
|
||||
enterBinop("^", booleanType, booleanType, booleanType, ixor);
|
||||
enterBinop("^", longType, longType, longType, lxor);
|
||||
enterBinop("^", intType, intType, intType, ixor);
|
||||
|
||||
enterBinop("<<", longType, longType, longType, lshll);
|
||||
enterBinop("<<", intType, longType, intType, ishll);
|
||||
enterBinop("<<", longType, intType, longType, lshl);
|
||||
enterBinop("<<", intType, intType, intType, ishl);
|
||||
|
||||
enterBinop(">>", longType, longType, longType, lshrl);
|
||||
enterBinop(">>", intType, longType, intType, ishrl);
|
||||
enterBinop(">>", longType, intType, longType, lshr);
|
||||
enterBinop(">>", intType, intType, intType, ishr);
|
||||
|
||||
enterBinop(">>>", longType, longType, longType, lushrl);
|
||||
enterBinop(">>>", intType, longType, intType, iushrl);
|
||||
enterBinop(">>>", longType, intType, longType, lushr);
|
||||
enterBinop(">>>", intType, intType, intType, iushr);
|
||||
|
||||
enterBinop("<", doubleType, doubleType, booleanType, dcmpg, iflt);
|
||||
enterBinop("<", floatType, floatType, booleanType, fcmpg, iflt);
|
||||
enterBinop("<", longType, longType, booleanType, lcmp, iflt);
|
||||
enterBinop("<", intType, intType, booleanType, if_icmplt);
|
||||
|
||||
enterBinop(">", doubleType, doubleType, booleanType, dcmpl, ifgt);
|
||||
enterBinop(">", floatType, floatType, booleanType, fcmpl, ifgt);
|
||||
enterBinop(">", longType, longType, booleanType, lcmp, ifgt);
|
||||
enterBinop(">", intType, intType, booleanType, if_icmpgt);
|
||||
|
||||
enterBinop("<=", doubleType, doubleType, booleanType, dcmpg, ifle);
|
||||
enterBinop("<=", floatType, floatType, booleanType, fcmpg, ifle);
|
||||
enterBinop("<=", longType, longType, booleanType, lcmp, ifle);
|
||||
enterBinop("<=", intType, intType, booleanType, if_icmple);
|
||||
|
||||
enterBinop(">=", doubleType, doubleType, booleanType, dcmpl, ifge);
|
||||
enterBinop(">=", floatType, floatType, booleanType, fcmpl, ifge);
|
||||
enterBinop(">=", longType, longType, booleanType, lcmp, ifge);
|
||||
enterBinop(">=", intType, intType, booleanType, if_icmpge);
|
||||
|
||||
enterBinop("==", objectType, objectType, booleanType, if_acmpeq);
|
||||
enterBinop("==", booleanType, booleanType, booleanType, if_icmpeq);
|
||||
enterBinop("==", doubleType, doubleType, booleanType, dcmpl, ifeq);
|
||||
enterBinop("==", floatType, floatType, booleanType, fcmpl, ifeq);
|
||||
enterBinop("==", longType, longType, booleanType, lcmp, ifeq);
|
||||
enterBinop("==", intType, intType, booleanType, if_icmpeq);
|
||||
|
||||
enterBinop("!=", objectType, objectType, booleanType, if_acmpne);
|
||||
enterBinop("!=", booleanType, booleanType, booleanType, if_icmpne);
|
||||
enterBinop("!=", doubleType, doubleType, booleanType, dcmpl, ifne);
|
||||
enterBinop("!=", floatType, floatType, booleanType, fcmpl, ifne);
|
||||
enterBinop("!=", longType, longType, booleanType, lcmp, ifne);
|
||||
enterBinop("!=", intType, intType, booleanType, if_icmpne);
|
||||
|
||||
enterBinop("&&", booleanType, booleanType, booleanType, bool_and);
|
||||
enterBinop("||", booleanType, booleanType, booleanType, bool_or);
|
||||
}
|
||||
}
|
177
jdkSrc/jdk8/com/sun/tools/javac/code/TargetType.java
Normal file
177
jdkSrc/jdk8/com/sun/tools/javac/code/TargetType.java
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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.tools.javac.code;
|
||||
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
|
||||
/**
|
||||
* Describes the type of program element an extended annotation (or extended
|
||||
* compound attribute) targets.
|
||||
*
|
||||
* By comparison, a Tree.Kind has enum values for all elements in the AST, and
|
||||
* it does not provide enough resolution for type arguments (i.e., whether an
|
||||
* annotation targets a type argument in a local variable, method return type,
|
||||
* or a typecast).
|
||||
*
|
||||
* <p><b>This is NOT part of any 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>
|
||||
*/
|
||||
// Code duplicated in com.sun.tools.classfile.TypeAnnotation.TargetType
|
||||
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 type test. */
|
||||
INSTANCEOF(0x43, true),
|
||||
|
||||
/** For annotations on an object creation expression. */
|
||||
NEW(0x44, true),
|
||||
|
||||
/** For annotations on a constructor reference receiver. */
|
||||
CONSTRUCTOR_REFERENCE(0x45, true),
|
||||
|
||||
/** For annotations on a method reference receiver. */
|
||||
METHOD_REFERENCE(0x46, true),
|
||||
|
||||
/** For annotations on a typecast. */
|
||||
CAST(0x47, true),
|
||||
|
||||
/** For annotations on a type argument of an object creation expression. */
|
||||
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
|
||||
|
||||
/** For annotations on a type argument of a method call. */
|
||||
METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
|
||||
|
||||
/** For annotations on a type argument of a constructor reference. */
|
||||
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
|
||||
|
||||
/** For annotations on a type argument of a method reference. */
|
||||
METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
|
||||
|
||||
/** For annotations with an unknown target. */
|
||||
UNKNOWN(0xFF);
|
||||
|
||||
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
|
||||
|
||||
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)
|
||||
Assert.error("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)
|
||||
Assert.error("Unknown TargetType: " + tag);
|
||||
return targets[tag];
|
||||
}
|
||||
}
|
2081
jdkSrc/jdk8/com/sun/tools/javac/code/Type.java
Normal file
2081
jdkSrc/jdk8/com/sun/tools/javac/code/Type.java
Normal file
File diff suppressed because it is too large
Load Diff
326
jdkSrc/jdk8/com/sun/tools/javac/code/TypeAnnotationPosition.java
Normal file
326
jdkSrc/jdk8/com/sun/tools/javac/code/TypeAnnotationPosition.java
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* 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.javac.code;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.JCLambda;
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
/** A type annotation position.
|
||||
*
|
||||
* <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>
|
||||
*/
|
||||
// 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<TypePathEntry> location = List.nil();
|
||||
|
||||
// Tree position.
|
||||
public int pos = -1;
|
||||
|
||||
// For type casts, type tests, new, locals (as start_pc),
|
||||
// and method and constructor reference type arguments.
|
||||
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.
|
||||
// In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
|
||||
// to the catch type index - that value is only temporary.
|
||||
// Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
|
||||
// we use that value to determine the exception table index.
|
||||
public int exception_index = Integer.MIN_VALUE;
|
||||
|
||||
// If this type annotation is within a lambda expression,
|
||||
// store a pointer to the lambda expression tree in order
|
||||
// to allow a later translation to the right method.
|
||||
public JCLambda onLambda = null;
|
||||
|
||||
public TypeAnnotationPosition() {}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('[');
|
||||
sb.append(type);
|
||||
|
||||
switch (type) {
|
||||
// instanceof
|
||||
case INSTANCEOF:
|
||||
// new expression
|
||||
case NEW:
|
||||
// constructor/method reference receiver
|
||||
case CONSTRUCTOR_REFERENCE:
|
||||
case METHOD_REFERENCE:
|
||||
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;
|
||||
// type cast
|
||||
case CAST:
|
||||
// method/constructor/reference type argument
|
||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||
case CONSTRUCTOR_REFERENCE_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;
|
||||
case UNKNOWN:
|
||||
sb.append(", position UNKNOWN!");
|
||||
break;
|
||||
default:
|
||||
Assert.error("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);
|
||||
|
||||
if (onLambda != null) {
|
||||
sb.append(", onLambda hash = ");
|
||||
sb.append(onLambda.hashCode());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public boolean matchesPos(int pos) {
|
||||
return this.pos == pos;
|
||||
}
|
||||
|
||||
public void updatePosOffset(int to) {
|
||||
offset = to;
|
||||
lvarOffset = new int[]{to};
|
||||
isValidOffset = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = new ListBuffer<>();
|
||||
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 = new ListBuffer<>();
|
||||
for (TypePathEntry tpe : locs) {
|
||||
loc = loc.append(tpe.tag.tag);
|
||||
loc = loc.append(tpe.arg);
|
||||
}
|
||||
return loc.toList();
|
||||
}
|
||||
}
|
1352
jdkSrc/jdk8/com/sun/tools/javac/code/TypeAnnotations.java
Normal file
1352
jdkSrc/jdk8/com/sun/tools/javac/code/TypeAnnotations.java
Normal file
File diff suppressed because it is too large
Load Diff
240
jdkSrc/jdk8/com/sun/tools/javac/code/TypeTag.java
Normal file
240
jdkSrc/jdk8/com/sun/tools/javac/code/TypeTag.java
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.javac.code;
|
||||
|
||||
import com.sun.source.tree.Tree.Kind;
|
||||
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTag.NumericClasses.*;
|
||||
|
||||
/** An interface for type tag values, which distinguish between different
|
||||
* sorts of types.
|
||||
*
|
||||
* <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 enum TypeTag {
|
||||
/** The tag of the basic type `byte'.
|
||||
*/
|
||||
BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, true),
|
||||
|
||||
/** The tag of the basic type `char'.
|
||||
*/
|
||||
CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, true),
|
||||
|
||||
/** The tag of the basic type `short'.
|
||||
*/
|
||||
SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, true),
|
||||
|
||||
/** The tag of the basic type `long'.
|
||||
*/
|
||||
LONG(LONG_CLASS, LONG_SUPERCLASSES, true),
|
||||
|
||||
/** The tag of the basic type `float'.
|
||||
*/
|
||||
FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, true),
|
||||
/** The tag of the basic type `int'.
|
||||
*/
|
||||
INT(INT_CLASS, INT_SUPERCLASSES, true),
|
||||
/** The tag of the basic type `double'.
|
||||
*/
|
||||
DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, true),
|
||||
/** The tag of the basic type `boolean'.
|
||||
*/
|
||||
BOOLEAN(0, 0, true),
|
||||
|
||||
/** The tag of the type `void'.
|
||||
*/
|
||||
VOID,
|
||||
|
||||
/** The tag of all class and interface types.
|
||||
*/
|
||||
CLASS,
|
||||
|
||||
/** The tag of all array types.
|
||||
*/
|
||||
ARRAY,
|
||||
|
||||
/** The tag of all (monomorphic) method types.
|
||||
*/
|
||||
METHOD,
|
||||
|
||||
/** The tag of all package "types".
|
||||
*/
|
||||
PACKAGE,
|
||||
|
||||
/** The tag of all (source-level) type variables.
|
||||
*/
|
||||
TYPEVAR,
|
||||
|
||||
/** The tag of all type arguments.
|
||||
*/
|
||||
WILDCARD,
|
||||
|
||||
/** The tag of all polymorphic (method-) types.
|
||||
*/
|
||||
FORALL,
|
||||
|
||||
/** The tag of deferred expression types in method context
|
||||
*/
|
||||
DEFERRED,
|
||||
|
||||
/** The tag of the bottom type {@code <null>}.
|
||||
*/
|
||||
BOT,
|
||||
|
||||
/** The tag of a missing type.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/** The tag of the error type.
|
||||
*/
|
||||
ERROR,
|
||||
|
||||
/** The tag of an unknown type
|
||||
*/
|
||||
UNKNOWN,
|
||||
|
||||
/** The tag of all instantiatable type variables.
|
||||
*/
|
||||
UNDETVAR,
|
||||
|
||||
/** Pseudo-types, these are special tags
|
||||
*/
|
||||
UNINITIALIZED_THIS,
|
||||
|
||||
UNINITIALIZED_OBJECT;
|
||||
|
||||
final int superClasses;
|
||||
final int numericClass;
|
||||
final boolean isPrimitive;
|
||||
|
||||
private TypeTag() {
|
||||
this(0, 0, false);
|
||||
}
|
||||
|
||||
private TypeTag(int numericClass, int superClasses, boolean isPrimitive) {
|
||||
this.superClasses = superClasses;
|
||||
this.numericClass = numericClass;
|
||||
this.isPrimitive = isPrimitive;
|
||||
}
|
||||
|
||||
public static class NumericClasses {
|
||||
public static final int BYTE_CLASS = 1;
|
||||
public static final int CHAR_CLASS = 2;
|
||||
public static final int SHORT_CLASS = 4;
|
||||
public static final int INT_CLASS = 8;
|
||||
public static final int LONG_CLASS = 16;
|
||||
public static final int FLOAT_CLASS = 32;
|
||||
public static final int DOUBLE_CLASS = 64;
|
||||
|
||||
static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS |
|
||||
LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
|
||||
|
||||
static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS |
|
||||
LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
|
||||
|
||||
static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS |
|
||||
LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
|
||||
|
||||
static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
|
||||
|
||||
static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
|
||||
|
||||
static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS;
|
||||
}
|
||||
|
||||
public boolean isStrictSubRangeOf(TypeTag tag) {
|
||||
/* Please don't change the implementation of this method to call method
|
||||
* isSubRangeOf. Both methods are called from hotspot code, the current
|
||||
* implementation is better performance-wise than the commented modification.
|
||||
*/
|
||||
return (this.superClasses & tag.numericClass) != 0 && this != tag;
|
||||
}
|
||||
|
||||
public boolean isSubRangeOf(TypeTag tag) {
|
||||
return (this.superClasses & tag.numericClass) != 0;
|
||||
}
|
||||
|
||||
/** Returns the number of type tags.
|
||||
*/
|
||||
public static int getTypeTagCount() {
|
||||
// last two tags are not included in the total as long as they are pseudo-types
|
||||
return (UNDETVAR.ordinal() + 1);
|
||||
}
|
||||
|
||||
public Kind getKindLiteral() {
|
||||
switch (this) {
|
||||
case INT:
|
||||
return Kind.INT_LITERAL;
|
||||
case LONG:
|
||||
return Kind.LONG_LITERAL;
|
||||
case FLOAT:
|
||||
return Kind.FLOAT_LITERAL;
|
||||
case DOUBLE:
|
||||
return Kind.DOUBLE_LITERAL;
|
||||
case BOOLEAN:
|
||||
return Kind.BOOLEAN_LITERAL;
|
||||
case CHAR:
|
||||
return Kind.CHAR_LITERAL;
|
||||
case CLASS:
|
||||
return Kind.STRING_LITERAL;
|
||||
case BOT:
|
||||
return Kind.NULL_LITERAL;
|
||||
default:
|
||||
throw new AssertionError("unknown literal kind " + this);
|
||||
}
|
||||
}
|
||||
|
||||
public TypeKind getPrimitiveTypeKind() {
|
||||
switch (this) {
|
||||
case BOOLEAN:
|
||||
return TypeKind.BOOLEAN;
|
||||
case BYTE:
|
||||
return TypeKind.BYTE;
|
||||
case SHORT:
|
||||
return TypeKind.SHORT;
|
||||
case INT:
|
||||
return TypeKind.INT;
|
||||
case LONG:
|
||||
return TypeKind.LONG;
|
||||
case CHAR:
|
||||
return TypeKind.CHAR;
|
||||
case FLOAT:
|
||||
return TypeKind.FLOAT;
|
||||
case DOUBLE:
|
||||
return TypeKind.DOUBLE;
|
||||
case VOID:
|
||||
return TypeKind.VOID;
|
||||
default:
|
||||
throw new AssertionError("unknown primitive type " + this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
4875
jdkSrc/jdk8/com/sun/tools/javac/code/Types.java
Normal file
4875
jdkSrc/jdk8/com/sun/tools/javac/code/Types.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user