001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
011:
012: import org.eclipse.jdt.internal.compiler.ASTVisitor;
013: import org.eclipse.jdt.internal.compiler.ClassFile;
014: import org.eclipse.jdt.internal.compiler.CompilationResult;
015: import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
016: import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
017: import org.eclipse.jdt.internal.compiler.parser.Parser;
018:
019: public class AnnotationMethodDeclaration extends MethodDeclaration {
020:
021: public Expression defaultValue;
022: public int extendedDimensions;
023:
024: /**
025: * MethodDeclaration constructor comment.
026: */
027: public AnnotationMethodDeclaration(
028: CompilationResult compilationResult) {
029: super (compilationResult);
030: }
031:
032: public void generateCode(ClassFile classFile) {
033: classFile.generateMethodInfoHeader(this .binding);
034: int methodAttributeOffset = classFile.contentsOffset;
035: int attributeNumber = classFile.generateMethodInfoAttribute(
036: this .binding, this );
037: classFile.completeMethodInfo(methodAttributeOffset,
038: attributeNumber);
039: }
040:
041: public boolean isAnnotationMethod() {
042:
043: return true;
044: }
045:
046: public boolean isMethod() {
047:
048: return false;
049: }
050:
051: public void parseStatements(Parser parser,
052: CompilationUnitDeclaration unit) {
053: // nothing to do
054: // annotation type member declaration don't have any body
055: }
056:
057: public StringBuffer print(int tab, StringBuffer output) {
058:
059: printIndent(tab, output);
060: printModifiers(this .modifiers, output);
061: if (this .annotations != null)
062: printAnnotations(this .annotations, output);
063:
064: TypeParameter[] typeParams = typeParameters();
065: if (typeParams != null) {
066: output.append('<');
067: int max = typeParams.length - 1;
068: for (int j = 0; j < max; j++) {
069: typeParams[j].print(0, output);
070: output.append(", ");//$NON-NLS-1$
071: }
072: typeParams[max].print(0, output);
073: output.append('>');
074: }
075:
076: printReturnType(0, output).append(this .selector).append('(');
077: if (this .arguments != null) {
078: for (int i = 0; i < this .arguments.length; i++) {
079: if (i > 0)
080: output.append(", "); //$NON-NLS-1$
081: this .arguments[i].print(0, output);
082: }
083: }
084: output.append(')');
085: if (this .thrownExceptions != null) {
086: output.append(" throws "); //$NON-NLS-1$
087: for (int i = 0; i < this .thrownExceptions.length; i++) {
088: if (i > 0)
089: output.append(", "); //$NON-NLS-1$
090: this .thrownExceptions[i].print(0, output);
091: }
092: }
093:
094: if (this .defaultValue != null) {
095: output.append(" default "); //$NON-NLS-1$
096: this .defaultValue.print(0, output);
097: }
098:
099: printBody(tab + 1, output);
100: return output;
101: }
102:
103: public void resolveStatements() {
104:
105: super .resolveStatements();
106: if (this .arguments != null) {
107: scope.problemReporter()
108: .annotationMembersCannotHaveParameters(this );
109: }
110: if (this .typeParameters != null) {
111: scope.problemReporter()
112: .annotationMembersCannotHaveTypeParameters(this );
113: }
114: if (this .extendedDimensions != 0) {
115: scope.problemReporter().illegalExtendedDimensions(this );
116: }
117: if (this .binding == null)
118: return;
119: TypeBinding returnTypeBinding = this .binding.returnType;
120: if (returnTypeBinding != null) {
121:
122: // annotation methods can only return base types, String, Class, enum type, annotation types and arrays of these
123: checkAnnotationMethodType: {
124: TypeBinding leafReturnType = returnTypeBinding
125: .leafComponentType();
126: if (returnTypeBinding.dimensions() <= 1) { // only 1-dimensional array permitted
127: switch (leafReturnType.erasure().id) {
128: case T_byte:
129: case T_short:
130: case T_char:
131: case T_int:
132: case T_long:
133: case T_float:
134: case T_double:
135: case T_boolean:
136: case T_JavaLangString:
137: case T_JavaLangClass:
138: break checkAnnotationMethodType;
139: }
140: if (leafReturnType.isEnum()
141: || leafReturnType.isAnnotationType())
142: break checkAnnotationMethodType;
143: }
144: scope.problemReporter().invalidAnnotationMemberType(
145: this );
146: }
147: if (this .defaultValue != null) {
148: MemberValuePair pair = new MemberValuePair(
149: this .selector, this .sourceStart,
150: this .sourceEnd, this .defaultValue);
151: pair.binding = this .binding;
152: pair.resolveTypeExpecting(scope, returnTypeBinding);
153: this .binding
154: .setDefaultValue(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair
155: .getValue(this .defaultValue));
156: } else { // let it know it does not have a default value so it won't try to find it
157: this .binding.setDefaultValue(null);
158: }
159: }
160: }
161:
162: public void traverse(ASTVisitor visitor, ClassScope classScope) {
163:
164: if (visitor.visit(this , classScope)) {
165: if (this .annotations != null) {
166: int annotationsLength = this .annotations.length;
167: for (int i = 0; i < annotationsLength; i++)
168: this.annotations[i].traverse(visitor, scope);
169: }
170: if (this.returnType != null) {
171: this.returnType.traverse(visitor, scope);
172: }
173: if (this.defaultValue != null) {
174: this.defaultValue.traverse(visitor, scope);
175: }
176: }
177: visitor.endVisit(this, classScope);
178: }
179: }
|