Mon, 09 Sep 2013 09:58:20 +0200
8022260: Rename javac.code.Annotations to javac.code.SymbolMetadata
Reviewed-by: jfranck, jjg
Contributed-by: Andreas Lundblad <andreas.lundblad@oracle.com>
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Annotations.java Sun Sep 08 11:54:21 2013 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,451 +0,0 @@ 1.4 -/* 1.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. 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. Oracle designates this 1.11 - * particular file as subject to the "Classpath" exception as provided 1.12 - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 - * or visit www.oracle.com if you need additional information or have any 1.26 - * questions. 1.27 - */ 1.28 - 1.29 -package com.sun.tools.javac.code; 1.30 - 1.31 -import java.util.Map; 1.32 - 1.33 -import javax.tools.JavaFileObject; 1.34 - 1.35 -import com.sun.tools.javac.comp.Annotate; 1.36 -import com.sun.tools.javac.comp.AttrContext; 1.37 -import com.sun.tools.javac.comp.Env; 1.38 -import com.sun.tools.javac.util.*; 1.39 -import com.sun.tools.javac.util.Assert; 1.40 -import com.sun.tools.javac.util.List; 1.41 -import com.sun.tools.javac.util.Log; 1.42 -import com.sun.tools.javac.util.Pair; 1.43 -import static com.sun.tools.javac.code.Kinds.PCK; 1.44 - 1.45 -/** 1.46 - * Container for all annotations (attributes in javac) on a Symbol. 1.47 - * 1.48 - * This class is explicitly mutable. Its contents will change when attributes 1.49 - * are annotated onto the Symbol. However this class depends on the facts that 1.50 - * List (in javac) is immutable. 1.51 - * 1.52 - * An instance of this class can be in one of three states: 1.53 - * 1.54 - * NOT_STARTED indicates that the Symbol this instance belongs to has not been 1.55 - * annotated (yet). Specifically if the declaration is not annotated this 1.56 - * instance will never move past NOT_STARTED. You can never go back to 1.57 - * NOT_STARTED. 1.58 - * 1.59 - * IN_PROGRESS annotations have been found on the declaration. Will be processed 1.60 - * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list 1.61 - * of attributes (and this moves out of the IN_PROGRESS state). 1.62 - * 1.63 - * "unnamed" this Annotations contains some attributes, possibly the final set. 1.64 - * While in this state you can only prepend or append to the attributes not set 1.65 - * it directly. You can also move back to the IN_PROGRESS state using reset(). 1.66 - * 1.67 - * <p><b>This is NOT part of any supported API. If you write code that depends 1.68 - * on this, you do so at your own risk. This code and its internal interfaces 1.69 - * are subject to change or deletion without notice.</b> 1.70 - */ 1.71 -public class Annotations { 1.72 - 1.73 - private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null); 1.74 - private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null); 1.75 - 1.76 - /* 1.77 - * This field should never be null 1.78 - */ 1.79 - private List<Attribute.Compound> attributes = DECL_NOT_STARTED; 1.80 - 1.81 - /* 1.82 - * Type attributes for this symbol. 1.83 - * This field should never be null. 1.84 - */ 1.85 - private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil(); 1.86 - 1.87 - /* 1.88 - * Type attributes of initializers in this class. 1.89 - * Unused if the current symbol is not a ClassSymbol. 1.90 - */ 1.91 - private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil(); 1.92 - 1.93 - /* 1.94 - * Type attributes of class initializers in this class. 1.95 - * Unused if the current symbol is not a ClassSymbol. 1.96 - */ 1.97 - private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil(); 1.98 - 1.99 - /* 1.100 - * The Symbol this Annotations instance belongs to 1.101 - */ 1.102 - private final Symbol sym; 1.103 - 1.104 - public Annotations(Symbol sym) { 1.105 - this.sym = sym; 1.106 - } 1.107 - 1.108 - public List<Attribute.Compound> getDeclarationAttributes() { 1.109 - return filterDeclSentinels(attributes); 1.110 - } 1.111 - 1.112 - public List<Attribute.TypeCompound> getTypeAttributes() { 1.113 - return type_attributes; 1.114 - } 1.115 - 1.116 - public List<Attribute.TypeCompound> getInitTypeAttributes() { 1.117 - return init_type_attributes; 1.118 - } 1.119 - 1.120 - public List<Attribute.TypeCompound> getClassInitTypeAttributes() { 1.121 - return clinit_type_attributes; 1.122 - } 1.123 - 1.124 - public void setDeclarationAttributes(List<Attribute.Compound> a) { 1.125 - Assert.check(pendingCompletion() || !isStarted()); 1.126 - if (a == null) { 1.127 - throw new NullPointerException(); 1.128 - } 1.129 - attributes = a; 1.130 - } 1.131 - 1.132 - public void setTypeAttributes(List<Attribute.TypeCompound> a) { 1.133 - if (a == null) { 1.134 - throw new NullPointerException(); 1.135 - } 1.136 - type_attributes = a; 1.137 - } 1.138 - 1.139 - public void setInitTypeAttributes(List<Attribute.TypeCompound> a) { 1.140 - if (a == null) { 1.141 - throw new NullPointerException(); 1.142 - } 1.143 - init_type_attributes = a; 1.144 - } 1.145 - 1.146 - public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) { 1.147 - if (a == null) { 1.148 - throw new NullPointerException(); 1.149 - } 1.150 - clinit_type_attributes = a; 1.151 - } 1.152 - 1.153 - public void setAttributes(Annotations other) { 1.154 - if (other == null) { 1.155 - throw new NullPointerException(); 1.156 - } 1.157 - setDeclarationAttributes(other.getDeclarationAttributes()); 1.158 - setTypeAttributes(other.getTypeAttributes()); 1.159 - setInitTypeAttributes(other.getInitTypeAttributes()); 1.160 - setClassInitTypeAttributes(other.getClassInitTypeAttributes()); 1.161 - } 1.162 - 1.163 - public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) { 1.164 - Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK)); 1.165 - this.setDeclarationAttributes(getAttributesForCompletion(ctx)); 1.166 - } 1.167 - 1.168 - public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) { 1.169 - this.appendUniqueTypes(getAttributesForCompletion(ctx)); 1.170 - } 1.171 - 1.172 - private <T extends Attribute.Compound> List<T> getAttributesForCompletion( 1.173 - final Annotate.AnnotateRepeatedContext<T> ctx) { 1.174 - 1.175 - Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated; 1.176 - boolean atLeastOneRepeated = false; 1.177 - List<T> buf = List.<T>nil(); 1.178 - for (ListBuffer<T> lb : annotated.values()) { 1.179 - if (lb.size() == 1) { 1.180 - buf = buf.prepend(lb.first()); 1.181 - } else { // repeated 1.182 - // This will break when other subtypes of Attributs.Compound 1.183 - // are introduced, because PlaceHolder is a subtype of TypeCompound. 1.184 - T res; 1.185 - @SuppressWarnings("unchecked") 1.186 - T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym); 1.187 - res = ph; 1.188 - buf = buf.prepend(res); 1.189 - atLeastOneRepeated = true; 1.190 - } 1.191 - } 1.192 - 1.193 - if (atLeastOneRepeated) { 1.194 - // The Symbol s is now annotated with a combination of 1.195 - // finished non-repeating annotations and placeholders for 1.196 - // repeating annotations. 1.197 - // 1.198 - // We need to do this in two passes because when creating 1.199 - // a container for a repeating annotation we must 1.200 - // guarantee that the @Repeatable on the 1.201 - // contained annotation is fully annotated 1.202 - // 1.203 - // The way we force this order is to do all repeating 1.204 - // annotations in a pass after all non-repeating are 1.205 - // finished. This will work because @Repeatable 1.206 - // is non-repeating and therefore will be annotated in the 1.207 - // fist pass. 1.208 - 1.209 - // Queue a pass that will replace Attribute.Placeholders 1.210 - // with Attribute.Compound (made from synthesized containers). 1.211 - ctx.annotateRepeated(new Annotate.Annotator() { 1.212 - @Override 1.213 - public String toString() { 1.214 - return "repeated annotation pass of: " + sym + " in: " + sym.owner; 1.215 - } 1.216 - 1.217 - @Override 1.218 - public void enterAnnotation() { 1.219 - complete(ctx); 1.220 - } 1.221 - }); 1.222 - } 1.223 - // Add non-repeating attributes 1.224 - return buf.reverse(); 1.225 - } 1.226 - 1.227 - public Annotations reset() { 1.228 - attributes = DECL_IN_PROGRESS; 1.229 - return this; 1.230 - } 1.231 - 1.232 - public boolean isEmpty() { 1.233 - return !isStarted() 1.234 - || pendingCompletion() 1.235 - || attributes.isEmpty(); 1.236 - } 1.237 - 1.238 - public boolean isTypesEmpty() { 1.239 - return type_attributes.isEmpty(); 1.240 - } 1.241 - 1.242 - public boolean pendingCompletion() { 1.243 - return attributes == DECL_IN_PROGRESS; 1.244 - } 1.245 - 1.246 - public Annotations append(List<Attribute.Compound> l) { 1.247 - attributes = filterDeclSentinels(attributes); 1.248 - 1.249 - if (l.isEmpty()) { 1.250 - ; // no-op 1.251 - } else if (attributes.isEmpty()) { 1.252 - attributes = l; 1.253 - } else { 1.254 - attributes = attributes.appendList(l); 1.255 - } 1.256 - return this; 1.257 - } 1.258 - 1.259 - public Annotations appendUniqueTypes(List<Attribute.TypeCompound> l) { 1.260 - if (l.isEmpty()) { 1.261 - ; // no-op 1.262 - } else if (type_attributes.isEmpty()) { 1.263 - type_attributes = l; 1.264 - } else { 1.265 - // TODO: in case we expect a large number of annotations, this 1.266 - // might be inefficient. 1.267 - for (Attribute.TypeCompound tc : l) { 1.268 - if (!type_attributes.contains(tc)) 1.269 - type_attributes = type_attributes.append(tc); 1.270 - } 1.271 - } 1.272 - return this; 1.273 - } 1.274 - 1.275 - public Annotations appendInitTypeAttributes(List<Attribute.TypeCompound> l) { 1.276 - if (l.isEmpty()) { 1.277 - ; // no-op 1.278 - } else if (init_type_attributes.isEmpty()) { 1.279 - init_type_attributes = l; 1.280 - } else { 1.281 - init_type_attributes = init_type_attributes.appendList(l); 1.282 - } 1.283 - return this; 1.284 - } 1.285 - 1.286 - public Annotations appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) { 1.287 - if (l.isEmpty()) { 1.288 - ; // no-op 1.289 - } else if (clinit_type_attributes.isEmpty()) { 1.290 - clinit_type_attributes = l; 1.291 - } else { 1.292 - clinit_type_attributes = clinit_type_attributes.appendList(l); 1.293 - } 1.294 - return this; 1.295 - } 1.296 - 1.297 - public Annotations prepend(List<Attribute.Compound> l) { 1.298 - attributes = filterDeclSentinels(attributes); 1.299 - 1.300 - if (l.isEmpty()) { 1.301 - ; // no-op 1.302 - } else if (attributes.isEmpty()) { 1.303 - attributes = l; 1.304 - } else { 1.305 - attributes = attributes.prependList(l); 1.306 - } 1.307 - return this; 1.308 - } 1.309 - 1.310 - private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) { 1.311 - return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED) 1.312 - ? List.<Attribute.Compound>nil() 1.313 - : a; 1.314 - } 1.315 - 1.316 - private boolean isStarted() { 1.317 - return attributes != DECL_NOT_STARTED; 1.318 - } 1.319 - 1.320 - private List<Attribute.Compound> getPlaceholders() { 1.321 - List<Attribute.Compound> res = List.<Attribute.Compound>nil(); 1.322 - for (Attribute.Compound a : filterDeclSentinels(attributes)) { 1.323 - if (a instanceof Placeholder) { 1.324 - res = res.prepend(a); 1.325 - } 1.326 - } 1.327 - return res.reverse(); 1.328 - } 1.329 - 1.330 - private List<Attribute.TypeCompound> getTypePlaceholders() { 1.331 - List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil(); 1.332 - for (Attribute.TypeCompound a : type_attributes) { 1.333 - if (a instanceof Placeholder) { 1.334 - res = res.prepend(a); 1.335 - } 1.336 - } 1.337 - return res.reverse(); 1.338 - } 1.339 - 1.340 - /* 1.341 - * Replace Placeholders for repeating annotations with their containers 1.342 - */ 1.343 - private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) { 1.344 - Log log = ctx.log; 1.345 - Env<AttrContext> env = ctx.env; 1.346 - JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); 1.347 - try { 1.348 - // TODO: can we reduce duplication in the following branches? 1.349 - if (ctx.isTypeCompound) { 1.350 - Assert.check(!isTypesEmpty()); 1.351 - 1.352 - if (isTypesEmpty()) { 1.353 - return; 1.354 - } 1.355 - 1.356 - List<Attribute.TypeCompound> result = List.nil(); 1.357 - for (Attribute.TypeCompound a : getTypeAttributes()) { 1.358 - if (a instanceof Placeholder) { 1.359 - @SuppressWarnings("unchecked") 1.360 - Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a; 1.361 - Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext()); 1.362 - 1.363 - if (null != replacement) { 1.364 - result = result.prepend(replacement); 1.365 - } 1.366 - } else { 1.367 - result = result.prepend(a); 1.368 - } 1.369 - } 1.370 - 1.371 - type_attributes = result.reverse(); 1.372 - 1.373 - Assert.check(Annotations.this.getTypePlaceholders().isEmpty()); 1.374 - } else { 1.375 - Assert.check(!pendingCompletion()); 1.376 - 1.377 - if (isEmpty()) { 1.378 - return; 1.379 - } 1.380 - 1.381 - List<Attribute.Compound> result = List.nil(); 1.382 - for (Attribute.Compound a : getDeclarationAttributes()) { 1.383 - if (a instanceof Placeholder) { 1.384 - @SuppressWarnings("unchecked") 1.385 - Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx); 1.386 - 1.387 - if (null != replacement) { 1.388 - result = result.prepend(replacement); 1.389 - } 1.390 - } else { 1.391 - result = result.prepend(a); 1.392 - } 1.393 - } 1.394 - 1.395 - attributes = result.reverse(); 1.396 - 1.397 - Assert.check(Annotations.this.getPlaceholders().isEmpty()); 1.398 - } 1.399 - } finally { 1.400 - log.useSource(oldSource); 1.401 - } 1.402 - } 1.403 - 1.404 - private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) { 1.405 - Log log = ctx.log; 1.406 - 1.407 - // Process repeated annotations 1.408 - T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym); 1.409 - 1.410 - if (validRepeated != null) { 1.411 - // Check that the container isn't manually 1.412 - // present along with repeated instances of 1.413 - // its contained annotation. 1.414 - ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); 1.415 - if (manualContainer != null) { 1.416 - log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", 1.417 - manualContainer.first().type.tsym); 1.418 - } 1.419 - } 1.420 - 1.421 - // A null return will delete the Placeholder 1.422 - return validRepeated; 1.423 - } 1.424 - 1.425 - private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound { 1.426 - 1.427 - private final Annotate.AnnotateRepeatedContext<T> ctx; 1.428 - private final List<T> placeholderFor; 1.429 - private final Symbol on; 1.430 - 1.431 - public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) { 1.432 - super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(), 1.433 - ctx.isTypeCompound ? 1.434 - ((Attribute.TypeCompound)placeholderFor.head).position : 1.435 - null); 1.436 - this.ctx = ctx; 1.437 - this.placeholderFor = placeholderFor; 1.438 - this.on = on; 1.439 - } 1.440 - 1.441 - @Override 1.442 - public String toString() { 1.443 - return "<placeholder: " + placeholderFor + " on: " + on + ">"; 1.444 - } 1.445 - 1.446 - public List<T> getPlaceholderFor() { 1.447 - return placeholderFor; 1.448 - } 1.449 - 1.450 - public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() { 1.451 - return ctx; 1.452 - } 1.453 - } 1.454 -}
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Sun Sep 08 11:54:21 2013 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Sep 09 09:58:20 2013 +0200 2.3 @@ -98,9 +98,9 @@ 2.4 // <editor-fold defaultstate="collapsed" desc="annotations"> 2.5 2.6 /** The attributes of this symbol are contained in this 2.7 - * Annotations. The Annotations instance is NOT immutable. 2.8 + * SymbolMetadata. The SymbolMetadata instance is NOT immutable. 2.9 */ 2.10 - protected Annotations annotations; 2.11 + protected SymbolMetadata annotations; 2.12 2.13 /** An accessor method for the attributes of this symbol. 2.14 * Attributes of class symbols should be accessed through the accessor 2.15 @@ -217,19 +217,19 @@ 2.16 public void setTypeAttributes(List<Attribute.TypeCompound> a) { 2.17 if (annotations != null || a.nonEmpty()) { 2.18 if (annotations == null) 2.19 - annotations = new Annotations(this); 2.20 + annotations = new SymbolMetadata(this); 2.21 annotations.setTypeAttributes(a); 2.22 } 2.23 } 2.24 2.25 - private Annotations initedAnnos() { 2.26 + private SymbolMetadata initedAnnos() { 2.27 if (annotations == null) 2.28 - annotations = new Annotations(this); 2.29 + annotations = new SymbolMetadata(this); 2.30 return annotations; 2.31 } 2.32 2.33 /** This method is intended for debugging only. */ 2.34 - public Annotations getAnnotations() { 2.35 + public SymbolMetadata getAnnotations() { 2.36 return annotations; 2.37 } 2.38 2.39 @@ -852,7 +852,7 @@ 2.40 private void mergeAttributes() { 2.41 if (annotations == null && 2.42 package_info.annotations != null) { 2.43 - annotations = new Annotations(this); 2.44 + annotations = new SymbolMetadata(this); 2.45 annotations.setAttributes(package_info.annotations); 2.46 } 2.47 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java Mon Sep 09 09:58:20 2013 +0200 3.3 @@ -0,0 +1,451 @@ 3.4 +/* 3.5 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. Oracle designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Oracle in the LICENSE file that accompanied this code. 3.13 + * 3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.17 + * version 2 for more details (a copy is included in the LICENSE file that 3.18 + * accompanied this code). 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License version 3.21 + * 2 along with this work; if not, write to the Free Software Foundation, 3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.23 + * 3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.25 + * or visit www.oracle.com if you need additional information or have any 3.26 + * questions. 3.27 + */ 3.28 + 3.29 +package com.sun.tools.javac.code; 3.30 + 3.31 +import java.util.Map; 3.32 + 3.33 +import javax.tools.JavaFileObject; 3.34 + 3.35 +import com.sun.tools.javac.comp.Annotate; 3.36 +import com.sun.tools.javac.comp.AttrContext; 3.37 +import com.sun.tools.javac.comp.Env; 3.38 +import com.sun.tools.javac.util.*; 3.39 +import com.sun.tools.javac.util.Assert; 3.40 +import com.sun.tools.javac.util.List; 3.41 +import com.sun.tools.javac.util.Log; 3.42 +import com.sun.tools.javac.util.Pair; 3.43 +import static com.sun.tools.javac.code.Kinds.PCK; 3.44 + 3.45 +/** 3.46 + * Container for all annotations (attributes in javac) on a Symbol. 3.47 + * 3.48 + * This class is explicitly mutable. Its contents will change when attributes 3.49 + * are annotated onto the Symbol. However this class depends on the facts that 3.50 + * List (in javac) is immutable. 3.51 + * 3.52 + * An instance of this class can be in one of three states: 3.53 + * 3.54 + * NOT_STARTED indicates that the Symbol this instance belongs to has not been 3.55 + * annotated (yet). Specifically if the declaration is not annotated this 3.56 + * instance will never move past NOT_STARTED. You can never go back to 3.57 + * NOT_STARTED. 3.58 + * 3.59 + * IN_PROGRESS annotations have been found on the declaration. Will be processed 3.60 + * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list 3.61 + * of attributes (and this moves out of the IN_PROGRESS state). 3.62 + * 3.63 + * "unnamed" this SymbolMetadata contains some attributes, possibly the final set. 3.64 + * While in this state you can only prepend or append to the attributes not set 3.65 + * it directly. You can also move back to the IN_PROGRESS state using reset(). 3.66 + * 3.67 + * <p><b>This is NOT part of any supported API. If you write code that depends 3.68 + * on this, you do so at your own risk. This code and its internal interfaces 3.69 + * are subject to change or deletion without notice.</b> 3.70 + */ 3.71 +public class SymbolMetadata { 3.72 + 3.73 + private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null); 3.74 + private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null); 3.75 + 3.76 + /* 3.77 + * This field should never be null 3.78 + */ 3.79 + private List<Attribute.Compound> attributes = DECL_NOT_STARTED; 3.80 + 3.81 + /* 3.82 + * Type attributes for this symbol. 3.83 + * This field should never be null. 3.84 + */ 3.85 + private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil(); 3.86 + 3.87 + /* 3.88 + * Type attributes of initializers in this class. 3.89 + * Unused if the current symbol is not a ClassSymbol. 3.90 + */ 3.91 + private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil(); 3.92 + 3.93 + /* 3.94 + * Type attributes of class initializers in this class. 3.95 + * Unused if the current symbol is not a ClassSymbol. 3.96 + */ 3.97 + private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil(); 3.98 + 3.99 + /* 3.100 + * The Symbol this SymbolMetadata instance belongs to 3.101 + */ 3.102 + private final Symbol sym; 3.103 + 3.104 + public SymbolMetadata(Symbol sym) { 3.105 + this.sym = sym; 3.106 + } 3.107 + 3.108 + public List<Attribute.Compound> getDeclarationAttributes() { 3.109 + return filterDeclSentinels(attributes); 3.110 + } 3.111 + 3.112 + public List<Attribute.TypeCompound> getTypeAttributes() { 3.113 + return type_attributes; 3.114 + } 3.115 + 3.116 + public List<Attribute.TypeCompound> getInitTypeAttributes() { 3.117 + return init_type_attributes; 3.118 + } 3.119 + 3.120 + public List<Attribute.TypeCompound> getClassInitTypeAttributes() { 3.121 + return clinit_type_attributes; 3.122 + } 3.123 + 3.124 + public void setDeclarationAttributes(List<Attribute.Compound> a) { 3.125 + Assert.check(pendingCompletion() || !isStarted()); 3.126 + if (a == null) { 3.127 + throw new NullPointerException(); 3.128 + } 3.129 + attributes = a; 3.130 + } 3.131 + 3.132 + public void setTypeAttributes(List<Attribute.TypeCompound> a) { 3.133 + if (a == null) { 3.134 + throw new NullPointerException(); 3.135 + } 3.136 + type_attributes = a; 3.137 + } 3.138 + 3.139 + public void setInitTypeAttributes(List<Attribute.TypeCompound> a) { 3.140 + if (a == null) { 3.141 + throw new NullPointerException(); 3.142 + } 3.143 + init_type_attributes = a; 3.144 + } 3.145 + 3.146 + public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) { 3.147 + if (a == null) { 3.148 + throw new NullPointerException(); 3.149 + } 3.150 + clinit_type_attributes = a; 3.151 + } 3.152 + 3.153 + public void setAttributes(SymbolMetadata other) { 3.154 + if (other == null) { 3.155 + throw new NullPointerException(); 3.156 + } 3.157 + setDeclarationAttributes(other.getDeclarationAttributes()); 3.158 + setTypeAttributes(other.getTypeAttributes()); 3.159 + setInitTypeAttributes(other.getInitTypeAttributes()); 3.160 + setClassInitTypeAttributes(other.getClassInitTypeAttributes()); 3.161 + } 3.162 + 3.163 + public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) { 3.164 + Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK)); 3.165 + this.setDeclarationAttributes(getAttributesForCompletion(ctx)); 3.166 + } 3.167 + 3.168 + public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) { 3.169 + this.appendUniqueTypes(getAttributesForCompletion(ctx)); 3.170 + } 3.171 + 3.172 + private <T extends Attribute.Compound> List<T> getAttributesForCompletion( 3.173 + final Annotate.AnnotateRepeatedContext<T> ctx) { 3.174 + 3.175 + Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated; 3.176 + boolean atLeastOneRepeated = false; 3.177 + List<T> buf = List.<T>nil(); 3.178 + for (ListBuffer<T> lb : annotated.values()) { 3.179 + if (lb.size() == 1) { 3.180 + buf = buf.prepend(lb.first()); 3.181 + } else { // repeated 3.182 + // This will break when other subtypes of Attributs.Compound 3.183 + // are introduced, because PlaceHolder is a subtype of TypeCompound. 3.184 + T res; 3.185 + @SuppressWarnings("unchecked") 3.186 + T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym); 3.187 + res = ph; 3.188 + buf = buf.prepend(res); 3.189 + atLeastOneRepeated = true; 3.190 + } 3.191 + } 3.192 + 3.193 + if (atLeastOneRepeated) { 3.194 + // The Symbol s is now annotated with a combination of 3.195 + // finished non-repeating annotations and placeholders for 3.196 + // repeating annotations. 3.197 + // 3.198 + // We need to do this in two passes because when creating 3.199 + // a container for a repeating annotation we must 3.200 + // guarantee that the @Repeatable on the 3.201 + // contained annotation is fully annotated 3.202 + // 3.203 + // The way we force this order is to do all repeating 3.204 + // annotations in a pass after all non-repeating are 3.205 + // finished. This will work because @Repeatable 3.206 + // is non-repeating and therefore will be annotated in the 3.207 + // fist pass. 3.208 + 3.209 + // Queue a pass that will replace Attribute.Placeholders 3.210 + // with Attribute.Compound (made from synthesized containers). 3.211 + ctx.annotateRepeated(new Annotate.Annotator() { 3.212 + @Override 3.213 + public String toString() { 3.214 + return "repeated annotation pass of: " + sym + " in: " + sym.owner; 3.215 + } 3.216 + 3.217 + @Override 3.218 + public void enterAnnotation() { 3.219 + complete(ctx); 3.220 + } 3.221 + }); 3.222 + } 3.223 + // Add non-repeating attributes 3.224 + return buf.reverse(); 3.225 + } 3.226 + 3.227 + public SymbolMetadata reset() { 3.228 + attributes = DECL_IN_PROGRESS; 3.229 + return this; 3.230 + } 3.231 + 3.232 + public boolean isEmpty() { 3.233 + return !isStarted() 3.234 + || pendingCompletion() 3.235 + || attributes.isEmpty(); 3.236 + } 3.237 + 3.238 + public boolean isTypesEmpty() { 3.239 + return type_attributes.isEmpty(); 3.240 + } 3.241 + 3.242 + public boolean pendingCompletion() { 3.243 + return attributes == DECL_IN_PROGRESS; 3.244 + } 3.245 + 3.246 + public SymbolMetadata append(List<Attribute.Compound> l) { 3.247 + attributes = filterDeclSentinels(attributes); 3.248 + 3.249 + if (l.isEmpty()) { 3.250 + ; // no-op 3.251 + } else if (attributes.isEmpty()) { 3.252 + attributes = l; 3.253 + } else { 3.254 + attributes = attributes.appendList(l); 3.255 + } 3.256 + return this; 3.257 + } 3.258 + 3.259 + public SymbolMetadata appendUniqueTypes(List<Attribute.TypeCompound> l) { 3.260 + if (l.isEmpty()) { 3.261 + ; // no-op 3.262 + } else if (type_attributes.isEmpty()) { 3.263 + type_attributes = l; 3.264 + } else { 3.265 + // TODO: in case we expect a large number of annotations, this 3.266 + // might be inefficient. 3.267 + for (Attribute.TypeCompound tc : l) { 3.268 + if (!type_attributes.contains(tc)) 3.269 + type_attributes = type_attributes.append(tc); 3.270 + } 3.271 + } 3.272 + return this; 3.273 + } 3.274 + 3.275 + public SymbolMetadata appendInitTypeAttributes(List<Attribute.TypeCompound> l) { 3.276 + if (l.isEmpty()) { 3.277 + ; // no-op 3.278 + } else if (init_type_attributes.isEmpty()) { 3.279 + init_type_attributes = l; 3.280 + } else { 3.281 + init_type_attributes = init_type_attributes.appendList(l); 3.282 + } 3.283 + return this; 3.284 + } 3.285 + 3.286 + public SymbolMetadata appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) { 3.287 + if (l.isEmpty()) { 3.288 + ; // no-op 3.289 + } else if (clinit_type_attributes.isEmpty()) { 3.290 + clinit_type_attributes = l; 3.291 + } else { 3.292 + clinit_type_attributes = clinit_type_attributes.appendList(l); 3.293 + } 3.294 + return this; 3.295 + } 3.296 + 3.297 + public SymbolMetadata prepend(List<Attribute.Compound> l) { 3.298 + attributes = filterDeclSentinels(attributes); 3.299 + 3.300 + if (l.isEmpty()) { 3.301 + ; // no-op 3.302 + } else if (attributes.isEmpty()) { 3.303 + attributes = l; 3.304 + } else { 3.305 + attributes = attributes.prependList(l); 3.306 + } 3.307 + return this; 3.308 + } 3.309 + 3.310 + private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) { 3.311 + return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED) 3.312 + ? List.<Attribute.Compound>nil() 3.313 + : a; 3.314 + } 3.315 + 3.316 + private boolean isStarted() { 3.317 + return attributes != DECL_NOT_STARTED; 3.318 + } 3.319 + 3.320 + private List<Attribute.Compound> getPlaceholders() { 3.321 + List<Attribute.Compound> res = List.<Attribute.Compound>nil(); 3.322 + for (Attribute.Compound a : filterDeclSentinels(attributes)) { 3.323 + if (a instanceof Placeholder) { 3.324 + res = res.prepend(a); 3.325 + } 3.326 + } 3.327 + return res.reverse(); 3.328 + } 3.329 + 3.330 + private List<Attribute.TypeCompound> getTypePlaceholders() { 3.331 + List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil(); 3.332 + for (Attribute.TypeCompound a : type_attributes) { 3.333 + if (a instanceof Placeholder) { 3.334 + res = res.prepend(a); 3.335 + } 3.336 + } 3.337 + return res.reverse(); 3.338 + } 3.339 + 3.340 + /* 3.341 + * Replace Placeholders for repeating annotations with their containers 3.342 + */ 3.343 + private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) { 3.344 + Log log = ctx.log; 3.345 + Env<AttrContext> env = ctx.env; 3.346 + JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); 3.347 + try { 3.348 + // TODO: can we reduce duplication in the following branches? 3.349 + if (ctx.isTypeCompound) { 3.350 + Assert.check(!isTypesEmpty()); 3.351 + 3.352 + if (isTypesEmpty()) { 3.353 + return; 3.354 + } 3.355 + 3.356 + List<Attribute.TypeCompound> result = List.nil(); 3.357 + for (Attribute.TypeCompound a : getTypeAttributes()) { 3.358 + if (a instanceof Placeholder) { 3.359 + @SuppressWarnings("unchecked") 3.360 + Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a; 3.361 + Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext()); 3.362 + 3.363 + if (null != replacement) { 3.364 + result = result.prepend(replacement); 3.365 + } 3.366 + } else { 3.367 + result = result.prepend(a); 3.368 + } 3.369 + } 3.370 + 3.371 + type_attributes = result.reverse(); 3.372 + 3.373 + Assert.check(SymbolMetadata.this.getTypePlaceholders().isEmpty()); 3.374 + } else { 3.375 + Assert.check(!pendingCompletion()); 3.376 + 3.377 + if (isEmpty()) { 3.378 + return; 3.379 + } 3.380 + 3.381 + List<Attribute.Compound> result = List.nil(); 3.382 + for (Attribute.Compound a : getDeclarationAttributes()) { 3.383 + if (a instanceof Placeholder) { 3.384 + @SuppressWarnings("unchecked") 3.385 + Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx); 3.386 + 3.387 + if (null != replacement) { 3.388 + result = result.prepend(replacement); 3.389 + } 3.390 + } else { 3.391 + result = result.prepend(a); 3.392 + } 3.393 + } 3.394 + 3.395 + attributes = result.reverse(); 3.396 + 3.397 + Assert.check(SymbolMetadata.this.getPlaceholders().isEmpty()); 3.398 + } 3.399 + } finally { 3.400 + log.useSource(oldSource); 3.401 + } 3.402 + } 3.403 + 3.404 + private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) { 3.405 + Log log = ctx.log; 3.406 + 3.407 + // Process repeated annotations 3.408 + T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym); 3.409 + 3.410 + if (validRepeated != null) { 3.411 + // Check that the container isn't manually 3.412 + // present along with repeated instances of 3.413 + // its contained annotation. 3.414 + ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); 3.415 + if (manualContainer != null) { 3.416 + log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", 3.417 + manualContainer.first().type.tsym); 3.418 + } 3.419 + } 3.420 + 3.421 + // A null return will delete the Placeholder 3.422 + return validRepeated; 3.423 + } 3.424 + 3.425 + private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound { 3.426 + 3.427 + private final Annotate.AnnotateRepeatedContext<T> ctx; 3.428 + private final List<T> placeholderFor; 3.429 + private final Symbol on; 3.430 + 3.431 + public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) { 3.432 + super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(), 3.433 + ctx.isTypeCompound ? 3.434 + ((Attribute.TypeCompound)placeholderFor.head).position : 3.435 + null); 3.436 + this.ctx = ctx; 3.437 + this.placeholderFor = placeholderFor; 3.438 + this.on = on; 3.439 + } 3.440 + 3.441 + @Override 3.442 + public String toString() { 3.443 + return "<placeholder: " + placeholderFor + " on: " + on + ">"; 3.444 + } 3.445 + 3.446 + public List<T> getPlaceholderFor() { 3.447 + return placeholderFor; 3.448 + } 3.449 + 3.450 + public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() { 3.451 + return ctx; 3.452 + } 3.453 + } 3.454 +}
4.1 --- a/test/tools/javac/lib/DPrinter.java Sun Sep 08 11:54:21 2013 +0100 4.2 +++ b/test/tools/javac/lib/DPrinter.java Mon Sep 09 09:58:20 2013 +0200 4.3 @@ -49,7 +49,7 @@ 4.4 import com.sun.source.util.TaskListener; 4.5 import com.sun.source.util.Trees; 4.6 import com.sun.tools.javac.api.JavacTrees; 4.7 -import com.sun.tools.javac.code.Annotations; 4.8 +import com.sun.tools.javac.code.SymbolMetadata; 4.9 import com.sun.tools.javac.code.Attribute; 4.10 import com.sun.tools.javac.code.Flags; 4.11 import com.sun.tools.javac.code.Kinds; 4.12 @@ -186,21 +186,21 @@ 4.13 FULL 4.14 }; 4.15 4.16 - public void printAnnotations(String label, Annotations annotations) { 4.17 + public void printAnnotations(String label, SymbolMetadata annotations) { 4.18 printAnnotations(label, annotations, Details.FULL); 4.19 } 4.20 4.21 - protected void printAnnotations(String label, Annotations annotations, Details details) { 4.22 + protected void printAnnotations(String label, SymbolMetadata annotations, Details details) { 4.23 if (annotations == null) { 4.24 printNull(label); 4.25 } else { 4.26 // no SUMMARY format currently available to use 4.27 4.28 // use reflection to get at private fields 4.29 - Object DECL_NOT_STARTED = getField(null, Annotations.class, "DECL_NOT_STARTED"); 4.30 - Object DECL_IN_PROGRESS = getField(null, Annotations.class, "DECL_IN_PROGRESS"); 4.31 - Object attributes = getField(annotations, Annotations.class, "attributes"); 4.32 - Object type_attributes = getField(annotations, Annotations.class, "type_attributes"); 4.33 + Object DECL_NOT_STARTED = getField(null, SymbolMetadata.class, "DECL_NOT_STARTED"); 4.34 + Object DECL_IN_PROGRESS = getField(null, SymbolMetadata.class, "DECL_IN_PROGRESS"); 4.35 + Object attributes = getField(annotations, SymbolMetadata.class, "attributes"); 4.36 + Object type_attributes = getField(annotations, SymbolMetadata.class, "type_attributes"); 4.37 4.38 if (!showEmptyItems) { 4.39 if (attributes instanceof List && ((List) attributes).isEmpty()