src/share/classes/com/sun/tools/javac/comp/MemberEnter.java

changeset 1570
f91144b7da75
parent 1521
71f35e4b93a5
child 1565
d04960f05593
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Jan 21 01:27:42 2013 -0500
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Feb 04 18:08:53 2013 -0500
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -25,15 +25,19 @@
    1.11  
    1.12  package com.sun.tools.javac.comp;
    1.13  
    1.14 -import java.util.*;
    1.15 +import java.util.HashMap;
    1.16 +import java.util.HashSet;
    1.17 +import java.util.LinkedHashMap;
    1.18 +import java.util.Map;
    1.19  import java.util.Set;
    1.20 +
    1.21 +import javax.lang.model.type.TypeKind;
    1.22  import javax.tools.JavaFileObject;
    1.23  
    1.24  import com.sun.tools.javac.code.*;
    1.25  import com.sun.tools.javac.jvm.*;
    1.26  import com.sun.tools.javac.tree.*;
    1.27  import com.sun.tools.javac.util.*;
    1.28 -import com.sun.tools.javac.util.List;
    1.29  
    1.30  import com.sun.tools.javac.code.Type.*;
    1.31  import com.sun.tools.javac.code.Symbol.*;
    1.32 @@ -345,12 +349,15 @@
    1.33       *  @param params      The method's value parameters.
    1.34       *  @param res             The method's result type,
    1.35       *                 null if it is a constructor.
    1.36 +     *  @param recvparam       The method's receiver parameter,
    1.37 +     *                 null if none given; TODO: or already set here?
    1.38       *  @param thrown      The method's thrown exceptions.
    1.39       *  @param env             The method's (local) environment.
    1.40       */
    1.41      Type signature(List<JCTypeParameter> typarams,
    1.42                     List<JCVariableDecl> params,
    1.43                     JCTree res,
    1.44 +                   JCVariableDecl recvparam,
    1.45                     List<JCExpression> thrown,
    1.46                     Env<AttrContext> env) {
    1.47  
    1.48 @@ -368,6 +375,15 @@
    1.49          // Attribute result type, if one is given.
    1.50          Type restype = res == null ? syms.voidType : attr.attribType(res, env);
    1.51  
    1.52 +        // Attribute receiver type, if one is given.
    1.53 +        Type recvtype;
    1.54 +        if (recvparam!=null) {
    1.55 +            memberEnter(recvparam, env);
    1.56 +            recvtype = recvparam.vartype.type;
    1.57 +        } else {
    1.58 +            recvtype = null;
    1.59 +        }
    1.60 +
    1.61          // Attribute thrown exceptions.
    1.62          ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
    1.63          for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
    1.64 @@ -376,10 +392,12 @@
    1.65                  exc = chk.checkClassType(l.head.pos(), exc);
    1.66              thrownbuf.append(exc);
    1.67          }
    1.68 -        Type mtype = new MethodType(argbuf.toList(),
    1.69 +        MethodType mtype = new MethodType(argbuf.toList(),
    1.70                                      restype,
    1.71                                      thrownbuf.toList(),
    1.72                                      syms.methodClass);
    1.73 +        mtype.recvtype = recvtype;
    1.74 +
    1.75          return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
    1.76      }
    1.77  
    1.78 @@ -573,7 +591,8 @@
    1.79          try {
    1.80              // Compute the method type
    1.81              m.type = signature(tree.typarams, tree.params,
    1.82 -                               tree.restype, tree.thrown,
    1.83 +                               tree.restype, tree.recvparam,
    1.84 +                               tree.thrown,
    1.85                                 localEnv);
    1.86          } finally {
    1.87              chk.setDeferredLintHandler(prevLintHandler);
    1.88 @@ -597,6 +616,10 @@
    1.89              enclScope.enter(m);
    1.90          }
    1.91          annotateLater(tree.mods.annotations, localEnv, m);
    1.92 +        // Visit the signature of the method. Note that
    1.93 +        // TypeAnnotate doesn't descend into the body.
    1.94 +        typeAnnotate(tree, localEnv, m);
    1.95 +
    1.96          if (tree.defaultValue != null)
    1.97              annotateDefaultValueLater(tree.defaultValue, localEnv, m);
    1.98      }
    1.99 @@ -642,7 +665,7 @@
   1.100              //(a plain array type) with the more precise VarargsType --- we need
   1.101              //to do it this way because varargs is represented in the tree as a modifier
   1.102              //on the parameter declaration, and not as a distinct type of array node.
   1.103 -            ArrayType atype = (ArrayType)tree.vartype.type;
   1.104 +            ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType();
   1.105              tree.vartype.type = atype.makeVarargs();
   1.106          }
   1.107          Scope enclScope = enter.enterScope(env);
   1.108 @@ -665,6 +688,8 @@
   1.109              enclScope.enter(v);
   1.110          }
   1.111          annotateLater(tree.mods.annotations, localEnv, v);
   1.112 +        typeAnnotate(tree.vartype, env, tree.sym);
   1.113 +        annotate.flush();
   1.114          v.pos = tree.pos;
   1.115      }
   1.116  
   1.117 @@ -759,7 +784,7 @@
   1.118                              log.error(annotations.head.pos,
   1.119                                        "already.annotated",
   1.120                                        kindName(s), s);
   1.121 -                        enterAnnotations(annotations, localEnv, s);
   1.122 +                        actualEnterAnnotations(annotations, localEnv, s);
   1.123                      } finally {
   1.124                          log.useSource(prev);
   1.125                      }
   1.126 @@ -781,7 +806,7 @@
   1.127      }
   1.128  
   1.129      /** Enter a set of annotations. */
   1.130 -    private void enterAnnotations(List<JCAnnotation> annotations,
   1.131 +    private void actualEnterAnnotations(List<JCAnnotation> annotations,
   1.132                            Env<AttrContext> env,
   1.133                            Symbol s) {
   1.134          Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
   1.135 @@ -817,11 +842,11 @@
   1.136                  && s.owner.kind != MTH
   1.137                  && types.isSameType(c.type, syms.deprecatedType)) {
   1.138                  s.flags_field |= Flags.DEPRECATED;
   1.139 -        }
   1.140 +            }
   1.141          }
   1.142  
   1.143 -        s.annotations.setAttributesWithCompletion(
   1.144 -                annotate.new AnnotateRepeatedContext(env, annotated, pos, log));
   1.145 +        s.annotations.setDeclarationAttributesWithCompletion(
   1.146 +                annotate.new AnnotateRepeatedContext<Attribute.Compound>(env, annotated, pos, log, false));
   1.147      }
   1.148  
   1.149      /** Queue processing of an attribute default value. */
   1.150 @@ -900,6 +925,12 @@
   1.151              // create an environment for evaluating the base clauses
   1.152              Env<AttrContext> baseEnv = baseEnv(tree, env);
   1.153  
   1.154 +            if (tree.extending != null)
   1.155 +                typeAnnotate(tree.extending, baseEnv, sym);
   1.156 +            for (JCExpression impl : tree.implementing)
   1.157 +                typeAnnotate(impl, baseEnv, sym);
   1.158 +            annotate.flush();
   1.159 +
   1.160              // Determine supertype.
   1.161              Type supertype =
   1.162                  (tree.extending != null)
   1.163 @@ -969,10 +1000,15 @@
   1.164              if (hasDeprecatedAnnotation(tree.mods.annotations))
   1.165                  c.flags_field |= DEPRECATED;
   1.166              annotateLater(tree.mods.annotations, baseEnv, c);
   1.167 +            // class type parameters use baseEnv but everything uses env
   1.168  
   1.169              chk.checkNonCyclicDecl(tree);
   1.170  
   1.171              attr.attribTypeVariables(tree.typarams, baseEnv);
   1.172 +            // Do this here, where we have the symbol.
   1.173 +            for (JCTypeParameter tp : tree.typarams)
   1.174 +                typeAnnotate(tp, baseEnv, sym);
   1.175 +            annotate.flush();
   1.176  
   1.177              // Add default constructor if needed.
   1.178              if ((c.flags() & INTERFACE) == 0 &&
   1.179 @@ -1050,12 +1086,120 @@
   1.180              } finally {
   1.181                  isFirst = true;
   1.182              }
   1.183 +        }
   1.184 +        annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree));
   1.185 +    }
   1.186  
   1.187 -            // commit pending annotations
   1.188 -            annotate.flush();
   1.189 +    private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
   1.190 +            final Env<AttrContext> env,
   1.191 +            final Symbol s) {
   1.192 +        Map<TypeSymbol, ListBuffer<Attribute.TypeCompound>> annotated =
   1.193 +                new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.TypeCompound>>();
   1.194 +        Map<Attribute.TypeCompound, DiagnosticPosition> pos =
   1.195 +                new HashMap<Attribute.TypeCompound, DiagnosticPosition>();
   1.196 +
   1.197 +        for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
   1.198 +            JCAnnotation a = al.head;
   1.199 +            Attribute.TypeCompound tc = annotate.enterTypeAnnotation(a,
   1.200 +                    syms.annotationType,
   1.201 +                    env);
   1.202 +            if (tc == null) {
   1.203 +                continue;
   1.204 +            }
   1.205 +
   1.206 +            if (annotated.containsKey(a.type.tsym)) {
   1.207 +                if (source.allowRepeatedAnnotations()) {
   1.208 +                    ListBuffer<Attribute.TypeCompound> l = annotated.get(a.type.tsym);
   1.209 +                    l = l.append(tc);
   1.210 +                    annotated.put(a.type.tsym, l);
   1.211 +                    pos.put(tc, a.pos());
   1.212 +                } else {
   1.213 +                    log.error(a.pos(), "duplicate.annotation");
   1.214 +                }
   1.215 +            } else {
   1.216 +                annotated.put(a.type.tsym, ListBuffer.of(tc));
   1.217 +                pos.put(tc, a.pos());
   1.218 +            }
   1.219 +        }
   1.220 +
   1.221 +        s.annotations.appendTypeAttributesWithCompletion(
   1.222 +                annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
   1.223 +    }
   1.224 +
   1.225 +    public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
   1.226 +        tree.accept(new TypeAnnotate(env, sym));
   1.227 +    }
   1.228 +
   1.229 +    /**
   1.230 +     * We need to use a TreeScanner, because it is not enough to visit the top-level
   1.231 +     * annotations. We also need to visit type arguments, etc.
   1.232 +     */
   1.233 +    private class TypeAnnotate extends TreeScanner {
   1.234 +        private Env<AttrContext> env;
   1.235 +        private Symbol sym;
   1.236 +
   1.237 +        public TypeAnnotate(final Env<AttrContext> env, final Symbol sym) {
   1.238 +            this.env = env;
   1.239 +            this.sym = sym;
   1.240 +        }
   1.241 +
   1.242 +        void annotateTypeLater(final List<JCAnnotation> annotations) {
   1.243 +            if (annotations.isEmpty()) {
   1.244 +                return;
   1.245 +            }
   1.246 +
   1.247 +            annotate.normal(new Annotate.Annotator() {
   1.248 +                @Override
   1.249 +                public String toString() {
   1.250 +                    return "type annotate " + annotations + " onto " + sym + " in " + sym.owner;
   1.251 +                }
   1.252 +                @Override
   1.253 +                public void enterAnnotation() {
   1.254 +                    JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
   1.255 +                    try {
   1.256 +                        actualEnterTypeAnnotations(annotations, env, sym);
   1.257 +                    } finally {
   1.258 +                        log.useSource(prev);
   1.259 +                    }
   1.260 +                }
   1.261 +            });
   1.262 +        }
   1.263 +
   1.264 +        @Override
   1.265 +        public void visitAnnotatedType(final JCAnnotatedType tree) {
   1.266 +            annotateTypeLater(tree.annotations);
   1.267 +            super.visitAnnotatedType(tree);
   1.268 +        }
   1.269 +
   1.270 +        @Override
   1.271 +        public void visitTypeParameter(final JCTypeParameter tree) {
   1.272 +            annotateTypeLater(tree.annotations);
   1.273 +            super.visitTypeParameter(tree);
   1.274 +        }
   1.275 +
   1.276 +        @Override
   1.277 +        public void visitNewArray(final JCNewArray tree) {
   1.278 +            annotateTypeLater(tree.annotations);
   1.279 +            for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
   1.280 +                annotateTypeLater(dimAnnos);
   1.281 +            super.visitNewArray(tree);
   1.282 +        }
   1.283 +
   1.284 +        @Override
   1.285 +        public void visitMethodDef(final JCMethodDecl tree) {
   1.286 +            scan(tree.mods);
   1.287 +            scan(tree.restype);
   1.288 +            scan(tree.typarams);
   1.289 +            scan(tree.recvparam);
   1.290 +            scan(tree.params);
   1.291 +            scan(tree.thrown);
   1.292 +            scan(tree.defaultValue);
   1.293 +            // Do not annotate the body, just the signature.
   1.294 +            // scan(tree.body);
   1.295          }
   1.296      }
   1.297  
   1.298 +
   1.299      private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
   1.300          Scope baseScope = new Scope(tree.sym);
   1.301          //import already entered local classes into base scope

mercurial