import eclipse 3.1 M4 compiler
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / AnnotationMethodDeclaration.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
12
13 import org.eclipse.jdt.internal.compiler.ASTVisitor;
14 import org.eclipse.jdt.internal.compiler.ClassFile;
15 import org.eclipse.jdt.internal.compiler.CompilationResult;
16 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
17 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
18 import org.eclipse.jdt.internal.compiler.parser.Parser;
19
20 public class AnnotationMethodDeclaration extends MethodDeclaration {
21         
22         public Expression defaultValue;
23         public int extendedDimensions;
24
25         /**
26          * MethodDeclaration constructor comment.
27          */
28         public AnnotationMethodDeclaration(CompilationResult compilationResult) {
29                 super(compilationResult);
30         }
31
32         public void generateCode(ClassFile classFile) {
33                 classFile.generateMethodInfoHeader(this.binding);
34                 int methodAttributeOffset = classFile.contentsOffset;
35                 int attributeNumber = classFile.generateMethodInfoAttribute(this.binding, this);
36                 classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
37         }
38         
39         public boolean isAnnotationMethod() {
40
41                 return true;
42         }
43         
44         public boolean isMethod() {
45
46                 return false;
47         }
48         
49         public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
50                 // nothing to do
51                 // annotation type member declaration don't have any body
52         }
53         
54         public StringBuffer print(int tab, StringBuffer output) {
55
56                 printIndent(tab, output);
57                 printModifiers(this.modifiers, output);
58                 if (this.annotations != null) printAnnotations(this.annotations, output);
59                 
60                 TypeParameter[] typeParams = typeParameters();
61                 if (typeParams != null) {
62                         output.append('<');//$NON-NLS-1$
63                         int max = typeParams.length - 1;
64                         for (int j = 0; j < max; j++) {
65                                 typeParams[j].print(0, output);
66                                 output.append(", ");//$NON-NLS-1$
67                         }
68                         typeParams[max].print(0, output);
69                         output.append('>');
70                 }
71                 
72                 printReturnType(0, output).append(this.selector).append('(');
73                 if (this.arguments != null) {
74                         for (int i = 0; i < this.arguments.length; i++) {
75                                 if (i > 0) output.append(", "); //$NON-NLS-1$
76                                 this.arguments[i].print(0, output);
77                         }
78                 }
79                 output.append(')');
80                 if (this.thrownExceptions != null) {
81                         output.append(" throws "); //$NON-NLS-1$
82                         for (int i = 0; i < this.thrownExceptions.length; i++) {
83                                 if (i > 0) output.append(", "); //$NON-NLS-1$
84                                 this.thrownExceptions[i].print(0, output);
85                         }
86                 }
87                 
88                 if (this.defaultValue != null) {
89                         output.append(" default "); //$NON-NLS-1$
90                         this.defaultValue.print(0, output);
91                 }
92                 
93                 printBody(tab + 1, output);
94                 return output;
95         }
96         
97         public void resolveStatements() {
98
99                 super.resolveStatements();
100                 if (this.arguments != null) {
101                         scope.problemReporter().annotationMembersCannotHaveParameters(this);
102                 }
103                 if (this.typeParameters != null) {
104                         scope.problemReporter().annotationMembersCannotHaveTypeParameters(this);
105                 }
106                 if (this.extendedDimensions != 0) {
107                         scope.problemReporter().illegalExtendedDimensions(this);                
108                 }               
109                 if (this.binding == null) return;
110                 TypeBinding returnTypeBinding = this.binding.returnType;
111                 if (returnTypeBinding != null) {
112                                 
113                         // annotation methods can only return base types, String, Class, enum type, annotation types and arrays of these
114                         checkAnnotationMethodType: {
115                                 TypeBinding leafReturnType = returnTypeBinding.leafComponentType();
116                                         
117                                 switch (leafReturnType.erasure().id) {
118                                         case T_byte :
119                                         case T_short :
120                                         case T_char :
121                                         case T_int :
122                                         case T_long :
123                                         case T_float :
124                                         case T_double :
125                                         case T_boolean :
126                                         case T_JavaLangString :
127                                         case T_JavaLangClass :
128                                                 if (returnTypeBinding.dimensions() <= 1) // only 1-dimensional array permitted
129                                                         break checkAnnotationMethodType;
130                                 }
131                                 if (leafReturnType.isEnum()) {
132                                         if (returnTypeBinding.dimensions() <= 1) // only 1-dimensional array permitted
133                                                 break checkAnnotationMethodType;
134                                 }
135                                 if (leafReturnType.isAnnotationType()) {
136                                         scope.classScope().detectAnnotationCycle(scope.enclosingSourceType(), leafReturnType, this.returnType);
137                                         if (returnTypeBinding.dimensions() <= 1) // only 1-dimensional array permitted
138                                                 break checkAnnotationMethodType;
139                                 }
140                                 scope.problemReporter().invalidAnnotationMemberType(this);
141                         }
142                         if (this.defaultValue != null) {
143                                 MemberValuePair pair = new MemberValuePair(this.selector, this.sourceStart, this.sourceEnd, this.defaultValue);
144                                 pair.binding = this.binding;
145                                 pair.resolveTypeExpecting(scope, returnTypeBinding);
146                         }
147                 }
148         }
149
150         public void traverse(
151                 ASTVisitor visitor,
152                 ClassScope classScope) {
153
154                 if (visitor.visit(this, classScope)) {
155                         if (this.annotations != null) {
156                                 int annotationsLength = this.annotations.length;
157                                 for (int i = 0; i < annotationsLength; i++)
158                                         this.annotations[i].traverse(visitor, scope);
159                         }
160                         if (this.returnType != null) {
161                                 this.returnType.traverse(visitor, scope);
162                         }
163                         if (this.defaultValue != null) {
164                                 this.defaultValue.traverse(visitor, scope);
165                         }
166                 }
167                 visitor.endVisit(this, classScope);
168         }
169 }