--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue May 14 15:04:06 2013 -0700
@@ -30,6 +30,8 @@
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.comp.*;
import com.sun.tools.javac.tree.*;
@@ -47,7 +49,6 @@
import static com.sun.tools.javac.jvm.CRTFlags.*;
import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
/** This pass maps flat Java (i.e. without inner classes) to bytecodes.
*
@@ -308,7 +309,15 @@
*/
int makeRef(DiagnosticPosition pos, Type type) {
checkDimension(pos, type);
- return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+ if (type.isAnnotated()) {
+ // Treat annotated types separately - we don't want
+ // to collapse all of them - at least for annotated
+ // exceptions.
+ // TODO: review this.
+ return pool.put((Object)type);
+ } else {
+ return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+ }
}
/** Check if the given type is an array with too many dimensions.
@@ -456,7 +465,9 @@
*/
List<JCTree> normalizeDefs(List<JCTree> defs, ClassSymbol c) {
ListBuffer<JCStatement> initCode = new ListBuffer<JCStatement>();
+ ListBuffer<Attribute.TypeCompound> initTAs = new ListBuffer<Attribute.TypeCompound>();
ListBuffer<JCStatement> clinitCode = new ListBuffer<JCStatement>();
+ ListBuffer<Attribute.TypeCompound> clinitTAs = new ListBuffer<Attribute.TypeCompound>();
ListBuffer<JCTree> methodDefs = new ListBuffer<JCTree>();
// Sort definitions into three listbuffers:
// - initCode for instance initializers
@@ -486,6 +497,7 @@
Assignment(sym, vdef.init);
initCode.append(init);
endPosTable.replaceTree(vdef, init);
+ initTAs.addAll(getAndRemoveNonFieldTAs(sym));
} else if (sym.getConstValue() == null) {
// Initialize class (static) variables only if
// they are not compile-time constants.
@@ -493,6 +505,7 @@
Assignment(sym, vdef.init);
clinitCode.append(init);
endPosTable.replaceTree(vdef, init);
+ clinitTAs.addAll(getAndRemoveNonFieldTAs(sym));
} else {
checkStringConstant(vdef.init.pos(), sym.getConstValue());
}
@@ -505,8 +518,10 @@
// Insert any instance initializers into all constructors.
if (initCode.length() != 0) {
List<JCStatement> inits = initCode.toList();
+ initTAs.addAll(c.annotations.getInitTypeAttributes());
+ List<Attribute.TypeCompound> initTAlist = initTAs.toList();
for (JCTree t : methodDefs) {
- normalizeMethod((JCMethodDecl)t, inits);
+ normalizeMethod((JCMethodDecl)t, inits, initTAlist);
}
}
// If there are class initializers, create a <clinit> method
@@ -524,11 +539,31 @@
JCBlock block = make.at(clinitStats.head.pos()).Block(0, clinitStats);
block.endpos = TreeInfo.endPos(clinitStats.last());
methodDefs.append(make.MethodDef(clinit, block));
+
+ if (!clinitTAs.isEmpty())
+ clinit.annotations.appendUniqueTypes(clinitTAs.toList());
+ if (!c.annotations.getClassInitTypeAttributes().isEmpty())
+ clinit.annotations.appendUniqueTypes(c.annotations.getClassInitTypeAttributes());
}
// Return all method definitions.
return methodDefs.toList();
}
+ private List<Attribute.TypeCompound> getAndRemoveNonFieldTAs(VarSymbol sym) {
+ List<TypeCompound> tas = sym.getRawTypeAttributes();
+ ListBuffer<Attribute.TypeCompound> fieldTAs = new ListBuffer<Attribute.TypeCompound>();
+ ListBuffer<Attribute.TypeCompound> nonfieldTAs = new ListBuffer<Attribute.TypeCompound>();
+ for (TypeCompound ta : tas) {
+ if (ta.position.type == TargetType.FIELD) {
+ fieldTAs.add(ta);
+ } else {
+ nonfieldTAs.add(ta);
+ }
+ }
+ sym.annotations.setTypeAttributes(fieldTAs.toList());
+ return nonfieldTAs.toList();
+ }
+
/** Check a constant value and report if it is a string that is
* too large.
*/
@@ -546,8 +581,9 @@
* @param md The tree potentially representing a
* constructor's definition.
* @param initCode The list of instance initializer statements.
+ * @param initTAs Type annotations from the initializer expression.
*/
- void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode) {
+ void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<TypeCompound> initTAs) {
if (md.name == names.init && TreeInfo.isInitialConstructor(md)) {
// We are seeing a constructor that does not call another
// constructor of the same class.
@@ -581,6 +617,8 @@
md.body.stats = newstats.toList();
if (md.body.endpos == Position.NOPOS)
md.body.endpos = TreeInfo.endPos(md.body.stats.last());
+
+ md.sym.annotations.appendUniqueTypes(initTAs);
}
}
@@ -1527,6 +1565,11 @@
registerCatch(tree.pos(),
startpc, end, code.curPc(),
catchType);
+ if (subCatch.type.isAnnotated()) {
+ // All compounds share the same position, simply update the
+ // first one.
+ subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+ }
}
gaps = gaps.tail;
startpc = gaps.head.intValue();
@@ -1538,6 +1581,11 @@
registerCatch(tree.pos(),
startpc, endpc, code.curPc(),
catchType);
+ if (subCatch.type.isAnnotated()) {
+ // All compounds share the same position, simply update the
+ // first one.
+ subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+ }
}
}
VarSymbol exparam = tree.param.sym;
@@ -1783,42 +1831,44 @@
result = items.makeStackItem(pt);
}
- private void setTypeAnnotationPositions(int treePos) {
- MethodSymbol meth = code.meth;
+ private void setTypeAnnotationPositions(int treePos) {
+ MethodSymbol meth = code.meth;
+ boolean initOrClinit = code.meth.getKind() == javax.lang.model.element.ElementKind.CONSTRUCTOR
+ || code.meth.getKind() == javax.lang.model.element.ElementKind.STATIC_INIT;
- for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
+ for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
- if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR
- && code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT)
- return;
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
+
+ if (!initOrClinit)
+ return;
- for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
+ for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
- ClassSymbol clazz = meth.enclClass();
- for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
- if (!s.getKind().isField())
- continue;
- for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
- }
- }
+ ClassSymbol clazz = meth.enclClass();
+ for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
+ if (!s.getKind().isField())
+ continue;
+
+ for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
+ }
+ }
public void visitNewClass(JCNewClass tree) {
// Enclosing instances or anonymous classes should have been eliminated