bd66b66850105454c4589203570ffe5478adb42d
[phpeclipse.git] /
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
14 import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
15 import net.sourceforge.phpdt.internal.compiler.lookup.*;
16 import net.sourceforge.phpdt.internal.compiler.problem.*;
17
18 public class AnonymousLocalTypeDeclaration extends LocalTypeDeclaration {
19
20         public static final char[] ANONYMOUS_EMPTY_NAME = new char[] {};
21         public QualifiedAllocationExpression allocation;
22
23         public AnonymousLocalTypeDeclaration(CompilationResult compilationResult) {
24                 super(compilationResult);
25                 modifiers = AccDefault;
26                 name = ANONYMOUS_EMPTY_NAME;
27         } 
28         
29         // use a default name in order to th name lookup 
30         // to operate juat like a regular type (which has a name)
31         //without checking systematically if the naem is null .... 
32         public MethodBinding createsInternalConstructorWithBinding(MethodBinding inheritedConstructorBinding) {
33
34                 //Add to method'set, the default constuctor that just recall the
35                 //super constructor with the same arguments
36                 String baseName = "$anonymous"; //$NON-NLS-1$
37                 TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters;
38                 int argumentsLength = argumentTypes.length;
39                 //the constructor
40                 ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationResult);
41                 cd.selector = new char[] { 'x' }; //no maining
42                 cd.sourceStart = sourceStart;
43                 cd.sourceEnd = sourceEnd;
44                 cd.modifiers = modifiers & AccVisibilityMASK;
45                 cd.isDefaultConstructor = true;
46
47                 if (argumentsLength > 0) {
48                         Argument[] arguments = (cd.arguments = new Argument[argumentsLength]);
49                         for (int i = argumentsLength; --i >= 0;) {
50                                 arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, AccDefault);
51                         }
52                 }
53
54                 //the super call inside the constructor
55                 cd.constructorCall =
56                         new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
57                 cd.constructorCall.sourceStart = sourceStart;
58                 cd.constructorCall.sourceEnd = sourceEnd;
59
60                 if (argumentsLength > 0) {
61                         Expression[] args;
62                         args = cd.constructorCall.arguments = new Expression[argumentsLength];
63                         for (int i = argumentsLength; --i >= 0;) {
64                                 args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L);
65                         }
66                 }
67
68                 //adding the constructor in the methods list
69                 if (methods == null) {
70                         methods = new AbstractMethodDeclaration[] { cd };
71                 } else {
72                         AbstractMethodDeclaration[] newMethods;
73                         System.arraycopy(
74                                 methods,
75                                 0,
76                                 newMethods = new AbstractMethodDeclaration[methods.length + 1],
77                                 1,
78                                 methods.length);
79                         newMethods[0] = cd;
80                         methods = newMethods;
81                 }
82
83                 //============BINDING UPDATE==========================
84                 cd.binding = new MethodBinding(
85                                 cd.modifiers, //methodDeclaration
86                                 argumentsLength == 0 ? NoParameters : argumentTypes, //arguments bindings
87                                 inheritedConstructorBinding.thrownExceptions, //exceptions
88                                 binding); //declaringClass
89                                 
90                 cd.scope = new MethodScope(scope, this, true);
91                 cd.bindArguments();
92                 cd.constructorCall.resolve(cd.scope);
93
94                 if (binding.methods == null) {
95                         binding.methods = new MethodBinding[] { cd.binding };
96                 } else {
97                         MethodBinding[] newMethods;
98                         System.arraycopy(
99                                 binding.methods,
100                                 0,
101                                 newMethods = new MethodBinding[binding.methods.length + 1],
102                                 1,
103                                 binding.methods.length);
104                         newMethods[0] = cd.binding;
105                         binding.methods = newMethods;
106                 }
107                 //===================================================
108
109                 return cd.binding;
110
111         }
112         public void resolve(BlockScope scope) {
113
114                 // scope and binding are provided in updateBindingSuperclass 
115                 resolve();
116                 updateMaxFieldCount();
117         }
118
119         public String toString(int tab) {
120
121                 return toStringBody(tab);
122         }
123
124         /**
125          *      Iteration for a local anonymous innertype
126          *
127          */
128         public void traverse(
129                 IAbstractSyntaxTreeVisitor visitor,
130                 BlockScope blockScope) {
131
132                 if (ignoreFurtherInvestigation)
133                         return;
134                 try {
135                         if (visitor.visit(this, blockScope)) {
136
137                                 int fieldsLength;
138                                 int methodsLength;
139                                 int memberTypesLength;
140
141                                 // <superclass> is bound to the actual type from the allocation expression
142                                 // therefore it has already been iterated at this point.
143
144                                 if (memberTypes != null) {
145                                         memberTypesLength = memberTypes.length;
146                                         for (int i = 0; i < memberTypesLength; i++)
147                                                 memberTypes[i].traverse(visitor, scope);
148                                 }
149                                 if (fields != null) {
150                                         fieldsLength = fields.length;
151                                         for (int i = 0; i < fieldsLength; i++) {
152                                                 FieldDeclaration field;
153                                                 if ((field = fields[i]).isStatic()) {
154                                                         // local type cannot have static fields
155                                                 } else {
156                                                         field.traverse(visitor, initializerScope);
157                                                 }
158                                         }
159                                 }
160                                 if (methods != null) {
161                                         methodsLength = methods.length;
162                                         for (int i = 0; i < methodsLength; i++)
163                                                 methods[i].traverse(visitor, scope);
164                                 }
165                         }
166                         visitor.endVisit(this, blockScope);
167                 } catch (AbortType e) {
168                 }
169         }
170 }