Thu, 10 Jun 2010 16:08:01 -0700
6944312: Potential rebranding issues in openjdk/langtools repository sources
Reviewed-by: darcy
1 /*
2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import javax.lang.model.element.ElementKind;
30 import com.sun.tools.javac.code.Symbol.VarSymbol;
31 import com.sun.tools.javac.tree.JCTree;
32 import com.sun.tools.javac.tree.TreeInfo;
33 import com.sun.tools.javac.tree.TreeScanner;
34 import com.sun.tools.javac.tree.JCTree.*;
35 import com.sun.tools.javac.util.Context;
36 import com.sun.tools.javac.util.List;
37 import com.sun.tools.javac.util.ListBuffer;
39 /**
40 * Contains operations specific to processing type annotations
41 */
42 public class TypeAnnotations {
43 private static final Context.Key<TypeAnnotations> key
44 = new Context.Key<TypeAnnotations>();
46 public static TypeAnnotations instance(Context context) {
47 TypeAnnotations instance = context.get(key);
48 if (instance == null)
49 instance = new TypeAnnotations(context);
50 return instance;
51 }
53 protected TypeAnnotations(Context context) {
54 context.put(key, this);
55 }
57 public void taFillAndLift(JCClassDecl tree, boolean visitBodies) {
58 new TypeAnnotationPositions().scan(tree);
59 new TypeAnnotationLift().scan(tree);
60 }
62 private static class TypeAnnotationPositions extends TreeScanner {
64 private ListBuffer<JCTree> frames = ListBuffer.lb();
65 private void push(JCTree t) { frames = frames.prepend(t); }
66 private JCTree pop() { return frames.next(); }
67 private JCTree peek2() { return frames.toList().tail.head; }
69 @Override
70 public void scan(JCTree tree) {
71 push(tree);
72 super.scan(tree);
73 pop();
74 }
76 private boolean inClass = false;
78 @Override
79 public void visitClassDef(JCClassDecl tree) {
80 if (!inClass) {
81 // Do not recurse into nested and inner classes since
82 // TransTypes.visitClassDef makes an invocation for each class
83 // separately.
84 inClass = true;
85 try {
86 super.visitClassDef(tree);
87 } finally {
88 inClass = false;
89 }
90 }
91 }
93 private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame,
94 List<JCTree> path, TypeAnnotationPosition p) {
95 switch (frame.getKind()) {
96 case TYPE_CAST:
97 p.type = TargetType.TYPECAST;
98 p.pos = frame.pos;
99 return p;
101 case INSTANCE_OF:
102 p.type = TargetType.INSTANCEOF;
103 p.pos = frame.pos;
104 return p;
106 case NEW_CLASS:
107 p.type = TargetType.NEW;
108 p.pos = frame.pos;
109 return p;
111 case NEW_ARRAY:
112 p.type = TargetType.NEW;
113 p.pos = frame.pos;
114 return p;
116 case CLASS:
117 p.pos = frame.pos;
118 if (((JCClassDecl)frame).extending == tree) {
119 p.type = TargetType.CLASS_EXTENDS;
120 p.type_index = -1;
121 } else if (((JCClassDecl)frame).implementing.contains(tree)) {
122 p.type = TargetType.CLASS_EXTENDS;
123 p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
124 } else if (((JCClassDecl)frame).typarams.contains(tree)) {
125 p.type = TargetType.CLASS_TYPE_PARAMETER;
126 p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
127 } else
128 throw new AssertionError();
129 return p;
131 case METHOD: {
132 JCMethodDecl frameMethod = (JCMethodDecl)frame;
133 p.pos = frame.pos;
134 if (frameMethod.receiverAnnotations.contains(tree))
135 p.type = TargetType.METHOD_RECEIVER;
136 else if (frameMethod.thrown.contains(tree)) {
137 p.type = TargetType.THROWS;
138 p.type_index = frameMethod.thrown.indexOf(tree);
139 } else if (((JCMethodDecl)frame).restype == tree) {
140 p.type = TargetType.METHOD_RETURN_GENERIC_OR_ARRAY;
141 } else if (frameMethod.typarams.contains(tree)) {
142 p.type = TargetType.METHOD_TYPE_PARAMETER;
143 p.parameter_index = frameMethod.typarams.indexOf(tree);
144 } else
145 throw new AssertionError();
146 return p;
147 }
148 case MEMBER_SELECT: {
149 JCFieldAccess fieldFrame = (JCFieldAccess)frame;
150 if ("class".contentEquals(fieldFrame.name)) {
151 p.type = TargetType.CLASS_LITERAL;
152 p.pos = TreeInfo.innermostType(fieldFrame.selected).pos;
153 } else
154 throw new AssertionError();
155 return p;
156 }
157 case PARAMETERIZED_TYPE: {
158 TypeAnnotationPosition nextP;
159 if (((JCTypeApply)frame).clazz == tree)
160 nextP = p; // generic: RAW; noop
161 else if (((JCTypeApply)frame).arguments.contains(tree))
162 p.location = p.location.prepend(
163 ((JCTypeApply)frame).arguments.indexOf(tree));
164 else
165 throw new AssertionError();
167 List<JCTree> newPath = path.tail;
168 return resolveFrame(newPath.head, newPath.tail.head, newPath, p);
169 }
171 case ARRAY_TYPE: {
172 p.location = p.location.prepend(0);
173 List<JCTree> newPath = path.tail;
174 return resolveFrame(newPath.head, newPath.tail.head, newPath, p);
175 }
177 case TYPE_PARAMETER:
178 if (path.tail.tail.head.getTag() == JCTree.CLASSDEF) {
179 JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
180 p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
181 p.parameter_index = clazz.typarams.indexOf(path.tail.head);
182 p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
183 } else if (path.tail.tail.head.getTag() == JCTree.METHODDEF) {
184 JCMethodDecl method = (JCMethodDecl)path.tail.tail.head;
185 p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
186 p.parameter_index = method.typarams.indexOf(path.tail.head);
187 p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
188 } else
189 throw new AssertionError();
190 p.pos = frame.pos;
191 return p;
193 case VARIABLE:
194 VarSymbol v = ((JCVariableDecl)frame).sym;
195 p.pos = frame.pos;
196 switch (v.getKind()) {
197 case LOCAL_VARIABLE:
198 p.type = TargetType.LOCAL_VARIABLE; break;
199 case FIELD:
200 p.type = TargetType.FIELD_GENERIC_OR_ARRAY; break;
201 case PARAMETER:
202 p.type = TargetType.METHOD_PARAMETER_GENERIC_OR_ARRAY;
203 p.parameter_index = methodParamIndex(path, frame);
204 break;
205 default: throw new AssertionError();
206 }
207 return p;
209 case ANNOTATED_TYPE: {
210 List<JCTree> newPath = path.tail;
211 return resolveFrame(newPath.head, newPath.tail.head,
212 newPath, p);
213 }
215 case METHOD_INVOCATION: {
216 JCMethodInvocation invocation = (JCMethodInvocation)frame;
217 if (!invocation.typeargs.contains(tree))
218 throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation);
219 p.type = TargetType.METHOD_TYPE_ARGUMENT;
220 p.pos = invocation.pos;
221 p.type_index = invocation.typeargs.indexOf(tree);
222 return p;
223 }
225 case EXTENDS_WILDCARD:
226 case SUPER_WILDCARD: {
227 p.type = TargetType.WILDCARD_BOUND;
228 List<JCTree> newPath = path.tail;
230 TypeAnnotationPosition wildcard =
231 resolveFrame(newPath.head, newPath.tail.head, newPath,
232 new TypeAnnotationPosition());
233 if (!wildcard.location.isEmpty())
234 wildcard.type = wildcard.type.getGenericComplement();
235 p.wildcard_position = wildcard;
236 p.pos = frame.pos;
237 return p;
238 }
239 }
240 return p;
241 }
243 private void setTypeAnnotationPos(List<JCTypeAnnotation> annotations, TypeAnnotationPosition position) {
244 for (JCTypeAnnotation anno : annotations) {
245 anno.annotation_position = position;
246 anno.attribute_field.position = position;
247 }
248 }
250 @Override
251 public void visitNewArray(JCNewArray tree) {
252 findPosition(tree, tree, tree.annotations);
253 int dimAnnosCount = tree.dimAnnotations.size();
255 // handle annotations associated with dimentions
256 for (int i = 0; i < dimAnnosCount; ++i) {
257 TypeAnnotationPosition p = new TypeAnnotationPosition();
258 p.type = TargetType.NEW_GENERIC_OR_ARRAY;
259 p.pos = tree.pos;
260 p.location = p.location.append(i);
261 setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
262 }
264 // handle "free" annotations
265 int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
266 JCExpression elemType = tree.elemtype;
267 while (elemType != null) {
268 if (elemType.getTag() == JCTree.ANNOTATED_TYPE) {
269 JCAnnotatedType at = (JCAnnotatedType)elemType;
270 TypeAnnotationPosition p = new TypeAnnotationPosition();
271 p.type = TargetType.NEW_GENERIC_OR_ARRAY;
272 p.pos = tree.pos;
273 p.location = p.location.append(i);
274 setTypeAnnotationPos(at.annotations, p);
275 elemType = at.underlyingType;
276 } else if (elemType.getTag() == JCTree.TYPEARRAY) {
277 ++i;
278 elemType = ((JCArrayTypeTree)elemType).elemtype;
279 } else
280 break;
281 }
283 // find annotations locations of initializer elements
284 scan(tree.elems);
285 }
287 @Override
288 public void visitAnnotatedType(JCAnnotatedType tree) {
289 findPosition(tree, peek2(), tree.annotations);
290 super.visitAnnotatedType(tree);
291 }
293 @Override
294 public void visitMethodDef(JCMethodDecl tree) {
295 TypeAnnotationPosition p = new TypeAnnotationPosition();
296 p.type = TargetType.METHOD_RECEIVER;
297 setTypeAnnotationPos(tree.receiverAnnotations, p);
298 super.visitMethodDef(tree);
299 }
300 @Override
301 public void visitTypeParameter(JCTypeParameter tree) {
302 findPosition(tree, peek2(), tree.annotations);
303 super.visitTypeParameter(tree);
304 }
306 void findPosition(JCTree tree, JCTree frame, List<JCTypeAnnotation> annotations) {
307 if (!annotations.isEmpty()) {
308 TypeAnnotationPosition p =
309 resolveFrame(tree, frame, frames.toList(),
310 new TypeAnnotationPosition());
311 if (!p.location.isEmpty())
312 p.type = p.type.getGenericComplement();
313 setTypeAnnotationPos(annotations, p);
314 }
315 }
317 private int methodParamIndex(List<JCTree> path, JCTree param) {
318 List<JCTree> curr = path;
319 if (curr.head != param)
320 curr = path.tail;
321 JCMethodDecl method = (JCMethodDecl)curr.tail.head;
322 return method.params.indexOf(param);
323 }
324 }
326 private static class TypeAnnotationLift extends TreeScanner {
327 List<Attribute.TypeCompound> recordedTypeAnnotations = List.nil();
329 boolean isInner = false;
330 @Override
331 public void visitClassDef(JCClassDecl tree) {
332 if (isInner) {
333 // tree is an inner class tree. stop now.
334 // TransTypes.visitClassDef makes an invocation for each class
335 // separately.
336 return;
337 }
338 isInner = true;
339 List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
340 recordedTypeAnnotations = List.nil();
341 try {
342 super.visitClassDef(tree);
343 } finally {
344 tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
345 recordedTypeAnnotations = prevTAs;
346 }
347 }
349 @Override
350 public void visitMethodDef(JCMethodDecl tree) {
351 List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
352 recordedTypeAnnotations = List.nil();
353 try {
354 super.visitMethodDef(tree);
355 } finally {
356 tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
357 recordedTypeAnnotations = prevTAs;
358 }
359 }
361 @Override
362 public void visitVarDef(JCVariableDecl tree) {
363 List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
364 recordedTypeAnnotations = List.nil();
365 ElementKind kind = tree.sym.getKind();
366 if (kind == ElementKind.LOCAL_VARIABLE && tree.mods.annotations.nonEmpty()) {
367 // need to lift the annotations
368 TypeAnnotationPosition position = new TypeAnnotationPosition();
369 position.pos = tree.pos;
370 position.type = TargetType.LOCAL_VARIABLE;
371 for (Attribute.Compound attribute : tree.sym.attributes_field) {
372 Attribute.TypeCompound tc =
373 new Attribute.TypeCompound(attribute.type, attribute.values, position);
374 recordedTypeAnnotations = recordedTypeAnnotations.append(tc);
375 }
376 }
377 try {
378 super.visitVarDef(tree);
379 } finally {
380 if (kind.isField() || kind == ElementKind.LOCAL_VARIABLE)
381 tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
382 recordedTypeAnnotations = kind.isField() ? prevTAs : prevTAs.appendList(recordedTypeAnnotations);
383 }
384 }
386 @Override
387 public void visitApply(JCMethodInvocation tree) {
388 scan(tree.meth);
389 scan(tree.typeargs);
390 scan(tree.args);
391 }
393 public void visitAnnotation(JCAnnotation tree) {
394 if (tree instanceof JCTypeAnnotation)
395 recordedTypeAnnotations = recordedTypeAnnotations.append(((JCTypeAnnotation)tree).attribute_field);
396 super.visitAnnotation(tree);
397 }
398 }
400 }