001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.core.ext.typeinfo;
017:
018: import java.lang.annotation.Annotation;
019: import java.util.ArrayList;
020: import java.util.List;
021: import java.util.Map;
022:
023: /**
024: * Common superclass for {@link JMethod} and {@link JConstructor}.
025: */
026: public abstract class JAbstractMethod implements HasAnnotations,
027: HasMetaData, HasTypeParameters {
028:
029: private final Annotations annotations;
030:
031: private int bodyEnd;
032:
033: private int bodyStart;
034:
035: private final int declEnd;
036:
037: private final int declStart;
038:
039: private boolean isVarArgs = false;
040:
041: private final HasMetaData metaData = new MetaData();
042:
043: private int modifierBits;
044:
045: private final String name;
046:
047: private final List<JParameter> params = new ArrayList<JParameter>();
048:
049: private final List<JType> thrownTypes = new ArrayList<JType>();
050:
051: private final List<JTypeParameter> typeParams = new ArrayList<JTypeParameter>();
052:
053: // Only the builder can construct
054: JAbstractMethod(
055: String name,
056: int declStart,
057: int declEnd,
058: int bodyStart,
059: int bodyEnd,
060: Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
061: this .name = name;
062: this .declStart = declStart;
063: this .declEnd = declEnd;
064: this .bodyStart = bodyStart;
065: this .bodyEnd = bodyEnd;
066: annotations = new Annotations();
067: annotations.addAnnotations(declaredAnnotations);
068: }
069:
070: /**
071: * @param enclosingType
072: * @param ctor
073: */
074: JAbstractMethod(JAbstractMethod srcMethod) {
075: this .annotations = new Annotations(srcMethod.annotations);
076: this .bodyEnd = srcMethod.bodyEnd;
077: this .bodyStart = srcMethod.bodyStart;
078: this .declEnd = srcMethod.declEnd;
079: this .declStart = srcMethod.declStart;
080: this .isVarArgs = srcMethod.isVarArgs;
081: MetaData.copy(this , srcMethod.metaData);
082: this .modifierBits = srcMethod.modifierBits;
083: this .name = srcMethod.name;
084: }
085:
086: public void addMetaData(String tagName, String[] values) {
087: metaData.addMetaData(tagName, values);
088: }
089:
090: public void addModifierBits(int bits) {
091: modifierBits |= bits;
092: }
093:
094: public void addThrows(JType type) {
095: thrownTypes.add(type);
096: }
097:
098: public JParameter findParameter(String name) {
099: for (JParameter param : params) {
100: if (param.getName().equals(name)) {
101: return param;
102: }
103: }
104: return null;
105: }
106:
107: public <T extends Annotation> T getAnnotation(
108: Class<T> annotationClass) {
109: return annotations.getAnnotation(annotationClass);
110: }
111:
112: public Annotation[] getAnnotations() {
113: return annotations.getAnnotations();
114: }
115:
116: public int getBodyEnd() {
117: return bodyEnd;
118: }
119:
120: public int getBodyStart() {
121: return bodyStart;
122: }
123:
124: public Annotation[] getDeclaredAnnotations() {
125: return annotations.getDeclaredAnnotations();
126: }
127:
128: public int getDeclEnd() {
129: return declEnd;
130: }
131:
132: public int getDeclStart() {
133: return declStart;
134: }
135:
136: /**
137: * Gets the type in which this method or constructor was declared.
138: */
139: public abstract JClassType getEnclosingType();
140:
141: public String[][] getMetaData(String tagName) {
142: return metaData.getMetaData(tagName);
143: }
144:
145: public String[] getMetaDataTags() {
146: return metaData.getMetaDataTags();
147: }
148:
149: public String getName() {
150: return name;
151: }
152:
153: public JParameter[] getParameters() {
154: return params.toArray(TypeOracle.NO_JPARAMS);
155: }
156:
157: public abstract String getReadableDeclaration();
158:
159: public JType[] getThrows() {
160: return thrownTypes.toArray(TypeOracle.NO_JTYPES);
161: }
162:
163: public JTypeParameter[] getTypeParameters() {
164: return typeParams
165: .toArray(new JTypeParameter[typeParams.size()]);
166: }
167:
168: public JAnnotationMethod isAnnotationMethod() {
169: return null;
170: }
171:
172: public boolean isAnnotationPresent(
173: Class<? extends Annotation> annotationClass) {
174: return annotations.isAnnotationPresent(annotationClass);
175: }
176:
177: public abstract JConstructor isConstructor();
178:
179: public boolean isDefaultAccess() {
180: return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC
181: | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
182: }
183:
184: public abstract JMethod isMethod();
185:
186: public boolean isPrivate() {
187: return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
188: }
189:
190: public boolean isProtected() {
191: return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
192: }
193:
194: public boolean isPublic() {
195: return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
196: }
197:
198: public boolean isVarArgs() {
199: return isVarArgs;
200: }
201:
202: public void setVarArgs() {
203: isVarArgs = true;
204: }
205:
206: protected int getModifierBits() {
207: return modifierBits;
208: }
209:
210: protected void toStringParamsAndThrows(StringBuilder sb) {
211: sb.append("(");
212: boolean needComma = false;
213: for (int i = 0, c = params.size(); i < c; ++i) {
214: JParameter param = params.get(i);
215: if (needComma) {
216: sb.append(", ");
217: } else {
218: needComma = true;
219: }
220: if (isVarArgs() && i == c - 1) {
221: JArrayType arrayType = param.getType().isArray();
222: assert (arrayType != null);
223: sb.append(arrayType.getComponentType()
224: .getParameterizedQualifiedSourceName());
225: sb.append("...");
226: } else {
227: sb.append(param.getType()
228: .getParameterizedQualifiedSourceName());
229: }
230: sb.append(" ");
231: sb.append(param.getName());
232: }
233: sb.append(")");
234:
235: if (!thrownTypes.isEmpty()) {
236: sb.append(" throws ");
237: needComma = false;
238: for (JType thrownType : thrownTypes) {
239: if (needComma) {
240: sb.append(", ");
241: } else {
242: needComma = true;
243: }
244: sb.append(thrownType
245: .getParameterizedQualifiedSourceName());
246: }
247: }
248: }
249:
250: protected void toStringTypeParams(StringBuilder sb) {
251: sb.append("<");
252: boolean needComma = false;
253: for (JTypeParameter typeParam : typeParams) {
254: if (needComma) {
255: sb.append(", ");
256: } else {
257: needComma = true;
258: }
259: sb.append(typeParam.getName());
260: sb.append(typeParam.getBounds().toString());
261: }
262: sb.append(">");
263: }
264:
265: void addParameter(JParameter param) {
266: params.add(param);
267: }
268:
269: void addTypeParameter(JTypeParameter typeParameter) {
270: typeParams.add(typeParameter);
271: }
272:
273: boolean hasParamTypes(JType[] paramTypes) {
274: if (params.size() != paramTypes.length) {
275: return false;
276: }
277:
278: for (int i = 0; i < paramTypes.length; i++) {
279: JParameter candidate = params.get(i);
280: // Identity tests are ok since identity is durable within an oracle.
281: //
282: if (candidate.getType() != paramTypes[i]) {
283: return false;
284: }
285: }
286: return true;
287: }
288: }
|