Refactored packagename to net.sourceforge.phpdt.internal.compiler.ast
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / AnonymousLocalTypeDeclaration.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AnonymousLocalTypeDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AnonymousLocalTypeDeclaration.java
new file mode 100644 (file)
index 0000000..73b3689
--- /dev/null
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.compiler.ast;
+
+import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
+import net.sourceforge.phpdt.internal.compiler.CompilationResult;
+import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
+import net.sourceforge.phpdt.internal.compiler.problem.AbortType;
+
+public class AnonymousLocalTypeDeclaration extends LocalTypeDeclaration {
+
+       public static final char[] ANONYMOUS_EMPTY_NAME = new char[] {};
+       public QualifiedAllocationExpression allocation;
+
+       public AnonymousLocalTypeDeclaration(CompilationResult compilationResult) {
+               super(compilationResult);
+               modifiers = AccDefault;
+               name = ANONYMOUS_EMPTY_NAME;
+       } 
+       
+       // use a default name in order to th name lookup 
+       // to operate just like a regular type (which has a name)
+       //without checking systematically if the naem is null .... 
+       public MethodBinding createsInternalConstructorWithBinding(MethodBinding inheritedConstructorBinding) {
+
+               //Add to method'set, the default constuctor that just recall the
+               //super constructor with the same arguments
+               String baseName = "$anonymous"; //$NON-NLS-1$
+               TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters;
+               int argumentsLength = argumentTypes.length;
+               //the constructor
+               ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationResult);
+               cd.selector = new char[] { 'x' }; //no maining
+               cd.sourceStart = sourceStart;
+               cd.sourceEnd = sourceEnd;
+               cd.modifiers = modifiers & AccVisibilityMASK;
+               cd.isDefaultConstructor = true;
+
+               if (argumentsLength > 0) {
+                       Argument[] arguments = (cd.arguments = new Argument[argumentsLength]);
+                       for (int i = argumentsLength; --i >= 0;) {
+                               arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, AccDefault);
+                       }
+               }
+
+               //the super call inside the constructor
+               cd.constructorCall = SuperReference.implicitSuperConstructorCall();
+               cd.constructorCall.sourceStart = sourceStart;
+               cd.constructorCall.sourceEnd = sourceEnd;
+
+               if (argumentsLength > 0) {
+                       Expression[] args;
+                       args = cd.constructorCall.arguments = new Expression[argumentsLength];
+                       for (int i = argumentsLength; --i >= 0;) {
+                               args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L);
+                       }
+               }
+
+               //adding the constructor in the methods list
+               if (methods == null) {
+                       methods = new AbstractMethodDeclaration[] { cd };
+               } else {
+                       AbstractMethodDeclaration[] newMethods;
+                       System.arraycopy(
+                               methods,
+                               0,
+                               newMethods = new AbstractMethodDeclaration[methods.length + 1],
+                               1,
+                               methods.length);
+                       newMethods[0] = cd;
+                       methods = newMethods;
+               }
+
+               //============BINDING UPDATE==========================
+               cd.binding = new MethodBinding(
+                               cd.modifiers, //methodDeclaration
+                               argumentsLength == 0 ? NoParameters : argumentTypes, //arguments bindings
+                               inheritedConstructorBinding.thrownExceptions, //exceptions
+                               binding); //declaringClass
+                               
+               cd.scope = new MethodScope(scope, cd, true);
+               cd.bindArguments();
+               cd.constructorCall.resolve(cd.scope);
+
+               if (binding.methods == null) {
+                       binding.methods = new MethodBinding[] { cd.binding };
+               } else {
+                       MethodBinding[] newMethods;
+                       System.arraycopy(
+                               binding.methods,
+                               0,
+                               newMethods = new MethodBinding[binding.methods.length + 1],
+                               1,
+                               binding.methods.length);
+                       newMethods[0] = cd.binding;
+                       binding.methods = newMethods;
+               }
+               //===================================================
+
+               return cd.binding;
+
+       }
+       public void resolve(BlockScope scope) {
+
+               if (binding != null) {
+                       // remember local types binding for innerclass emulation propagation
+                       scope.referenceCompilationUnit().record((LocalTypeBinding)binding);
+               }
+               // scope and binding are provided in updateBindingSuperclass 
+               resolve();
+               updateMaxFieldCount();
+       }
+
+       public String toString(int tab) {
+
+               return toStringBody(tab);
+       }
+
+       /**
+        *      Iteration for a local anonymous innertype
+        *
+        */
+       public void traverse(
+           ASTVisitor visitor,
+               BlockScope blockScope) {
+
+               if (ignoreFurtherInvestigation)
+                       return;
+               try {
+                       if (visitor.visit(this, blockScope)) {
+
+                               int fieldsLength;
+                               int methodsLength;
+                               int memberTypesLength;
+
+                               // <superclass> is bound to the actual type from the allocation expression
+                               // therefore it has already been iterated at this point.
+
+                               if (memberTypes != null) {
+                                       memberTypesLength = memberTypes.length;
+                                       for (int i = 0; i < memberTypesLength; i++)
+                                               memberTypes[i].traverse(visitor, scope);
+                               }
+                               if (fields != null) {
+                                       fieldsLength = fields.length;
+                                       for (int i = 0; i < fieldsLength; i++) {
+                                               FieldDeclaration field;
+                                               if ((field = fields[i]).isStatic()) {
+                                                       // local type cannot have static fields
+                                               } else {
+                                                       field.traverse(visitor, initializerScope);
+                                               }
+                                       }
+                               }
+                               if (methods != null) {
+                                       methodsLength = methods.length;
+                                       for (int i = 0; i < methodsLength; i++)
+                                               methods[i].traverse(visitor, scope);
+                               }
+                       }
+                       visitor.endVisit(this, blockScope);
+               } catch (AbortType e) {
+               }
+       }
+}