Refactored packagename to net.sourceforge.phpdt.internal.compiler.ast
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / AllocationExpression.java
index 3c999d0..7eb480b 100644 (file)
@@ -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
+}