X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AllocationExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AllocationExpression.java index 3c999d0..7eb480b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AllocationExpression.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AllocationExpression.java @@ -1,19 +1,28 @@ /******************************************************************************* - * 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.*; -import net.sourceforge.phpdt.internal.compiler.flow.*; -import net.sourceforge.phpdt.internal.compiler.lookup.*; +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.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.NestedTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticArgumentBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; public class AllocationExpression extends Expression @@ -26,7 +35,6 @@ public class AllocationExpression MethodBinding syntheticAccessor; public AllocationExpression() { - super(); } public FlowInfo analyseCode( @@ -34,7 +42,8 @@ public class AllocationExpression FlowContext flowContext, FlowInfo flowInfo) { - // must verify that exceptions potentially thrown by this expression are caught in the method + // check captured variables are initialized in current context (26134) + checkCapturedLocalInitializationIfNecessary(this.binding.declaringClass, currentScope, flowInfo); // process arguments if (arguments != null) { @@ -47,7 +56,7 @@ public class AllocationExpression } // record some dependency information for exception types ReferenceBinding[] thrownExceptions; - if (((thrownExceptions = binding.thrownExceptions).length) != 0) { + if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) { // check exception handling flowContext.checkExceptionHandlers( thrownExceptions, @@ -57,57 +66,85 @@ public class AllocationExpression } manageEnclosingInstanceAccessIfNecessary(currentScope); manageSyntheticAccessIfNecessary(currentScope); + return flowInfo; } + public void checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo) { + + if (checkedType.isLocalType() + && !checkedType.isAnonymousType() + && !currentScope.isDefinedInType(checkedType)) { // only check external allocations + NestedTypeBinding nestedType = (NestedTypeBinding) checkedType; + SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables(); + if (syntheticArguments != null) + for (int i = 0, count = syntheticArguments.length; i < count; i++){ + SyntheticArgumentBinding syntheticArgument = syntheticArguments[i]; + LocalVariableBinding targetLocal; + if ((targetLocal = syntheticArgument.actualOuterLocalVariable) == null) continue; +// if (targetLocal.declaration != null && !flowInfo.isDefinitelyAssigned(targetLocal)){ +// currentScope.problemReporter().uninitializedLocalVariable(targetLocal, this); +// } + } + + } + } + public Expression enclosingInstance() { return null; } - public void generateCode( - BlockScope currentScope, - CodeStream codeStream, - boolean valueRequired) { - - int pc = codeStream.position; - ReferenceBinding allocatedType = binding.declaringClass; - - codeStream.new_(allocatedType); - if (valueRequired) { - codeStream.dup(); - } - // better highlight for allocation: display the type individually - codeStream.recordPositionsFrom(pc, type.sourceStart); - - // handling innerclass instance allocation - if (allocatedType.isNestedType()) { - codeStream.generateSyntheticArgumentValues( - currentScope, - allocatedType, - enclosingInstance(), - this); - } - // generate the arguments for constructor - if (arguments != null) { - for (int i = 0, count = arguments.length; i < count; i++) { - arguments[i].generateCode(currentScope, codeStream, true); - } - } - // invoke constructor - if (syntheticAccessor == null) { - codeStream.invokespecial(binding); - } else { - // synthetic accessor got some extra arguments appended to its signature, which need values - for (int i = 0, - max = syntheticAccessor.parameters.length - binding.parameters.length; - i < max; - i++) { - codeStream.aconst_null(); - } - codeStream.invokespecial(syntheticAccessor); - } - codeStream.recordPositionsFrom(pc, this.sourceStart); - } +// public void generateCode( +// BlockScope currentScope, +// CodeStream codeStream, +// boolean valueRequired) { +// +// int pc = codeStream.position; +// ReferenceBinding allocatedType = binding.declaringClass; +// +// codeStream.new_(allocatedType); +// if (valueRequired) { +// codeStream.dup(); +// } +// // better highlight for allocation: display the type individually +// codeStream.recordPositionsFrom(pc, type.sourceStart); +// +// // handling innerclass instance allocation - enclosing instance arguments +// if (allocatedType.isNestedType()) { +// codeStream.generateSyntheticEnclosingInstanceValues( +// currentScope, +// allocatedType, +// enclosingInstance(), +// this); +// } +// // generate the arguments for constructor +// if (arguments != null) { +// for (int i = 0, count = arguments.length; i < count; i++) { +// arguments[i].generateCode(currentScope, codeStream, true); +// } +// } +// // handling innerclass instance allocation - outer local arguments +// if (allocatedType.isNestedType()) { +// codeStream.generateSyntheticOuterArgumentValues( +// currentScope, +// allocatedType, +// this); +// } +// // invoke constructor +// if (syntheticAccessor == null) { +// codeStream.invokespecial(binding); +// } else { +// // synthetic accessor got some extra arguments appended to its signature, which need values +// for (int i = 0, +// max = syntheticAccessor.parameters.length - binding.parameters.length; +// i < max; +// i++) { +// codeStream.aconst_null(); +// } +// codeStream.invokespecial(syntheticAccessor); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } public boolean isSuperAccess() { @@ -135,14 +172,11 @@ public class AllocationExpression && currentScope.enclosingSourceType().isLocalType()) { if (allocatedType.isLocalType()) { - ((LocalTypeBinding) allocatedType).addInnerEmulationDependent( - currentScope, - false, - false); + ((LocalTypeBinding) allocatedType).addInnerEmulationDependent(currentScope, false); // request cascade of accesses } else { // locally propagate, since we already now the desired shape for sure - currentScope.propagateInnerEmulation(allocatedType, false, false); + currentScope.propagateInnerEmulation(allocatedType, false); // request cascade of accesses } } @@ -153,25 +187,37 @@ public class AllocationExpression if (binding.isPrivate() && (currentScope.enclosingSourceType() != binding.declaringClass)) { - if (currentScope - .environment() - .options - .isPrivateConstructorAccessChangingVisibility) { - binding.tagForClearingPrivateModifier(); - // constructor will not be dumped as private, no emulation required thus - } else { +// if (currentScope +// .environment() +// .options +// .isPrivateConstructorAccessChangingVisibility) { +// binding.tagForClearingPrivateModifier(); +// // constructor will not be dumped as private, no emulation required thus +// } else { syntheticAccessor = - ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding); + ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding, isSuperAccess()); currentScope.problemReporter().needToEmulateMethodAccess(binding, this); - } +// } } } + public StringBuffer printExpression(int indent, StringBuffer output) { + output.append("new "); //$NON-NLS-1$ + type.printExpression(0, output); + output.append('('); + if (arguments != null) { + for (int i = 0; i < arguments.length; i++) { + if (i > 0) output.append(", "); //$NON-NLS-1$ + arguments[i].printExpression(0, output); + } + } + return output.append(')'); + } public TypeBinding resolveType(BlockScope scope) { // Propagate the type checking to the arguments, and check if the constructor is defined. constant = NotAConstant; - TypeBinding typeBinding = type.resolveType(scope); + this.resolvedType = type.resolveType(scope); // will check for null after args are resolved // buffering the arguments' types @@ -184,22 +230,22 @@ public class AllocationExpression if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null) argHasError = true; if (argHasError) - return typeBinding; + return this.resolvedType; } - if (typeBinding == null) + if (this.resolvedType == null) return null; - if (!typeBinding.canBeInstantiated()) { - scope.problemReporter().cannotInstantiate(type, typeBinding); - return typeBinding; + if (!this.resolvedType.canBeInstantiated()) { + scope.problemReporter().cannotInstantiate(type, this.resolvedType); + return this.resolvedType; } - ReferenceBinding allocatedType = (ReferenceBinding) typeBinding; + ReferenceBinding allocatedType = (ReferenceBinding) this.resolvedType; if (!(binding = scope.getConstructor(allocatedType, argumentTypes, this)) .isValidBinding()) { if (binding.declaringClass == null) binding.declaringClass = allocatedType; scope.problemReporter().invalidConstructor(this, binding); - return typeBinding; + return this.resolvedType; } if (isMethodUseDeprecated(binding, scope)) scope.problemReporter().deprecatedMethod(binding, this); @@ -240,7 +286,7 @@ public class AllocationExpression return s; } - public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + public void traverse(ASTVisitor visitor, BlockScope scope) { if (visitor.visit(this, scope)) { int argumentsLength; @@ -253,4 +299,4 @@ public class AllocationExpression } visitor.endVisit(this, scope); } -} \ No newline at end of file +}