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