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