| package org.eclipse.jdt.internal.compiler.ast; |
| |
| /* |
| * (c) Copyright IBM Corp. 2000, 2001. |
| * All Rights Reserved. |
| */ |
| import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor; |
| import org.eclipse.jdt.internal.compiler.lookup.*; |
| import org.eclipse.jdt.internal.compiler.problem.*; |
| |
| public class AnonymousLocalTypeDeclaration extends LocalTypeDeclaration { |
| //a temporal default name |
| public static final char[] ANONYMOUS_EMPTY_NAME = new char[]{} ; |
| public QualifiedAllocationExpression allocation; |
| public AnonymousLocalTypeDeclaration(){ |
| super(); |
| modifiers = AccDefault ; |
| name = ANONYMOUS_EMPTY_NAME; } // use a default name in order to th name lookup |
| // to operate juat 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"/*nonNLS*/; |
| TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters; |
| int argumentsLength = argumentTypes.length; |
| //the constructor |
| ConstructorDeclaration cd = new ConstructorDeclaration(); |
| cd.selector = new char[] {'x'}; //no maining |
| cd.sourceStart = sourceStart; |
| cd.sourceEnd = sourceEnd; |
| cd.modifiers = modifiers & AccVisibilityMASK; |
| |
| if (argumentsLength > 0) { |
| Argument[] arguments = (cd.arguments = new Argument[argumentsLength]); |
| for (int i = argumentsLength; --i >= 0;) { |
| arguments[i] = |
| new Argument( |
| (baseName + i).toCharArray(), |
| 0L, |
| //toCharArray() could be optimized .... |
| null, //no meaning (a TypeReference) |
| AccDefault); |
| } |
| } |
| |
| //the super call inside the constructor |
| cd.constructorCall = |
| new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); |
| 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, this, 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) { |
| // scope and binding are provided in updateBindingSuperclass |
| |
| resolve(); |
| updateMaxFieldCount(); |
| } |
| public String toString(int tab ){ |
| /*slow code */ |
| |
| return toStringBody(tab); |
| } |
| /** |
| * Iteration for a local anonymous innertype |
| * |
| */ |
| public void traverse(IAbstractSyntaxTreeVisitor 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) { |
| } |
| } |
| } |