X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ConstructorDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ConstructorDeclaration.java index a47678b..e43ddcb 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ConstructorDeclaration.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ConstructorDeclaration.java @@ -1,87 +1,89 @@ /******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. + * 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 v0.5 + * 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-v05.html + * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation - ******************************************************************************/ + *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.ast; import java.util.ArrayList; -import net.sourceforge.phpdt.core.compiler.IProblem; -import net.sourceforge.phpdt.internal.compiler.ClassFile; +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.ASTVisitor; import net.sourceforge.phpdt.internal.compiler.CompilationResult; -import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; -import net.sourceforge.phpdt.internal.compiler.codegen.CodeStream; import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext; import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext; import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope; import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; -import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; -import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope; -import net.sourceforge.phpdt.internal.compiler.lookup.NestedTypeBinding; import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; -import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticArgumentBinding; -import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; -import net.sourceforge.phpdt.internal.compiler.parser.Parser; +import net.sourceforge.phpdt.internal.compiler.parser.UnitParser; import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod; -import net.sourceforge.phpdt.internal.compiler.util.CharOperation; public class ConstructorDeclaration extends AbstractMethodDeclaration { public ExplicitConstructorCall constructorCall; + public final static char[] ConstantPoolName = "".toCharArray(); //$NON-NLS-1$ - public boolean isDefaultConstructor = false; - public int referenceCount = 0; - // count how many times this constructor is referenced from other local constructors + public boolean isDefaultConstructor = false; - public ConstructorDeclaration(CompilationResult compilationResult){ + public ConstructorDeclaration(CompilationResult compilationResult) { super(compilationResult); } - - public void analyseCode( - ClassScope classScope, - InitializationFlowContext initializerFlowContext, - FlowInfo flowInfo) { + + public void analyseCode(ClassScope classScope, + InitializationFlowContext initializerFlowContext, FlowInfo flowInfo) { if (ignoreFurtherInvestigation) return; + + if (this.binding != null && this.binding.isPrivate() + && !this.binding.isPrivateUsed()) { + if (!classScope.referenceCompilationUnit().compilationResult + .hasSyntaxError()) { + scope.problemReporter().unusedPrivateConstructor(this); + } + } + + // check constructor recursion, once all constructor got resolved + if (isRecursive(null /* lazy initialized visited list */)) { + this.scope.problemReporter().recursiveConstructorInvocation( + this.constructorCall); + } + try { - ExceptionHandlingFlowContext constructorContext = - new ExceptionHandlingFlowContext( - initializerFlowContext.parent, - this, - binding.thrownExceptions, - scope, - FlowInfo.DeadEnd); - initializerFlowContext.checkInitializerExceptions( - scope, - constructorContext, - flowInfo); - - // anonymous constructor can gain extra thrown exceptions from unhandled ones + ExceptionHandlingFlowContext constructorContext = new ExceptionHandlingFlowContext( + initializerFlowContext.parent, this, + binding.thrownExceptions, scope, FlowInfo.DEAD_END); + initializerFlowContext.checkInitializerExceptions(scope, + constructorContext, flowInfo); + + // anonymous constructor can gain extra thrown exceptions from + // unhandled ones if (binding.declaringClass.isAnonymousType()) { ArrayList computedExceptions = constructorContext.extendedExceptions; - if (computedExceptions != null){ + if (computedExceptions != null) { int size; - if ((size = computedExceptions.size()) > 0){ + if ((size = computedExceptions.size()) > 0) { ReferenceBinding[] actuallyThrownExceptions; - computedExceptions.toArray(actuallyThrownExceptions = new ReferenceBinding[size]); + computedExceptions + .toArray(actuallyThrownExceptions = new ReferenceBinding[size]); binding.thrownExceptions = actuallyThrownExceptions; } } } - + // propagate to constructor call if (constructorCall != null) { - // if calling 'this(...)', then flag all non-static fields as definitely - // set since they are supposed to be set inside other local constructor + // if calling 'this(...)', then flag all non-static fields as + // definitely + // set since they are supposed to be set inside other local + // constructor if (constructorCall.accessMode == ExplicitConstructorCall.This) { FieldBinding[] fields = binding.declaringClass.fields(); for (int i = 0, count = fields.length; i < count; i++) { @@ -91,34 +93,40 @@ public class ConstructorDeclaration extends AbstractMethodDeclaration { } } } - flowInfo = constructorCall.analyseCode(scope, constructorContext, flowInfo); + flowInfo = constructorCall.analyseCode(scope, + constructorContext, flowInfo); } // propagate to statements if (statements != null) { + boolean didAlreadyComplain = false; for (int i = 0, count = statements.length; i < count; i++) { Statement stat; - if (!flowInfo.complainIfUnreachable((stat = statements[i]), scope)) { - flowInfo = stat.analyseCode(scope, constructorContext, flowInfo); + if (!flowInfo.complainIfUnreachable(stat = statements[i], + scope, didAlreadyComplain)) { + flowInfo = stat.analyseCode(scope, constructorContext, + flowInfo); + } else { + didAlreadyComplain = true; } } } // check for missing returning path - needFreeReturn = - !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable()); + this.needFreeReturn = flowInfo.isReachable(); // check missing blank final field initializations if ((constructorCall != null) - && (constructorCall.accessMode != ExplicitConstructorCall.This)) { - flowInfo = flowInfo.mergedWith(initializerFlowContext.initsOnReturn); + && (constructorCall.accessMode != ExplicitConstructorCall.This)) { + flowInfo = flowInfo + .mergedWith(constructorContext.initsOnReturn); FieldBinding[] fields = binding.declaringClass.fields(); for (int i = 0, count = fields.length; i < count; i++) { FieldBinding field; - if ((!(field = fields[i]).isStatic()) - && field.isFinal() - && (!flowInfo.isDefinitelyAssigned(fields[i]))) { + if ((!(field = fields[i]).isStatic()) && field.isFinal() + && (!flowInfo.isDefinitelyAssigned(fields[i]))) { scope.problemReporter().uninitializedBlankFinalField( - field, - isDefaultConstructor ? (AstNode) scope.referenceType() : this); + field, + isDefaultConstructor ? (ASTNode) scope + .referenceType() : this); } } } @@ -129,159 +137,205 @@ public class ConstructorDeclaration extends AbstractMethodDeclaration { /** * Bytecode generation for a constructor - * - * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope - * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile + * + * @param classScope + * net.sourceforge.phpdt.internal.compiler.lookup.ClassScope + * @param classFile + * net.sourceforge.phpdt.internal.compiler.codegen.ClassFile */ - public void generateCode(ClassScope classScope, ClassFile classFile) { - int problemResetPC = 0; - if (ignoreFurtherInvestigation) { - if (this.binding == null) - return; // Handle methods with invalid signature or duplicates - int problemsLength; - IProblem[] problems = - scope.referenceCompilationUnit().compilationResult.getProblems(); - IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; - System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); - classFile.addProblemConstructor(this, binding, problemsCopy); - return; - } - try { - problemResetPC = classFile.contentsOffset; - this.internalGenerateCode(classScope, classFile); - } catch (AbortMethod e) { - if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { - // a branch target required a goto_w, restart code gen in wide mode. - try { - if (statements != null) { - for (int i = 0, max = statements.length; i < max; i++) - statements[i].resetStateForCodeGeneration(); - } - classFile.contentsOffset = problemResetPC; - classFile.methodCount--; - classFile.codeStream.wideMode = true; // request wide mode - this.internalGenerateCode(classScope, classFile); // restart method generation - } catch (AbortMethod e2) { - int problemsLength; - IProblem[] problems = - scope.referenceCompilationUnit().compilationResult.getProblems(); - IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; - System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); - classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC); - } - } else { - int problemsLength; - IProblem[] problems = - scope.referenceCompilationUnit().compilationResult.getProblems(); - IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; - System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); - classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC); - } - } - } - - private void internalGenerateCode(ClassScope classScope, ClassFile classFile) { - classFile.generateMethodInfoHeader(binding); - int methodAttributeOffset = classFile.contentsOffset; - int attributeNumber = classFile.generateMethodInfoAttribute(binding); - if ((!binding.isNative()) && (!binding.isAbstract())) { - TypeDeclaration declaringType = classScope.referenceContext; - int codeAttributeOffset = classFile.contentsOffset; - classFile.generateCodeAttributeHeader(); - CodeStream codeStream = classFile.codeStream; - codeStream.reset(this, classFile); - // initialize local positions - including initializer scope. - ReferenceBinding declaringClass = binding.declaringClass; - int argSize = 0; - scope.computeLocalVariablePositions(// consider synthetic arguments if any - argSize = - declaringClass.isNestedType() - ? ((NestedTypeBinding) declaringClass).syntheticArgumentsOffset - : 1, - codeStream); - if (arguments != null) { - for (int i = 0, max = arguments.length; i < max; i++) { - // arguments initialization for local variable debug attributes - LocalVariableBinding argBinding; - codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding); - argBinding.recordInitializationStartPC(0); - TypeBinding argType; - if ((argType = argBinding.type) == LongBinding || (argType == DoubleBinding)) { - argSize += 2; - } else { - argSize++; - } - } - } - MethodScope initializerScope = declaringType.initializerScope; - initializerScope.computeLocalVariablePositions(argSize, codeStream); - // offset by the argument size (since not linked to method scope) - - // generate constructor call - if (constructorCall != null) { - constructorCall.generateCode(scope, codeStream); - } - // generate field initialization - only if not invoking another constructor call of the same class - if ((constructorCall != null) - && (constructorCall.accessMode != ExplicitConstructorCall.This)) { - // generate synthetic fields initialization - if (declaringClass.isNestedType()) { - NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; - SyntheticArgumentBinding[] syntheticArgs = - nestedType.syntheticEnclosingInstances(); - for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; - i < max; - i++) { - if (syntheticArgs[i].matchingField != null) { - codeStream.aload_0(); - codeStream.load(syntheticArgs[i]); - codeStream.putfield(syntheticArgs[i].matchingField); - } - } - syntheticArgs = nestedType.syntheticOuterLocalVariables(); - for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; - i < max; - i++) { - if (syntheticArgs[i].matchingField != null) { - codeStream.aload_0(); - codeStream.load(syntheticArgs[i]); - codeStream.putfield(syntheticArgs[i].matchingField); - } - } - } - // generate user field initialization - if (declaringType.fields != null) { - for (int i = 0, max = declaringType.fields.length; i < max; i++) { - FieldDeclaration fieldDecl; - if (!(fieldDecl = declaringType.fields[i]).isStatic()) { - fieldDecl.generateCode(initializerScope, codeStream); - } - } - } - } - // generate statements - if (statements != null) { - for (int i = 0, max = statements.length; i < max; i++) { - statements[i].generateCode(scope, codeStream); - } - } - if (needFreeReturn) { - codeStream.return_(); - } - // local variable attributes - codeStream.exitUserScope(scope); - codeStream.recordPositionsFrom(0, this.bodyEnd); - classFile.completeCodeAttribute(codeAttributeOffset); - attributeNumber++; - } - classFile.completeMethodInfo(methodAttributeOffset, attributeNumber); - - // if a problem got reported during code gen, then trigger problem method creation - if (ignoreFurtherInvestigation) { - throw new AbortMethod(scope.referenceCompilationUnit().compilationResult); - } - } - + // public void generateCode(ClassScope classScope, ClassFile classFile) { + // + // int problemResetPC = 0; + // if (ignoreFurtherInvestigation) { + // if (this.binding == null) + // return; // Handle methods with invalid signature or duplicates + // int problemsLength; + // IProblem[] problems = + // scope.referenceCompilationUnit().compilationResult.getProblems(); + // IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; + // System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); + // classFile.addProblemConstructor(this, binding, problemsCopy); + // return; + // } + // try { + // problemResetPC = classFile.contentsOffset; + // this.internalGenerateCode(classScope, classFile); + // } catch (AbortMethod e) { + // if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { + // // a branch target required a goto_w, restart code gen in wide mode. + // try { + // if (statements != null) { + // for (int i = 0, max = statements.length; i < max; i++) + // statements[i].resetStateForCodeGeneration(); + // } + // classFile.contentsOffset = problemResetPC; + // classFile.methodCount--; + // classFile.codeStream.wideMode = true; // request wide mode + // this.internalGenerateCode(classScope, classFile); // restart method + // generation + // } catch (AbortMethod e2) { + // int problemsLength; + // IProblem[] problems = + // scope.referenceCompilationUnit().compilationResult.getAllProblems(); + // IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; + // System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); + // classFile.addProblemConstructor(this, binding, problemsCopy, + // problemResetPC); + // } + // } else { + // int problemsLength; + // IProblem[] problems = + // scope.referenceCompilationUnit().compilationResult.getAllProblems(); + // IProblem[] problemsCopy = new IProblem[problemsLength = problems.length]; + // System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); + // classFile.addProblemConstructor(this, binding, problemsCopy, + // problemResetPC); + // } + // } + // } + // + // public void generateSyntheticFieldInitializationsIfNecessary( + // MethodScope scope, + // CodeStream codeStream, + // ReferenceBinding declaringClass) { + // + // if (!declaringClass.isNestedType()) return; + // + // NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; + // + // SyntheticArgumentBinding[] syntheticArgs = + // nestedType.syntheticEnclosingInstances(); + // for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i + // < max; i++) { + // SyntheticArgumentBinding syntheticArg; + // if ((syntheticArg = syntheticArgs[i]).matchingField != null) { + // codeStream.aload_0(); + // codeStream.load(syntheticArg); + // codeStream.putfield(syntheticArg.matchingField); + // } + // } + // syntheticArgs = nestedType.syntheticOuterLocalVariables(); + // for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i + // < max; i++) { + // SyntheticArgumentBinding syntheticArg; + // if ((syntheticArg = syntheticArgs[i]).matchingField != null) { + // codeStream.aload_0(); + // codeStream.load(syntheticArg); + // codeStream.putfield(syntheticArg.matchingField); + // } + // } + // } + // + // private void internalGenerateCode(ClassScope classScope, ClassFile + // classFile) { + // + // classFile.generateMethodInfoHeader(binding); + // int methodAttributeOffset = classFile.contentsOffset; + // int attributeNumber = classFile.generateMethodInfoAttribute(binding); + // if ((!binding.isNative()) && (!binding.isAbstract())) { + // + // TypeDeclaration declaringType = classScope.referenceContext; + // int codeAttributeOffset = classFile.contentsOffset; + // classFile.generateCodeAttributeHeader(); + // CodeStream codeStream = classFile.codeStream; + // codeStream.reset(this, classFile); + // + // // initialize local positions - including initializer scope. + // ReferenceBinding declaringClass = binding.declaringClass; + // + // int argSlotSize = 1; // this==aload0 + // + // if (declaringClass.isNestedType()){ + // NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; + // this.scope.extraSyntheticArguments = + // nestedType.syntheticOuterLocalVariables(); + // scope.computeLocalVariablePositions(// consider synthetic arguments if + // any + // nestedType.enclosingInstancesSlotSize + 1, + // codeStream); + // argSlotSize += nestedType.enclosingInstancesSlotSize; + // argSlotSize += nestedType.outerLocalVariablesSlotSize; + // } else { + // scope.computeLocalVariablePositions(1, codeStream); + // } + // + // if (arguments != null) { + // for (int i = 0, max = arguments.length; i < max; i++) { + // // arguments initialization for local variable debug attributes + // LocalVariableBinding argBinding; + // codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding); + // argBinding.recordInitializationStartPC(0); + // TypeBinding argType; + // if ((argType = argBinding.type) == LongBinding || (argType == + // DoubleBinding)) { + // argSlotSize += 2; + // } else { + // argSlotSize++; + // } + // } + // } + // + // MethodScope initializerScope = declaringType.initializerScope; + // initializerScope.computeLocalVariablePositions(argSlotSize, codeStream); + // // offset by the argument size (since not linked to method scope) + // + // boolean needFieldInitializations = constructorCall == null || + // constructorCall.accessMode != ExplicitConstructorCall.This; + // + // // post 1.4 source level, synthetic initializations occur prior to + // explicit constructor call + // boolean preInitSyntheticFields = scope.environment().options.targetJDK >= + // CompilerOptions.JDK1_4; + // + // if (needFieldInitializations && preInitSyntheticFields){ + // generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, + // declaringClass); + // } + // // generate constructor call + // if (constructorCall != null) { + // constructorCall.generateCode(scope, codeStream); + // } + // // generate field initialization - only if not invoking another + // constructor call of the same class + // if (needFieldInitializations) { + // if (!preInitSyntheticFields){ + // generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, + // declaringClass); + // } + // // generate user field initialization + // if (declaringType.fields != null) { + // for (int i = 0, max = declaringType.fields.length; i < max; i++) { + // FieldDeclaration fieldDecl; + // if (!(fieldDecl = declaringType.fields[i]).isStatic()) { + // fieldDecl.generateCode(initializerScope, codeStream); + // } + // } + // } + // } + // // generate statements + // if (statements != null) { + // for (int i = 0, max = statements.length; i < max; i++) { + // statements[i].generateCode(scope, codeStream); + // } + // } + // if (this.needFreeReturn) { + // codeStream.return_(); + // } + // // local variable attributes + // codeStream.exitUserScope(scope); + // codeStream.recordPositionsFrom(0, this.bodyEnd); + // classFile.completeCodeAttribute(codeAttributeOffset); + // attributeNumber++; + // } + // classFile.completeMethodInfo(methodAttributeOffset, attributeNumber); + // + // // if a problem got reported during code gen, then trigger problem method + // creation + // if (ignoreFurtherInvestigation) { + // throw new + // AbortMethod(scope.referenceCompilationUnit().compilationResult); + // } + // } public boolean isConstructor() { return true; @@ -297,16 +351,46 @@ public class ConstructorDeclaration extends AbstractMethodDeclaration { return true; } - public void parseStatements(Parser parser, CompilationUnitDeclaration unit) { + /** + * Returns true if the constructor is directly involved in a cycle. Given + * most constructors aren't, we only allocate the visited list lazily. + */ + public boolean isRecursive(ArrayList visited) { + + if (this.binding == null || this.constructorCall == null + || this.constructorCall.binding == null + || this.constructorCall.isSuperAccess() + || !this.constructorCall.binding.isValidBinding()) { + return false; + } + + ConstructorDeclaration targetConstructor = ((ConstructorDeclaration) this.scope + .referenceType().declarationOf(constructorCall.binding)); + if (this == targetConstructor) + return true; // direct case + + if (visited == null) { // lazy allocation + visited = new ArrayList(1); + } else { + int index = visited.indexOf(this); + if (index >= 0) + return index == 0; // only blame if directly part of the cycle + } + visited.add(this); + + return targetConstructor.isRecursive(visited); + } + + public void parseStatements(UnitParser parser, + CompilationUnitDeclaration unit) { - //fill up the constructor body with its statements + // fill up the constructor body with its statements if (ignoreFurtherInvestigation) return; - if (isDefaultConstructor){ - constructorCall = - new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); + if (isDefaultConstructor) { + constructorCall = SuperReference.implicitSuperConstructorCall(); constructorCall.sourceStart = sourceStart; - constructorCall.sourceEnd = sourceEnd; + constructorCall.sourceEnd = sourceEnd; return; } parser.parse(this, unit); @@ -314,48 +398,33 @@ public class ConstructorDeclaration extends AbstractMethodDeclaration { } /* - * Type checking for constructor, just another method, except for special check - * for recursive constructor invocations. + * Type checking for constructor, just another method, except for special + * check for recursive constructor invocations. */ - public void resolveStatements(ClassScope upperScope) { -/* - // checking for recursive constructor call (protection) - if (!ignoreFurtherInvestigation && constructorCall == null){ - constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); - constructorCall.sourceStart = sourceStart; - constructorCall.sourceEnd = sourceEnd; - } -*/ - if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector)){ + public void resolveStatements() { + + if (!CharOperation.equals(scope.enclosingSourceType().sourceName, + selector)) { scope.problemReporter().missingReturnType(this); } // if null ==> an error has occurs at parsing time .... - if (constructorCall != null) { + if (this.constructorCall != null) { // e.g. using super() in java.lang.Object - if (binding != null - && binding.declaringClass.id == T_Object - && constructorCall.accessMode != ExplicitConstructorCall.This) { - if (constructorCall.accessMode == ExplicitConstructorCall.Super) { - scope.problemReporter().cannotUseSuperInJavaLangObject(constructorCall); - } - constructorCall = null; + if (this.binding != null + && this.binding.declaringClass.id == T_Object + && this.constructorCall.accessMode != ExplicitConstructorCall.This) { + if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) { + scope.problemReporter().cannotUseSuperInJavaLangObject( + this.constructorCall); + } + this.constructorCall = null; } else { - constructorCall.resolve(scope); - } - } - - super.resolveStatements(upperScope); - - // indirect reference: increment target constructor reference count - if (constructorCall != null){ - if (constructorCall.binding != null - && !constructorCall.isSuperAccess() - && constructorCall.binding.isValidBinding()) { - ((ConstructorDeclaration) - (upperScope.referenceContext.declarationOf(constructorCall.binding))).referenceCount++; + this.constructorCall.resolve(this.scope); } } + + super.resolveStatements(); } public String toStringStatements(int tab) { @@ -377,9 +446,7 @@ public class ConstructorDeclaration extends AbstractMethodDeclaration { return s; } - public void traverse( - IAbstractSyntaxTreeVisitor visitor, - ClassScope classScope) { + public void traverse(ASTVisitor visitor, ClassScope classScope) { if (visitor.visit(this, classScope)) { if (arguments != null) { @@ -402,4 +469,4 @@ public class ConstructorDeclaration extends AbstractMethodDeclaration { } visitor.endVisit(this, classScope); } -} \ No newline at end of file +}