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