Tue, 19 Jan 2010 14:28:45 -0800
6917067: refactor type annotations code from TransTypes into new TypeAnnotations class
Reviewed-by: jjg, darcy
Contributed-by: mali@csail.mit.edu, mernst@cs.washington.edu
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Tue Jan 19 14:28:45 2010 -0800 1.3 @@ -0,0 +1,411 @@ 1.4 +/* 1.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.code; 1.30 + 1.31 +import javax.lang.model.element.ElementKind; 1.32 + 1.33 +import com.sun.tools.javac.code.Symbol.VarSymbol; 1.34 +import com.sun.tools.javac.tree.JCTree; 1.35 +import com.sun.tools.javac.tree.TreeInfo; 1.36 +import com.sun.tools.javac.tree.TreeScanner; 1.37 +import com.sun.tools.javac.tree.JCTree.*; 1.38 +import com.sun.tools.javac.util.Context; 1.39 +import com.sun.tools.javac.util.List; 1.40 +import com.sun.tools.javac.util.ListBuffer; 1.41 + 1.42 +/** 1.43 + * Contains operations specific to processing type annotations 1.44 + */ 1.45 +public class TypeAnnotations { 1.46 + private static final Context.Key<TypeAnnotations> key 1.47 + = new Context.Key<TypeAnnotations>(); 1.48 + 1.49 + public static TypeAnnotations instance(Context context) { 1.50 + TypeAnnotations instance = context.get(key); 1.51 + if (instance == null) 1.52 + instance = new TypeAnnotations(context); 1.53 + return instance; 1.54 + } 1.55 + 1.56 + protected TypeAnnotations(Context context) { 1.57 + context.put(key, this); 1.58 + } 1.59 + 1.60 + public void taFillAndLift(JCClassDecl tree, boolean visitBodies) { 1.61 + new TypeAnnotationPositions().scan(tree); 1.62 + new TypeAnnotationLift().scan(tree); 1.63 + } 1.64 + 1.65 + private static class TypeAnnotationPositions extends TreeScanner { 1.66 + 1.67 + private ListBuffer<JCTree> frames = ListBuffer.lb(); 1.68 + private void push(JCTree t) { frames = frames.prepend(t); } 1.69 + private JCTree pop() { return frames.next(); } 1.70 + private JCTree peek2() { return frames.toList().tail.head; } 1.71 + 1.72 + @Override 1.73 + public void scan(JCTree tree) { 1.74 + push(tree); 1.75 + super.scan(tree); 1.76 + pop(); 1.77 + } 1.78 + 1.79 + private boolean inClass = false; 1.80 + 1.81 + @Override 1.82 + public void visitClassDef(JCClassDecl tree) { 1.83 + if (!inClass) { 1.84 + // Do not recurse into nested and inner classes since 1.85 + // TransTypes.visitClassDef makes an invocation for each class 1.86 + // separately. 1.87 + inClass = true; 1.88 + try { 1.89 + super.visitClassDef(tree); 1.90 + } finally { 1.91 + inClass = false; 1.92 + } 1.93 + } 1.94 + } 1.95 + 1.96 + private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame, 1.97 + List<JCTree> path, TypeAnnotationPosition p) { 1.98 + switch (frame.getKind()) { 1.99 + case TYPE_CAST: 1.100 + p.type = TargetType.TYPECAST; 1.101 + p.pos = frame.pos; 1.102 + return p; 1.103 + 1.104 + case INSTANCE_OF: 1.105 + p.type = TargetType.INSTANCEOF; 1.106 + p.pos = frame.pos; 1.107 + return p; 1.108 + 1.109 + case NEW_CLASS: 1.110 + p.type = TargetType.NEW; 1.111 + p.pos = frame.pos; 1.112 + return p; 1.113 + 1.114 + case NEW_ARRAY: 1.115 + p.type = TargetType.NEW; 1.116 + p.pos = frame.pos; 1.117 + return p; 1.118 + 1.119 + case CLASS: 1.120 + p.pos = frame.pos; 1.121 + if (((JCClassDecl)frame).extending == tree) { 1.122 + p.type = TargetType.CLASS_EXTENDS; 1.123 + p.type_index = -1; 1.124 + } else if (((JCClassDecl)frame).implementing.contains(tree)) { 1.125 + p.type = TargetType.CLASS_EXTENDS; 1.126 + p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree); 1.127 + } else if (((JCClassDecl)frame).typarams.contains(tree)) { 1.128 + p.type = TargetType.CLASS_TYPE_PARAMETER; 1.129 + p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree); 1.130 + } else 1.131 + throw new AssertionError(); 1.132 + return p; 1.133 + 1.134 + case METHOD: { 1.135 + JCMethodDecl frameMethod = (JCMethodDecl)frame; 1.136 + p.pos = frame.pos; 1.137 + if (frameMethod.receiverAnnotations.contains(tree)) 1.138 + p.type = TargetType.METHOD_RECEIVER; 1.139 + else if (frameMethod.thrown.contains(tree)) { 1.140 + p.type = TargetType.THROWS; 1.141 + p.type_index = frameMethod.thrown.indexOf(tree); 1.142 + } else if (((JCMethodDecl)frame).restype == tree) { 1.143 + p.type = TargetType.METHOD_RETURN_GENERIC_OR_ARRAY; 1.144 + } else if (frameMethod.typarams.contains(tree)) { 1.145 + p.type = TargetType.METHOD_TYPE_PARAMETER; 1.146 + p.parameter_index = frameMethod.typarams.indexOf(tree); 1.147 + } else 1.148 + throw new AssertionError(); 1.149 + return p; 1.150 + } 1.151 + case MEMBER_SELECT: { 1.152 + JCFieldAccess fieldFrame = (JCFieldAccess)frame; 1.153 + if ("class".contentEquals(fieldFrame.name)) { 1.154 + p.type = TargetType.CLASS_LITERAL; 1.155 + if (fieldFrame.selected instanceof JCAnnotatedType) { 1.156 + p.pos = TreeInfo.typeIn(fieldFrame).pos; 1.157 + } else if (fieldFrame.selected instanceof JCArrayTypeTree) { 1.158 + p.pos = fieldFrame.selected.pos; 1.159 + } 1.160 + } else 1.161 + throw new AssertionError(); 1.162 + return p; 1.163 + } 1.164 + case PARAMETERIZED_TYPE: { 1.165 + TypeAnnotationPosition nextP; 1.166 + if (((JCTypeApply)frame).clazz == tree) 1.167 + nextP = p; // generic: RAW; noop 1.168 + else if (((JCTypeApply)frame).arguments.contains(tree)) 1.169 + p.location = p.location.prepend( 1.170 + ((JCTypeApply)frame).arguments.indexOf(tree)); 1.171 + else 1.172 + throw new AssertionError(); 1.173 + 1.174 + List<JCTree> newPath = path.tail; 1.175 + return resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.176 + } 1.177 + 1.178 + case ARRAY_TYPE: { 1.179 + p.location = p.location.prepend(0); 1.180 + List<JCTree> newPath = path.tail; 1.181 + return resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.182 + } 1.183 + 1.184 + case TYPE_PARAMETER: 1.185 + if (path.tail.tail.head.getTag() == JCTree.CLASSDEF) { 1.186 + JCClassDecl clazz = (JCClassDecl)path.tail.tail.head; 1.187 + p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND; 1.188 + p.parameter_index = clazz.typarams.indexOf(path.tail.head); 1.189 + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); 1.190 + } else if (path.tail.tail.head.getTag() == JCTree.METHODDEF) { 1.191 + JCMethodDecl method = (JCMethodDecl)path.tail.tail.head; 1.192 + p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND; 1.193 + p.parameter_index = method.typarams.indexOf(path.tail.head); 1.194 + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); 1.195 + } else 1.196 + throw new AssertionError(); 1.197 + p.pos = frame.pos; 1.198 + return p; 1.199 + 1.200 + case VARIABLE: 1.201 + VarSymbol v = ((JCVariableDecl)frame).sym; 1.202 + p.pos = frame.pos; 1.203 + switch (v.getKind()) { 1.204 + case LOCAL_VARIABLE: 1.205 + p.type = TargetType.LOCAL_VARIABLE; break; 1.206 + case FIELD: 1.207 + p.type = TargetType.FIELD_GENERIC_OR_ARRAY; break; 1.208 + case PARAMETER: 1.209 + p.type = TargetType.METHOD_PARAMETER_GENERIC_OR_ARRAY; 1.210 + p.parameter_index = methodParamIndex(path, frame); 1.211 + break; 1.212 + default: throw new AssertionError(); 1.213 + } 1.214 + return p; 1.215 + 1.216 + case ANNOTATED_TYPE: { 1.217 + List<JCTree> newPath = path.tail; 1.218 + return resolveFrame(newPath.head, newPath.tail.head, 1.219 + newPath, p); 1.220 + } 1.221 + 1.222 + case METHOD_INVOCATION: { 1.223 + JCMethodInvocation invocation = (JCMethodInvocation)frame; 1.224 + if (!invocation.typeargs.contains(tree)) 1.225 + throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation); 1.226 + p.type = TargetType.METHOD_TYPE_ARGUMENT; 1.227 + p.pos = invocation.pos; 1.228 + p.type_index = invocation.typeargs.indexOf(tree); 1.229 + return p; 1.230 + } 1.231 + 1.232 + case EXTENDS_WILDCARD: 1.233 + case SUPER_WILDCARD: { 1.234 + p.type = TargetType.WILDCARD_BOUND; 1.235 + List<JCTree> newPath = path.tail; 1.236 + 1.237 + TypeAnnotationPosition wildcard = 1.238 + resolveFrame(newPath.head, newPath.tail.head, newPath, 1.239 + new TypeAnnotationPosition()); 1.240 + if (!wildcard.location.isEmpty()) 1.241 + wildcard.type = wildcard.type.getGenericComplement(); 1.242 + p.wildcard_position = wildcard; 1.243 + p.pos = frame.pos; 1.244 + return p; 1.245 + } 1.246 + } 1.247 + return p; 1.248 + } 1.249 + 1.250 + @Override 1.251 + public void visitApply(JCMethodInvocation tree) { 1.252 + scan(tree.meth); 1.253 + scan(tree.typeargs); 1.254 + scan(tree.args); 1.255 + } 1.256 + 1.257 + private void setTypeAnnotationPos(List<JCTypeAnnotation> annotations, TypeAnnotationPosition position) { 1.258 + for (JCTypeAnnotation anno : annotations) { 1.259 + anno.annotation_position = position; 1.260 + anno.attribute_field.position = position; 1.261 + } 1.262 + } 1.263 + 1.264 + @Override 1.265 + public void visitNewArray(JCNewArray tree) { 1.266 + findPosition(tree, tree, tree.annotations); 1.267 + int dimAnnosCount = tree.dimAnnotations.size(); 1.268 + 1.269 + // handle annotations associated with dimentions 1.270 + for (int i = 0; i < dimAnnosCount; ++i) { 1.271 + TypeAnnotationPosition p = new TypeAnnotationPosition(); 1.272 + p.type = TargetType.NEW_GENERIC_OR_ARRAY; 1.273 + p.pos = tree.pos; 1.274 + p.location = p.location.append(i); 1.275 + setTypeAnnotationPos(tree.dimAnnotations.get(i), p); 1.276 + } 1.277 + 1.278 + // handle "free" annotations 1.279 + int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1; 1.280 + JCExpression elemType = tree.elemtype; 1.281 + while (elemType != null) { 1.282 + if (elemType.getTag() == JCTree.ANNOTATED_TYPE) { 1.283 + JCAnnotatedType at = (JCAnnotatedType)elemType; 1.284 + TypeAnnotationPosition p = new TypeAnnotationPosition(); 1.285 + p.type = TargetType.NEW_GENERIC_OR_ARRAY; 1.286 + p.pos = tree.pos; 1.287 + p.location = p.location.append(i); 1.288 + setTypeAnnotationPos(at.annotations, p); 1.289 + elemType = at.underlyingType; 1.290 + } else if (elemType.getTag() == JCTree.TYPEARRAY) { 1.291 + ++i; 1.292 + elemType = ((JCArrayTypeTree)elemType).elemtype; 1.293 + } else 1.294 + break; 1.295 + } 1.296 + 1.297 + // find annotations locations of initializer elements 1.298 + scan(tree.elems); 1.299 + } 1.300 + 1.301 + @Override 1.302 + public void visitAnnotatedType(JCAnnotatedType tree) { 1.303 + findPosition(tree, peek2(), tree.annotations); 1.304 + super.visitAnnotatedType(tree); 1.305 + } 1.306 + 1.307 + @Override 1.308 + public void visitMethodDef(JCMethodDecl tree) { 1.309 + TypeAnnotationPosition p = new TypeAnnotationPosition(); 1.310 + p.type = TargetType.METHOD_RECEIVER; 1.311 + setTypeAnnotationPos(tree.receiverAnnotations, p); 1.312 + super.visitMethodDef(tree); 1.313 + } 1.314 + @Override 1.315 + public void visitTypeParameter(JCTypeParameter tree) { 1.316 + findPosition(tree, peek2(), tree.annotations); 1.317 + super.visitTypeParameter(tree); 1.318 + } 1.319 + 1.320 + void findPosition(JCTree tree, JCTree frame, List<JCTypeAnnotation> annotations) { 1.321 + if (!annotations.isEmpty()) { 1.322 + TypeAnnotationPosition p = 1.323 + resolveFrame(tree, frame, frames.toList(), 1.324 + new TypeAnnotationPosition()); 1.325 + if (!p.location.isEmpty()) 1.326 + p.type = p.type.getGenericComplement(); 1.327 + setTypeAnnotationPos(annotations, p); 1.328 + } 1.329 + } 1.330 + 1.331 + private int methodParamIndex(List<JCTree> path, JCTree param) { 1.332 + List<JCTree> curr = path; 1.333 + if (curr.head != param) 1.334 + curr = path.tail; 1.335 + JCMethodDecl method = (JCMethodDecl)curr.tail.head; 1.336 + return method.params.indexOf(param); 1.337 + } 1.338 + } 1.339 + 1.340 + private static class TypeAnnotationLift extends TreeScanner { 1.341 + List<Attribute.TypeCompound> recordedTypeAnnotations = List.nil(); 1.342 + 1.343 + boolean isInner = false; 1.344 + @Override 1.345 + public void visitClassDef(JCClassDecl tree) { 1.346 + if (isInner) { 1.347 + // tree is an inner class tree. stop now. 1.348 + // TransTypes.visitClassDef makes an invocation for each class 1.349 + // separately. 1.350 + return; 1.351 + } 1.352 + isInner = true; 1.353 + List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations; 1.354 + recordedTypeAnnotations = List.nil(); 1.355 + try { 1.356 + super.visitClassDef(tree); 1.357 + } finally { 1.358 + tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations); 1.359 + recordedTypeAnnotations = prevTAs; 1.360 + } 1.361 + } 1.362 + 1.363 + @Override 1.364 + public void visitMethodDef(JCMethodDecl tree) { 1.365 + List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations; 1.366 + recordedTypeAnnotations = List.nil(); 1.367 + try { 1.368 + super.visitMethodDef(tree); 1.369 + } finally { 1.370 + tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations); 1.371 + recordedTypeAnnotations = prevTAs; 1.372 + } 1.373 + } 1.374 + 1.375 + @Override 1.376 + public void visitVarDef(JCVariableDecl tree) { 1.377 + List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations; 1.378 + recordedTypeAnnotations = List.nil(); 1.379 + ElementKind kind = tree.sym.getKind(); 1.380 + if (kind == ElementKind.LOCAL_VARIABLE && tree.mods.annotations.nonEmpty()) { 1.381 + // need to lift the annotations 1.382 + TypeAnnotationPosition position = new TypeAnnotationPosition(); 1.383 + position.pos = tree.pos; 1.384 + position.type = TargetType.LOCAL_VARIABLE; 1.385 + for (Attribute.Compound attribute : tree.sym.attributes_field) { 1.386 + Attribute.TypeCompound tc = 1.387 + new Attribute.TypeCompound(attribute.type, attribute.values, position); 1.388 + recordedTypeAnnotations = recordedTypeAnnotations.append(tc); 1.389 + } 1.390 + } 1.391 + try { 1.392 + super.visitVarDef(tree); 1.393 + } finally { 1.394 + if (kind.isField() || kind == ElementKind.LOCAL_VARIABLE) 1.395 + tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations); 1.396 + recordedTypeAnnotations = kind.isField() ? prevTAs : prevTAs.appendList(recordedTypeAnnotations); 1.397 + } 1.398 + } 1.399 + 1.400 + @Override 1.401 + public void visitApply(JCMethodInvocation tree) { 1.402 + scan(tree.meth); 1.403 + scan(tree.typeargs); 1.404 + scan(tree.args); 1.405 + } 1.406 + 1.407 + public void visitAnnotation(JCAnnotation tree) { 1.408 + if (tree instanceof JCTypeAnnotation) 1.409 + recordedTypeAnnotations = recordedTypeAnnotations.append(((JCTypeAnnotation)tree).attribute_field); 1.410 + super.visitAnnotation(tree); 1.411 + } 1.412 + } 1.413 + 1.414 +}
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Jan 15 15:37:13 2010 -0800 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Tue Jan 19 14:28:45 2010 -0800 2.3 @@ -61,8 +61,6 @@ 2.4 return instance; 2.5 } 2.6 2.7 - private boolean debugJSR308; 2.8 - 2.9 private Names names; 2.10 private Log log; 2.11 private Symtab syms; 2.12 @@ -71,6 +69,7 @@ 2.13 private boolean allowEnums; 2.14 private Types types; 2.15 private final Resolve resolve; 2.16 + private final TypeAnnotations typeAnnotations; 2.17 2.18 /** 2.19 * Flag to indicate whether or not to generate bridge methods. 2.20 @@ -92,7 +91,7 @@ 2.21 types = Types.instance(context); 2.22 make = TreeMaker.instance(context); 2.23 resolve = Resolve.instance(context); 2.24 - debugJSR308 = Options.instance(context).get("TA:trans") != null; 2.25 + typeAnnotations = TypeAnnotations.instance(context); 2.26 } 2.27 2.28 /** A hashtable mapping bridge methods to the methods they override after 2.29 @@ -440,8 +439,7 @@ 2.30 } 2.31 2.32 public void visitClassDef(JCClassDecl tree) { 2.33 - new TypeAnnotationPositions().scan(tree); 2.34 - new TypeAnnotationLift().scan(tree); 2.35 + typeAnnotations.taFillAndLift(tree, true); 2.36 translateClass(tree.sym); 2.37 result = tree; 2.38 } 2.39 @@ -801,359 +799,4 @@ 2.40 pt = null; 2.41 return translate(cdef, null); 2.42 } 2.43 - 2.44 - private class TypeAnnotationPositions extends TreeScanner { 2.45 - 2.46 - private ListBuffer<JCTree> frames = ListBuffer.lb(); 2.47 - private void push(JCTree t) { frames = frames.prepend(t); } 2.48 - private JCTree pop() { return frames.next(); } 2.49 - private JCTree peek() { return frames.first(); } 2.50 - private JCTree peek2() { return frames.toList().tail.head; } 2.51 - 2.52 - @Override 2.53 - public void scan(JCTree tree) { 2.54 - push(tree); 2.55 - super.scan(tree); 2.56 - pop(); 2.57 - } 2.58 - 2.59 - private boolean inClass = false; 2.60 - 2.61 - @Override 2.62 - public void visitClassDef(JCClassDecl tree) { 2.63 - if (!inClass) { 2.64 - // Do not recurse into nested and inner classes since 2.65 - // TransTypes.visitClassDef makes an invocation for each class 2.66 - // separately. 2.67 - inClass = true; 2.68 - try { 2.69 - super.visitClassDef(tree); 2.70 - } finally { 2.71 - inClass = false; 2.72 - } 2.73 - } 2.74 - } 2.75 - 2.76 - private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame, 2.77 - List<JCTree> path, TypeAnnotationPosition p) { 2.78 - switch (frame.getKind()) { 2.79 - case TYPE_CAST: 2.80 - p.type = TargetType.TYPECAST; 2.81 - p.pos = frame.pos; 2.82 - return p; 2.83 - 2.84 - case INSTANCE_OF: 2.85 - p.type = TargetType.INSTANCEOF; 2.86 - p.pos = frame.pos; 2.87 - return p; 2.88 - 2.89 - case NEW_CLASS: 2.90 - p.type = TargetType.NEW; 2.91 - p.pos = frame.pos; 2.92 - return p; 2.93 - 2.94 - case NEW_ARRAY: 2.95 - p.type = TargetType.NEW; 2.96 - p.pos = frame.pos; 2.97 - return p; 2.98 - 2.99 - case CLASS: 2.100 - p.pos = frame.pos; 2.101 - if (((JCClassDecl)frame).extending == tree) { 2.102 - p.type = TargetType.CLASS_EXTENDS; 2.103 - p.type_index = -1; 2.104 - } else if (((JCClassDecl)frame).implementing.contains(tree)) { 2.105 - p.type = TargetType.CLASS_EXTENDS; 2.106 - p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree); 2.107 - } else if (((JCClassDecl)frame).typarams.contains(tree)) { 2.108 - p.type = TargetType.CLASS_TYPE_PARAMETER; 2.109 - p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree); 2.110 - } else 2.111 - throw new AssertionError(); 2.112 - return p; 2.113 - 2.114 - case METHOD: { 2.115 - JCMethodDecl frameMethod = (JCMethodDecl)frame; 2.116 - p.pos = frame.pos; 2.117 - if (frameMethod.receiverAnnotations.contains(tree)) 2.118 - p.type = TargetType.METHOD_RECEIVER; 2.119 - else if (frameMethod.thrown.contains(tree)) { 2.120 - p.type = TargetType.THROWS; 2.121 - p.type_index = frameMethod.thrown.indexOf(tree); 2.122 - } else if (((JCMethodDecl)frame).restype == tree) { 2.123 - p.type = TargetType.METHOD_RETURN_GENERIC_OR_ARRAY; 2.124 - } else if (frameMethod.typarams.contains(tree)) { 2.125 - p.type = TargetType.METHOD_TYPE_PARAMETER; 2.126 - p.parameter_index = frameMethod.typarams.indexOf(tree); 2.127 - } else 2.128 - throw new AssertionError(); 2.129 - return p; 2.130 - } 2.131 - case MEMBER_SELECT: { 2.132 - JCFieldAccess fieldFrame = (JCFieldAccess)frame; 2.133 - if (fieldFrame.name == names._class) { 2.134 - p.type = TargetType.CLASS_LITERAL; 2.135 - if (fieldFrame.selected instanceof JCAnnotatedType) { 2.136 - p.pos = TreeInfo.typeIn(fieldFrame).pos; 2.137 - } else if (fieldFrame.selected instanceof JCArrayTypeTree) { 2.138 - p.pos = fieldFrame.selected.pos; 2.139 - } 2.140 - } else 2.141 - throw new AssertionError(); 2.142 - return p; 2.143 - } 2.144 - case PARAMETERIZED_TYPE: { 2.145 - TypeAnnotationPosition nextP; 2.146 - if (((JCTypeApply)frame).clazz == tree) 2.147 - nextP = p; // generic: RAW; noop 2.148 - else if (((JCTypeApply)frame).arguments.contains(tree)) 2.149 - p.location = p.location.prepend( 2.150 - ((JCTypeApply)frame).arguments.indexOf(tree)); 2.151 - else 2.152 - throw new AssertionError(); 2.153 - 2.154 - List<JCTree> newPath = path.tail; 2.155 - return resolveFrame(newPath.head, newPath.tail.head, newPath, p); 2.156 - } 2.157 - 2.158 - case ARRAY_TYPE: { 2.159 - p.location = p.location.prepend(0); 2.160 - List<JCTree> newPath = path.tail; 2.161 - return resolveFrame(newPath.head, newPath.tail.head, newPath, p); 2.162 - } 2.163 - 2.164 - case TYPE_PARAMETER: 2.165 - if (path.tail.tail.head.getTag() == JCTree.CLASSDEF) { 2.166 - JCClassDecl clazz = (JCClassDecl)path.tail.tail.head; 2.167 - p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND; 2.168 - p.parameter_index = clazz.typarams.indexOf(path.tail.head); 2.169 - p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); 2.170 - } else if (path.tail.tail.head.getTag() == JCTree.METHODDEF) { 2.171 - JCMethodDecl method = (JCMethodDecl)path.tail.tail.head; 2.172 - p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND; 2.173 - p.parameter_index = method.typarams.indexOf(path.tail.head); 2.174 - p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); 2.175 - } else 2.176 - throw new AssertionError(); 2.177 - p.pos = frame.pos; 2.178 - return p; 2.179 - 2.180 - case VARIABLE: 2.181 - VarSymbol v = ((JCVariableDecl)frame).sym; 2.182 - p.pos = frame.pos; 2.183 - switch (v.getKind()) { 2.184 - case LOCAL_VARIABLE: 2.185 - p.type = TargetType.LOCAL_VARIABLE; break; 2.186 - case FIELD: 2.187 - p.type = TargetType.FIELD_GENERIC_OR_ARRAY; break; 2.188 - case PARAMETER: 2.189 - p.type = TargetType.METHOD_PARAMETER_GENERIC_OR_ARRAY; 2.190 - p.parameter_index = methodParamIndex(path, frame); 2.191 - break; 2.192 - default: throw new AssertionError(); 2.193 - } 2.194 - return p; 2.195 - 2.196 - case ANNOTATED_TYPE: { 2.197 - List<JCTree> newPath = path.tail; 2.198 - return resolveFrame(newPath.head, newPath.tail.head, 2.199 - newPath, p); 2.200 - } 2.201 - 2.202 - case METHOD_INVOCATION: { 2.203 - JCMethodInvocation invocation = (JCMethodInvocation)frame; 2.204 - if (!invocation.typeargs.contains(tree)) 2.205 - throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation); 2.206 - p.type = TargetType.METHOD_TYPE_ARGUMENT; 2.207 - p.pos = invocation.pos; 2.208 - p.type_index = invocation.typeargs.indexOf(tree); 2.209 - return p; 2.210 - } 2.211 - 2.212 - case EXTENDS_WILDCARD: 2.213 - case SUPER_WILDCARD: { 2.214 - p.type = TargetType.WILDCARD_BOUND; 2.215 - List<JCTree> newPath = path.tail; 2.216 - 2.217 - TypeAnnotationPosition wildcard = 2.218 - resolveFrame(newPath.head, newPath.tail.head, newPath, 2.219 - new TypeAnnotationPosition()); 2.220 - if (!wildcard.location.isEmpty()) 2.221 - wildcard.type = wildcard.type.getGenericComplement(); 2.222 - p.wildcard_position = wildcard; 2.223 - p.pos = frame.pos; 2.224 - return p; 2.225 - } 2.226 - } 2.227 - return p; 2.228 - } 2.229 - 2.230 - @Override 2.231 - public void visitApply(JCMethodInvocation tree) { 2.232 - scan(tree.meth); 2.233 - scan(tree.typeargs); 2.234 - scan(tree.args); 2.235 - } 2.236 - 2.237 - private void setTypeAnnotationPos(List<JCTypeAnnotation> annotations, TypeAnnotationPosition position) { 2.238 - for (JCTypeAnnotation anno : annotations) { 2.239 - anno.annotation_position = position; 2.240 - anno.attribute_field.position = position; 2.241 - } 2.242 - } 2.243 - 2.244 - @Override 2.245 - public void visitNewArray(JCNewArray tree) { 2.246 - findPosition(tree, tree, tree.annotations); 2.247 - int dimAnnosCount = tree.dimAnnotations.size(); 2.248 - 2.249 - // handle annotations associated with dimentions 2.250 - for (int i = 0; i < dimAnnosCount; ++i) { 2.251 - TypeAnnotationPosition p = new TypeAnnotationPosition(); 2.252 - p.type = TargetType.NEW_GENERIC_OR_ARRAY; 2.253 - p.pos = tree.pos; 2.254 - p.location = p.location.append(i); 2.255 - setTypeAnnotationPos(tree.dimAnnotations.get(i), p); 2.256 - } 2.257 - 2.258 - // handle "free" annotations 2.259 - int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1; 2.260 - JCExpression elemType = tree.elemtype; 2.261 - while (elemType != null) { 2.262 - if (elemType.getTag() == JCTree.ANNOTATED_TYPE) { 2.263 - JCAnnotatedType at = (JCAnnotatedType)elemType; 2.264 - TypeAnnotationPosition p = new TypeAnnotationPosition(); 2.265 - p.type = TargetType.NEW_GENERIC_OR_ARRAY; 2.266 - p.pos = tree.pos; 2.267 - p.location = p.location.append(i); 2.268 - setTypeAnnotationPos(at.annotations, p); 2.269 - elemType = at.underlyingType; 2.270 - } else if (elemType.getTag() == JCTree.TYPEARRAY) { 2.271 - ++i; 2.272 - elemType = ((JCArrayTypeTree)elemType).elemtype; 2.273 - } else 2.274 - break; 2.275 - } 2.276 - 2.277 - // find annotations locations of initializer elements 2.278 - scan(tree.elems); 2.279 - } 2.280 - 2.281 - @Override 2.282 - public void visitAnnotatedType(JCAnnotatedType tree) { 2.283 - findPosition(tree, peek2(), tree.annotations); 2.284 - super.visitAnnotatedType(tree); 2.285 - } 2.286 - 2.287 - @Override 2.288 - public void visitMethodDef(JCMethodDecl tree) { 2.289 - TypeAnnotationPosition p = new TypeAnnotationPosition(); 2.290 - p.type = TargetType.METHOD_RECEIVER; 2.291 - setTypeAnnotationPos(tree.receiverAnnotations, p); 2.292 - super.visitMethodDef(tree); 2.293 - } 2.294 - @Override 2.295 - public void visitTypeParameter(JCTypeParameter tree) { 2.296 - findPosition(tree, peek2(), tree.annotations); 2.297 - super.visitTypeParameter(tree); 2.298 - } 2.299 - 2.300 - void findPosition(JCTree tree, JCTree frame, List<JCTypeAnnotation> annotations) { 2.301 - if (!annotations.isEmpty()) { 2.302 - TypeAnnotationPosition p = 2.303 - resolveFrame(tree, frame, frames.toList(), 2.304 - new TypeAnnotationPosition()); 2.305 - if (!p.location.isEmpty()) 2.306 - p.type = p.type.getGenericComplement(); 2.307 - setTypeAnnotationPos(annotations, p); 2.308 - if (debugJSR308) { 2.309 - System.out.println("trans: " + tree); 2.310 - System.out.println(" target: " + p); 2.311 - } 2.312 - } 2.313 - } 2.314 - 2.315 - private int methodParamIndex(List<JCTree> path, JCTree param) { 2.316 - List<JCTree> curr = path; 2.317 - if (curr.head != param) 2.318 - curr = path.tail; 2.319 - JCMethodDecl method = (JCMethodDecl)curr.tail.head; 2.320 - return method.params.indexOf(param); 2.321 - } 2.322 - } 2.323 - 2.324 - private class TypeAnnotationLift extends TreeScanner { 2.325 - List<Attribute.TypeCompound> recordedTypeAnnotations = List.nil(); 2.326 - 2.327 - boolean isInner = false; 2.328 - @Override 2.329 - public void visitClassDef(JCClassDecl tree) { 2.330 - if (isInner) { 2.331 - // tree is an inner class tree. stop now. 2.332 - // TransTypes.visitClassDef makes an invocation for each class 2.333 - // seperately. 2.334 - return; 2.335 - } 2.336 - isInner = true; 2.337 - List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations; 2.338 - recordedTypeAnnotations = List.nil(); 2.339 - try { 2.340 - super.visitClassDef(tree); 2.341 - } finally { 2.342 - tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations); 2.343 - recordedTypeAnnotations = prevTAs; 2.344 - } 2.345 - } 2.346 - 2.347 - @Override 2.348 - public void visitMethodDef(JCMethodDecl tree) { 2.349 - List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations; 2.350 - recordedTypeAnnotations = List.nil(); 2.351 - try { 2.352 - super.visitMethodDef(tree); 2.353 - } finally { 2.354 - tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations); 2.355 - recordedTypeAnnotations = prevTAs; 2.356 - } 2.357 - } 2.358 - 2.359 - @Override 2.360 - public void visitVarDef(JCVariableDecl tree) { 2.361 - List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations; 2.362 - recordedTypeAnnotations = List.nil(); 2.363 - ElementKind kind = tree.sym.getKind(); 2.364 - if (kind == ElementKind.LOCAL_VARIABLE && tree.mods.annotations.nonEmpty()) { 2.365 - // need to lift the annotations 2.366 - TypeAnnotationPosition position = new TypeAnnotationPosition(); 2.367 - position.pos = tree.pos; 2.368 - position.type = TargetType.LOCAL_VARIABLE; 2.369 - for (Attribute.Compound attribute : tree.sym.attributes_field) { 2.370 - Attribute.TypeCompound tc = 2.371 - new Attribute.TypeCompound(attribute.type, attribute.values, position); 2.372 - recordedTypeAnnotations = recordedTypeAnnotations.append(tc); 2.373 - } 2.374 - } 2.375 - try { 2.376 - super.visitVarDef(tree); 2.377 - } finally { 2.378 - if (kind.isField() || kind == ElementKind.LOCAL_VARIABLE) 2.379 - tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations); 2.380 - recordedTypeAnnotations = kind.isField() ? prevTAs : prevTAs.appendList(recordedTypeAnnotations); 2.381 - } 2.382 - } 2.383 - 2.384 - @Override 2.385 - public void visitApply(JCMethodInvocation tree) { 2.386 - scan(tree.meth); 2.387 - scan(tree.typeargs); 2.388 - scan(tree.args); 2.389 - } 2.390 - 2.391 - public void visitAnnotation(JCAnnotation tree) { 2.392 - if (tree instanceof JCTypeAnnotation) 2.393 - recordedTypeAnnotations = recordedTypeAnnotations.append(((JCTypeAnnotation)tree).attribute_field); 2.394 - super.visitAnnotation(tree); 2.395 - } 2.396 - } 2.397 - 2.398 }