X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Fast%2FConstructorDeclaration.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Fast%2FConstructorDeclaration.java;h=0000000000000000000000000000000000000000;hb=6f0cd02d46e011bd5599e1b7fefc6159cb811135;hp=7170bbf40d60755c9a86e35efa5f1a4dfd9fe537;hpb=622d0e5a4b1b35b6918a516a79a0cc22272a919e;p=org.ibex.tool.git diff --git a/src/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/src/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java deleted file mode 100644 index 7170bbf..0000000 --- a/src/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java +++ /dev/null @@ -1,454 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 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 org.eclipse.jdt.internal.compiler.ast; - -import java.util.ArrayList; - -import org.eclipse.jdt.core.compiler.*; -import org.eclipse.jdt.internal.compiler.*; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.codegen.*; -import org.eclipse.jdt.internal.compiler.flow.*; -import org.eclipse.jdt.internal.compiler.lookup.*; -import org.eclipse.jdt.internal.compiler.parser.*; -import org.eclipse.jdt.internal.compiler.problem.*; - -public class ConstructorDeclaration extends AbstractMethodDeclaration { - - public ExplicitConstructorCall constructorCall; - public final static char[] ConstantPoolName = "".toCharArray(); //$NON-NLS-1$ - public boolean isDefaultConstructor = false; - - public ConstructorDeclaration(CompilationResult compilationResult){ - super(compilationResult); - } - - 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.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){ - int size; - if ((size = computedExceptions.size()) > 0){ - ReferenceBinding[] actuallyThrownExceptions; - 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 (constructorCall.accessMode == ExplicitConstructorCall.This) { - FieldBinding[] fields = binding.declaringClass.fields(); - for (int i = 0, count = fields.length; i < count; i++) { - FieldBinding field; - if (!(field = fields[i]).isStatic()) { - flowInfo.markAsDefinitelyAssigned(field); - } - } - } - 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 = statements[i]; - if (!stat.complainIfUnreachable(flowInfo, scope, didAlreadyComplain)) { - flowInfo = stat.analyseCode(scope, constructorContext, flowInfo); - } else { - didAlreadyComplain = true; - } - } - } - // check for missing returning path - this.needFreeReturn = flowInfo.isReachable(); - - // check missing blank final field initializations - if ((constructorCall != null) - && (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]))) { - scope.problemReporter().uninitializedBlankFinalField( - field, - isDefaultConstructor ? (ASTNode) scope.referenceType() : this); - } - } - } - // check unreachable catch blocks - constructorContext.complainIfUnusedExceptionHandlers(this); - } catch (AbortMethod e) { - this.ignoreFurtherInvestigation = true; - } - } - - /** - * Bytecode generation for a constructor - * - * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope - * @param classFile org.eclipse.jdt.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 { - 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 methodScope, - 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 >= ClassFileConstants.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, null); - } - } - - public boolean isConstructor() { - - return true; - } - - public boolean isDefaultConstructor() { - - return this.isDefaultConstructor; - } - - public boolean isInitializationMethod() { - - return true; - } - - /** - * Returns true if the constructor is directly involved in a cycle. - * Given most constructors aren't, we only allocate the visited list - * lazily. - * - * @param visited - * @return - */ - 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(Parser parser, CompilationUnitDeclaration unit) { - - //fill up the constructor body with its statements - if (ignoreFurtherInvestigation) - return; - if (isDefaultConstructor){ - constructorCall = SuperReference.implicitSuperConstructorCall(); - constructorCall.sourceStart = sourceStart; - constructorCall.sourceEnd = sourceEnd; - return; - } - parser.parse(this, unit); - - } - - public StringBuffer printBody(int indent, StringBuffer output) { - - output.append(" {"); //$NON-NLS-1$ - if (constructorCall != null) { - output.append('\n'); - constructorCall.printStatement(indent, output); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (statements != null) { - for (int i = 0; i < statements.length; i++) { - output.append('\n'); - statements[i].printStatement(indent, output); //$NON-NLS-1$ - } - } - output.append('\n'); - printIndent(indent == 0 ? 0 : indent - 1, output).append('}'); - return output; - } - - public void resolveJavadoc() { - - if (this.binding == null || this.javadoc != null) { - super.resolveJavadoc(); - } else if (!isDefaultConstructor) { - this.scope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers); - } - } - - /* - * Type checking for constructor, just another method, except for special check - * for recursive constructor invocations. - */ - public void resolveStatements() { - - if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector)){ - scope.problemReporter().missingReturnType(this); - } - - // if null ==> an error has occurs at parsing time .... - if (this.constructorCall != null) { - // e.g. using super() in java.lang.Object - 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 { - this.constructorCall.resolve(this.scope); - } - } - if ((modifiers & AccSemicolonBody) != 0) { - scope.problemReporter().methodNeedBody(this); - } - super.resolveStatements(); - } - - public void traverse( - ASTVisitor visitor, - ClassScope classScope) { - - if (visitor.visit(this, classScope)) { - if (arguments != null) { - int argumentLength = arguments.length; - for (int i = 0; i < argumentLength; i++) - arguments[i].traverse(visitor, scope); - } - if (thrownExceptions != null) { - int thrownExceptionsLength = thrownExceptions.length; - for (int i = 0; i < thrownExceptionsLength; i++) - thrownExceptions[i].traverse(visitor, scope); - } - if (constructorCall != null) - constructorCall.traverse(visitor, scope); - if (statements != null) { - int statementsLength = statements.length; - for (int i = 0; i < statementsLength; i++) - statements[i].traverse(visitor, scope); - } - } - visitor.endVisit(this, classScope); - } -}