SymbolMetadata.java revision 3828:d30434bde0a8
143166Snsouch/* 243166Snsouch * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 343166Snsouch * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 443166Snsouch * 543166Snsouch * This code is free software; you can redistribute it and/or modify it 643166Snsouch * under the terms of the GNU General Public License version 2 only, as 743166Snsouch * published by the Free Software Foundation. Oracle designates this 843166Snsouch * particular file as subject to the "Classpath" exception as provided 943166Snsouch * by Oracle in the LICENSE file that accompanied this code. 1043166Snsouch * 1143166Snsouch * This code is distributed in the hope that it will be useful, but WITHOUT 1243166Snsouch * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1343166Snsouch * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1443166Snsouch * version 2 for more details (a copy is included in the LICENSE file that 1543166Snsouch * accompanied this code). 1643166Snsouch * 1743166Snsouch * You should have received a copy of the GNU General Public License version 1843166Snsouch * 2 along with this work; if not, write to the Free Software Foundation, 1943166Snsouch * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2043166Snsouch * 2143166Snsouch * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2243166Snsouch * or visit www.oracle.com if you need additional information or have any 2343166Snsouch * questions. 2443166Snsouch */ 2543166Snsouch 2643166Snsouchpackage com.sun.tools.javac.code; 27116192Sobrien 28116192Sobrien 29116192Sobrienimport com.sun.tools.javac.code.Attribute.TypeCompound; 3043166Snsouchimport com.sun.tools.javac.code.Kinds.Kind; 3143166Snsouchimport com.sun.tools.javac.util.Assert; 32165951Sjhbimport com.sun.tools.javac.util.List; 3343166Snsouchimport com.sun.tools.javac.util.ListBuffer; 34165951Sjhb 3543166Snsouch/** 36165951Sjhb * Container for all annotations (attributes in javac) on a Symbol. 3746651Speter * 38165951Sjhb * This class is explicitly mutable. Its contents will change when attributes 3943166Snsouch * are annotated onto the Symbol. However this class depends on the facts that 4043166Snsouch * List (in javac) is immutable. 4143166Snsouch * 4243166Snsouch * An instance of this class can be in one of three states: 43119288Simp * 44119288Simp * NOT_STARTED indicates that the Symbol this instance belongs to has not been 4543166Snsouch * annotated (yet). Specifically if the declaration is not annotated this 4643166Snsouch * instance will never move past NOT_STARTED. You can never go back to 4743166Snsouch * NOT_STARTED. 4843166Snsouch * 49165951Sjhb * IN_PROGRESS annotations have been found on the declaration. Will be processed 50165951Sjhb * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list 51165951Sjhb * of attributes (and this moves out of the IN_PROGRESS state). 52165951Sjhb * 53165951Sjhb * "unnamed" this SymbolMetadata contains some attributes, possibly the final set. 54165951Sjhb * While in this state you can only prepend or append to the attributes not set 55165951Sjhb * it directly. You can also move back to the IN_PROGRESS state using reset(). 56197128Savg * 57197128Savg * <p><b>This is NOT part of any supported API. If you write code that depends 58165951Sjhb * on this, you do so at your own risk. This code and its internal interfaces 5943166Snsouch * are subject to change or deletion without notice.</b> 60162289Sjhb */ 61165951Sjhbpublic class SymbolMetadata { 62165951Sjhb 63165951Sjhb private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null); 64165951Sjhb private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null); 6543166Snsouch 6643166Snsouch /* 67165951Sjhb * This field should never be null 68165951Sjhb */ 69165951Sjhb private List<Attribute.Compound> attributes = DECL_NOT_STARTED; 70165951Sjhb 71162234Sjhb /* 7243166Snsouch * Type attributes for this symbol. 7343166Snsouch * This field should never be null. 7443166Snsouch */ 7543166Snsouch private List<Attribute.TypeCompound> type_attributes = List.nil(); 7643166Snsouch 7743166Snsouch /* 7843166Snsouch * Type attributes of initializers in this class. 7943166Snsouch * Unused if the current symbol is not a ClassSymbol. 8043166Snsouch */ 81162234Sjhb private List<Attribute.TypeCompound> init_type_attributes = List.nil(); 82165951Sjhb 83165951Sjhb /* 84165951Sjhb * Type attributes of class initializers in this class. 85165951Sjhb * Unused if the current symbol is not a ClassSymbol. 86165951Sjhb */ 87162289Sjhb private List<Attribute.TypeCompound> clinit_type_attributes = List.nil(); 88165951Sjhb 89165951Sjhb /* 90165951Sjhb * The Symbol this SymbolMetadata instance belongs to 9143166Snsouch */ 92165951Sjhb private final Symbol sym; 93165951Sjhb 94165951Sjhb public SymbolMetadata(Symbol sym) { 95165951Sjhb this.sym = sym; 96165951Sjhb } 97165951Sjhb 98165951Sjhb public List<Attribute.Compound> getDeclarationAttributes() { 99165951Sjhb return filterDeclSentinels(attributes); 100165951Sjhb } 101234677Savg 102234677Savg public List<Attribute.TypeCompound> getTypeAttributes() { 103234677Savg return type_attributes; 104197128Savg } 105234213Savg 106234213Savg public List<Attribute.TypeCompound> getInitTypeAttributes() { 107234213Savg return init_type_attributes; 108197128Savg } 109197128Savg 110197128Savg public List<Attribute.TypeCompound> getClassInitTypeAttributes() { 111165951Sjhb return clinit_type_attributes; 112165951Sjhb } 113165951Sjhb 11443166Snsouch public void setDeclarationAttributes(List<Attribute.Compound> a) { 115165951Sjhb Assert.check(pendingCompletion() || !isStarted()); 116165951Sjhb if (a == null) { 117162289Sjhb throw new NullPointerException(); 118165951Sjhb } 119165951Sjhb attributes = a; 120165951Sjhb } 121165951Sjhb 122165951Sjhb public void setTypeAttributes(List<Attribute.TypeCompound> a) { 123197128Savg if (a == null) { 124165951Sjhb throw new NullPointerException(); 125162289Sjhb } 126178972Sjhb type_attributes = a; 127178972Sjhb } 128165951Sjhb 12943166Snsouch public void setInitTypeAttributes(List<Attribute.TypeCompound> a) { 130197128Savg if (a == null) { 131197128Savg throw new NullPointerException(); 132197128Savg } 133197128Savg init_type_attributes = a; 134197128Savg } 135197128Savg 136197128Savg public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) { 137197128Savg if (a == null) { 138197128Savg throw new NullPointerException(); 139197128Savg } 140197128Savg clinit_type_attributes = a; 141165951Sjhb } 142165951Sjhb 143165951Sjhb public void setAttributes(SymbolMetadata other) { 144165951Sjhb if (other == null) { 145165951Sjhb throw new NullPointerException(); 146165951Sjhb } 147165951Sjhb setDeclarationAttributes(other.getDeclarationAttributes()); 148165951Sjhb if ((sym.flags() & Flags.BRIDGE) != 0) { 14943166Snsouch Assert.check(other.sym.kind == Kind.MTH); 150197128Savg ListBuffer<TypeCompound> typeAttributes = new ListBuffer<>(); 151197128Savg for (TypeCompound tc : other.getTypeAttributes()) { 152197128Savg // Carry over only contractual type annotations: i.e nothing interior to method body. 153197128Savg if (!tc.position.type.isLocal()) 154197128Savg typeAttributes.append(tc); 155165951Sjhb } 156197128Savg setTypeAttributes(typeAttributes.toList()); 157197128Savg } else { 158197128Savg setTypeAttributes(other.getTypeAttributes()); 159165951Sjhb } 160165951Sjhb if (sym.kind == Kind.TYP) { 161165951Sjhb setInitTypeAttributes(other.getInitTypeAttributes()); 162165951Sjhb setClassInitTypeAttributes(other.getClassInitTypeAttributes()); 163165951Sjhb } 164165951Sjhb } 165197128Savg 166197128Savg public SymbolMetadata reset() { 167197128Savg attributes = DECL_IN_PROGRESS; 168165951Sjhb return this; 169165951Sjhb } 170165951Sjhb 171197128Savg public boolean isEmpty() { 172165951Sjhb return !isStarted() 173197128Savg || pendingCompletion() 174168870Sjhb || attributes.isEmpty(); 17543166Snsouch } 176197325Savg 177197325Savg public boolean isTypesEmpty() { 178197325Savg return type_attributes.isEmpty(); 179197325Savg } 180197325Savg 181197325Savg public boolean pendingCompletion() { 182197128Savg return attributes == DECL_IN_PROGRESS; 183197128Savg } 184197128Savg 185197128Savg public SymbolMetadata append(List<Attribute.Compound> l) { 186165951Sjhb attributes = filterDeclSentinels(attributes); 187165951Sjhb 188165951Sjhb if (l.isEmpty()) { 189165951Sjhb // no-op 19046651Speter } else if (attributes.isEmpty()) { 191165951Sjhb attributes = l; 192165951Sjhb } else { 193197128Savg attributes = attributes.appendList(l); 194197128Savg } 195197128Savg return this; 196165951Sjhb } 197165951Sjhb 198165951Sjhb public SymbolMetadata appendUniqueTypes(List<Attribute.TypeCompound> l) { 199165951Sjhb if (l.isEmpty()) { 200165951Sjhb // no-op 201165951Sjhb } else if (type_attributes.isEmpty()) { 202165951Sjhb type_attributes = l; 20343166Snsouch } else { 204179622Sjhb // TODO: in case we expect a large number of annotations, this 205179622Sjhb // might be inefficient. 206165951Sjhb for (Attribute.TypeCompound tc : l) { 207165951Sjhb if (!type_attributes.contains(tc)) 208165951Sjhb type_attributes = type_attributes.append(tc); 209165951Sjhb } 210162289Sjhb } 211197128Savg return this; 212165951Sjhb } 213165951Sjhb 214165951Sjhb public SymbolMetadata appendInitTypeAttributes(List<Attribute.TypeCompound> l) { 215165951Sjhb if (l.isEmpty()) { 216165951Sjhb // no-op 217165951Sjhb } else if (init_type_attributes.isEmpty()) { 218165951Sjhb init_type_attributes = l; 219165951Sjhb } else { 220165951Sjhb init_type_attributes = init_type_attributes.appendList(l); 221162289Sjhb } 222165951Sjhb return this; 223165951Sjhb } 224165951Sjhb 225165951Sjhb public SymbolMetadata appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) { 226165951Sjhb if (l.isEmpty()) { 22743166Snsouch // no-op 228165951Sjhb } else if (clinit_type_attributes.isEmpty()) { 229165951Sjhb clinit_type_attributes = l; 230165951Sjhb } else { 231165951Sjhb clinit_type_attributes = clinit_type_attributes.appendList(l); 232165951Sjhb } 233162289Sjhb return this; 234165951Sjhb } 23543166Snsouch 236162289Sjhb public SymbolMetadata prepend(List<Attribute.Compound> l) { 237165951Sjhb attributes = filterDeclSentinels(attributes); 238162289Sjhb 239165951Sjhb if (l.isEmpty()) { 240165951Sjhb // no-op 241165951Sjhb } else if (attributes.isEmpty()) { 242162289Sjhb attributes = l; 243165951Sjhb } else { 244165951Sjhb attributes = attributes.prependList(l); 245165951Sjhb } 246165951Sjhb return this; 247165951Sjhb } 248165951Sjhb 249165951Sjhb private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) { 250165951Sjhb return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED) 251165951Sjhb ? List.nil() 252165951Sjhb : a; 253165951Sjhb } 25443166Snsouch 255165951Sjhb private boolean isStarted() { 256165951Sjhb return attributes != DECL_NOT_STARTED; 257165951Sjhb } 25843166Snsouch} 259165951Sjhb