+++ /dev/null
-/*******************************************************************************
- * 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 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 net.sourceforge.phpeclipse.internal.compiler.ast;
-
-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
- implements InvocationSite {
-
- public TypeReference type;
- public Expression[] arguments;
- public MethodBinding binding;
-
- MethodBinding syntheticAccessor;
-
- public AllocationExpression() {
- }
-
- public FlowInfo analyseCode(
- BlockScope currentScope,
- FlowContext flowContext,
- FlowInfo flowInfo) {
-
- // check captured variables are initialized in current context (26134)
- checkCapturedLocalInitializationIfNecessary(this.binding.declaringClass, currentScope, flowInfo);
-
- // process arguments
- if (arguments != null) {
- for (int i = 0, count = arguments.length; i < count; i++) {
- flowInfo =
- arguments[i]
- .analyseCode(currentScope, flowContext, flowInfo)
- .unconditionalInits();
- }
- }
- // record some dependency information for exception types
- ReferenceBinding[] thrownExceptions;
- if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
- // check exception handling
- flowContext.checkExceptionHandlers(
- thrownExceptions,
- this,
- flowInfo,
- currentScope);
- }
- 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 - 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() {
-
- return false;
- }
-
- public boolean isTypeAccess() {
-
- return true;
- }
-
- /* Inner emulation consists in either recording a dependency
- * link only, or performing one level of propagation.
- *
- * Dependency mechanism is used whenever dealing with source target
- * types, since by the time we reach them, we might not yet know their
- * exact need.
- */
- public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-
- ReferenceBinding allocatedType;
-
- // perform some emulation work in case there is some and we are inside a local type only
- if ((allocatedType = binding.declaringClass).isNestedType()
- && currentScope.enclosingSourceType().isLocalType()) {
-
- if (allocatedType.isLocalType()) {
- ((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);
- // request cascade of accesses
- }
- }
- }
-
- public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {
-
- 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 {
- syntheticAccessor =
- ((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;
- this.resolvedType = type.resolveType(scope);
- // will check for null after args are resolved
-
- // buffering the arguments' types
- TypeBinding[] argumentTypes = NoParameters;
- if (arguments != null) {
- boolean argHasError = false;
- int length = arguments.length;
- argumentTypes = new TypeBinding[length];
- for (int i = 0; i < length; i++)
- if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
- argHasError = true;
- if (argHasError)
- return this.resolvedType;
- }
- if (this.resolvedType == null)
- return null;
-
- if (!this.resolvedType.canBeInstantiated()) {
- scope.problemReporter().cannotInstantiate(type, this.resolvedType);
- return this.resolvedType;
- }
- 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 this.resolvedType;
- }
- if (isMethodUseDeprecated(binding, scope))
- scope.problemReporter().deprecatedMethod(binding, this);
-
- if (arguments != null)
- for (int i = 0; i < arguments.length; i++)
- arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]);
- return allocatedType;
- }
-
- public void setActualReceiverType(ReferenceBinding receiverType) {
- // ignored
- }
-
- public void setDepth(int i) {
- // ignored
- }
-
- public void setFieldIndex(int i) {
- // ignored
- }
-
- public String toStringExpression() {
-
- String s = "new " + type.toString(0); //$NON-NLS-1$
- if (arguments == null)
- s = s + "()"; //$NON-NLS-1$
- else {
- s = s + "("; //$NON-NLS-1$
- for (int i = 0; i < arguments.length; i++) {
- s = s + arguments[i].toStringExpression();
- if (i == (arguments.length - 1))
- s = s + ")"; //$NON-NLS-1$
- else
- s = s + ", "; //$NON-NLS-1$
- }
- }
- return s;
- }
-
- public void traverse(ASTVisitor visitor, BlockScope scope) {
-
- if (visitor.visit(this, scope)) {
- int argumentsLength;
- type.traverse(visitor, scope);
- if (arguments != null) {
- argumentsLength = arguments.length;
- for (int i = 0; i < argumentsLength; i++)
- arguments[i].traverse(visitor, scope);
- }
- }
- visitor.endVisit(this, scope);
- }
-}