6917067: refactor type annotations code from TransTypes into new TypeAnnotations class

Tue, 19 Jan 2010 14:28:45 -0800

author
jjg
date
Tue, 19 Jan 2010 14:28:45 -0800
changeset 477
f23b985beb78
parent 472
a84062774f0e
child 478
0eaf89e08564

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

src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/TransTypes.java file | annotate | diff | comparison | revisions
     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  }

mercurial