X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/LocalDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/LocalDeclaration.java index 51dcdab..59073c2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/LocalDeclaration.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/LocalDeclaration.java @@ -1,20 +1,18 @@ /******************************************************************************* - * 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 net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; -import net.sourceforge.phpdt.internal.compiler.codegen.CodeStream; +import net.sourceforge.phpdt.internal.compiler.ASTVisitor; import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; -import net.sourceforge.phpdt.internal.compiler.impl.Constant; import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding; import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding; import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; @@ -25,11 +23,8 @@ public class LocalDeclaration extends AbstractVariableDeclaration { public LocalVariableBinding binding; - public LocalDeclaration( - Expression expr, - char[] name, - int sourceStart, - int sourceEnd) { + public LocalDeclaration(Expression expr, char[] name, int sourceStart, + int sourceEnd) { initialization = expr; this.name = name; @@ -37,97 +32,121 @@ public class LocalDeclaration extends AbstractVariableDeclaration { this.sourceEnd = sourceEnd; if (initialization != null) { this.declarationSourceEnd = initialization.sourceEnd; + this.declarationEnd = initialization.sourceEnd; } else { - this.declarationSourceEnd = sourceEnd; + this.declarationEnd = sourceEnd; } - this.declarationEnd = this.declarationSourceEnd; } - public FlowInfo analyseCode( - BlockScope currentScope, - FlowContext flowContext, - FlowInfo flowInfo) { + public FlowInfo analyseCode(BlockScope currentScope, + FlowContext flowContext, FlowInfo flowInfo) { // record variable initialization if any - if (!flowInfo.isDeadEnd() && !flowInfo.isFakeReachable()) { - bits |= IsLocalDeclarationReachableMASK; // only set if actually reached + if (flowInfo.isReachable()) { + bits |= IsLocalDeclarationReachableMASK; // only set if actually + // reached } if (initialization == null) return flowInfo; - flowInfo = - initialization - .analyseCode(currentScope, flowContext, flowInfo) - .unconditionalInits(); + + flowInfo = initialization.analyseCode(currentScope, flowContext, + flowInfo).unconditionalInits(); + + // final int i = (i = 0); + // no need to complain since (i = 0) part will get the blame + // if (binding.isFinal() && flowInfo.isPotentiallyAssigned(binding)) { + // currentScope.problemReporter().duplicateInitializationOfFinalLocal(binding, + // this); + // } + flowInfo.markAsDefinitelyAssigned(binding); return flowInfo; } public void checkModifiers() { - //only potential valid modifier is <> - if (((modifiers & AccJustFlag) | AccFinal) != AccFinal) - //AccModifierProblem -> other (non-visibility problem) - //AccAlternateModifierProblem -> duplicate modifier - //AccModifierProblem | AccAlternateModifierProblem -> visibility problem" - // -x-1 returns the bitInvert + // only potential valid modifier is <> + if (((modifiers & AccJustFlag) & ~AccFinal) != 0) + // AccModifierProblem -> other (non-visibility problem) + // AccAlternateModifierProblem -> duplicate modifier + // AccModifierProblem | AccAlternateModifierProblem -> visibility + // problem" - modifiers = - (modifiers & (-AccAlternateModifierProblem - 1)) | AccModifierProblem; + modifiers = (modifiers & ~AccAlternateModifierProblem) + | AccModifierProblem; } /** - * Code generation for a local declaration: - * i.e. normal assignment to a local variable + unused variable handling + * Code generation for a local declaration: normal assignment to a local + * variable + unused variable handling */ - public void generateCode(BlockScope currentScope, CodeStream codeStream) { - - if ((bits & IsReachableMASK) == 0) { - return; - } - int pc = codeStream.position; - Constant inlinedValue; - // something to initialize? - if (binding.resolvedPosition != -1) { - codeStream.addVisibleLocalVariable(binding); - } - if (initialization != null) { - // initialize to constant value? - if ((inlinedValue = initialization.constant) != NotAConstant) { - // forget initializing unused or final locals set to constant value (final ones are inlined) - if (binding.resolvedPosition != -1) { // may need to preserve variable - int initPC = codeStream.position; - codeStream.generateConstant(inlinedValue, initialization.implicitConversion); - codeStream.recordPositionsFrom(initPC, initialization.sourceStart); - codeStream.store(binding, false); - binding.recordInitializationStartPC(codeStream.position); - // codeStream.lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index - // codeStream.lastInitStateIndexWhenAddingInits = -2; // reinitialize add index - } - } else { // initializing to non-constant value - initialization.generateCode(currentScope, codeStream, true); - // if binding unused generate then discard the value - if (binding.resolvedPosition != -1) { - codeStream.store(binding, false); - if (binding.initializationCount == 0) { - /* Variable may have been initialized during the code initializing it - e.g. int i = (i = 1); - */ - binding.recordInitializationStartPC(codeStream.position); - // codeStream.lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index - // codeStream.lastInitStateIndexWhenAddingInits = -2; // reinitialize add index - } - } else { - if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) { - codeStream.pop2(); - } else { - codeStream.pop(); - } - } - } - } - codeStream.recordPositionsFrom(pc, this.sourceStart); - } - + // public void generateCode(BlockScope currentScope, CodeStream codeStream) + // { + // + // // even if not reachable, variable must be added to visible if allocated + // (28298) + // if (binding.resolvedPosition != -1) { + // codeStream.addVisibleLocalVariable(binding); + // } + // if ((bits & IsReachableMASK) == 0) { + // return; + // } + // int pc = codeStream.position; + // Constant inlinedValue; + // + // // something to initialize? + // if (initialization != null) { + // // initialize to constant value? + // if ((inlinedValue = initialization.constant) != NotAConstant) { + // // forget initializing unused or final locals set to constant value + // (final ones are inlined) + // if (binding.resolvedPosition != -1) { // may need to preserve variable + // int initPC = codeStream.position; + // codeStream.generateConstant(inlinedValue, + // initialization.implicitConversion); + // codeStream.recordPositionsFrom(initPC, initialization.sourceStart); + // codeStream.store(binding, false); + // binding.recordInitializationStartPC(codeStream.position); + // // codeStream.lastInitStateIndexWhenRemovingInits = -2; // reinitialize + // remove index + // // codeStream.lastInitStateIndexWhenAddingInits = -2; // reinitialize add + // index + // } + // } else { // initializing to non-constant value + // initialization.generateCode(currentScope, codeStream, true); + // // if binding unused generate then discard the value + // if (binding.resolvedPosition != -1) { + // // 26903, need extra cast to store null in array local var + // if (binding.type.isArrayType() + // && (initialization.resolvedType == NullBinding // arrayLoc = null + // || ((initialization instanceof CastExpression) // arrayLoc = (type[])null + // && + // (((CastExpression)initialization).innermostCastedExpression().resolvedType + // == NullBinding)))){ + // codeStream.checkcast(binding.type); + // } + // codeStream.store(binding, false); + // if (binding.initializationCount == 0) { + // /* Variable may have been initialized during the code initializing it + // e.g. int i = (i = 1); + // */ + // binding.recordInitializationStartPC(codeStream.position); + // // codeStream.lastInitStateIndexWhenRemovingInits = -2; // reinitialize + // remove index + // // codeStream.lastInitStateIndexWhenAddingInits = -2; // reinitialize add + // index + // } + // } else { + // if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) { + // codeStream.pop2(); + // } else { + // codeStream.pop(); + // } + // } + // } + // } + // codeStream.recordPositionsFrom(pc, this.sourceStart); + // } public String name() { return String.valueOf(name); @@ -145,7 +164,8 @@ public class LocalDeclaration extends AbstractVariableDeclaration { scope.problemReporter().variableTypeCannotBeVoid(this); return; } - if (tb.isArrayType() && ((ArrayBinding) tb).leafComponentType == VoidBinding) { + if (tb.isArrayType() + && ((ArrayBinding) tb).leafComponentType == VoidBinding) { scope.problemReporter().variableTypeCannotBeVoidArray(this); return; } @@ -156,23 +176,29 @@ public class LocalDeclaration extends AbstractVariableDeclaration { // the name already exists... may carry on with the first binding... scope.problemReporter().redefineLocal(this); } else { + if ((modifiers & AccFinal) != 0 && this.initialization == null) { + modifiers |= AccBlankFinal; + } binding = new LocalVariableBinding(this, tb, modifiers, false); scope.addLocalVariable(binding); binding.constant = NotAConstant; // allow to recursivelly target the binding.... - // the correct constant is harmed if correctly computed at the end of this method + // the correct constant is harmed if correctly computed at the end + // of this method } if (tb == null) { if (initialization != null) - initialization.resolveType(scope); // want to report all possible errors + initialization.resolveType(scope); // want to report all + // possible errors return; } - // store the constant for final locals + // store the constant for final locals if (initialization != null) { if (initialization instanceof ArrayInitializer) { - TypeBinding initTb = initialization.resolveTypeExpecting(scope, tb); + TypeBinding initTb = initialization.resolveTypeExpecting(scope, + tb); if (initTb != null) { ((ArrayInitializer) initialization).binding = (ArrayBinding) initTb; initialization.implicitWidening(tb, initTb); @@ -180,26 +206,29 @@ public class LocalDeclaration extends AbstractVariableDeclaration { } else { TypeBinding initTb = initialization.resolveType(scope); if (initTb != null) { - if (initialization.isConstantValueOfTypeAssignableToType(initTb, tb) - || (tb.isBaseType() && BaseTypeBinding.isWidening(tb.id, initTb.id)) - || BlockScope.areTypesCompatible(initTb, tb)) + if (initialization.isConstantValueOfTypeAssignableToType( + initTb, tb) + || (tb.isBaseType() && BaseTypeBinding.isWidening( + tb.id, initTb.id)) + || initTb.isCompatibleWith(tb)) initialization.implicitWidening(tb, initTb); else - scope.problemReporter().typeMismatchError(initTb, tb, this); + scope.problemReporter().typeMismatchError(initTb, tb, + this); } } // change the constant in the binding when it is final - // (the optimization of the constant propagation will be done later on) + // (the optimization of the constant propagation will be done later + // on) // cast from constant actual type to variable type - binding.constant = - binding.isFinal() - ? initialization.constant.castTo((tb.id << 4) + initialization.constant.typeID()) + binding.constant = binding.isFinal() ? initialization.constant + .castTo((tb.id << 4) + initialization.constant.typeID()) : NotAConstant; } } - public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + public void traverse(ASTVisitor visitor, BlockScope scope) { if (visitor.visit(this, scope)) { type.traverse(visitor, scope); @@ -208,4 +237,4 @@ public class LocalDeclaration extends AbstractVariableDeclaration { } visitor.endVisit(this, scope); } -} \ No newline at end of file +}