improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / MethodScope.java
index 7ec902b..e246740 100644 (file)
@@ -1,24 +1,26 @@
 /*******************************************************************************
- * 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.lookup;
 
-import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference;
-import net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference;
-import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
+import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
+
 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
 import net.sourceforge.phpdt.internal.compiler.flow.UnconditionalFlowInfo;
 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
+import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedNameReference;
+import net.sourceforge.phpeclipse.internal.compiler.ast.SingleNameReference;
+import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
 
 /**
  * Particular block scope used for methods, constructors or clinits, representing
@@ -28,17 +30,16 @@ import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 public class MethodScope extends BlockScope {
 
        public ReferenceContext referenceContext;
-       public boolean needToCompactLocalVariables;
        public boolean isStatic; // method modifier or initializer one
 
-       //fields used in the TC process (no real meaning)
+       //fields used during name resolution
        public static final int NotInFieldDecl = -1; //must be a negative value 
-       public boolean isConstructorCall = false; //modified on the fly by the TC
-       public int fieldDeclarationIndex = NotInFieldDecl;
-       //modified on the fly by the TC
+       public boolean isConstructorCall = false; 
+       public FieldBinding initializedField; // the field being initialized
+       public int fieldDeclarationIndex = NotInFieldDecl; 
 
+       // flow analysis
        public int analysisIndex; // for setting flow-analysis id
-
        public boolean isPropagatingInnerClassEmulation;
 
        // for local variables table attributes
@@ -46,10 +47,10 @@ public class MethodScope extends BlockScope {
        public long[] definiteInits = new long[4];
        public long[][] extraDefiniteInits = new long[4][];
 
-       public MethodScope(
-               ClassScope parent,
-               ReferenceContext context,
-               boolean isStatic) {
+       // inner-emulation
+       public SyntheticArgumentBinding[] extraSyntheticArguments;
+       
+       public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) {
 
                super(METHOD_SCOPE, parent);
                locals = new LocalVariableBinding[5];
@@ -80,17 +81,17 @@ public class MethodScope extends BlockScope {
 
                // check for abnormal modifiers
                int unexpectedModifiers =
-                       ~(AccPublic | AccPrivate | AccProtected | AccStrictfp);
+                       ~(AccPublic | AccPrivate | AccProtected);// | AccStrictfp);
                if ((realModifiers & unexpectedModifiers) != 0)
                        problemReporter().illegalModifierForMethod(
                                methodBinding.declaringClass,
                                (AbstractMethodDeclaration) referenceContext);
-               else if (
-                       (((AbstractMethodDeclaration) referenceContext).modifiers & AccStrictfp) != 0)
-                       // must check the parse node explicitly
-                       problemReporter().illegalModifierForMethod(
-                               methodBinding.declaringClass,
-                               (AbstractMethodDeclaration) referenceContext);
+//             else if (
+//                     (((AbstractMethodDeclaration) referenceContext).modifiers & AccStrictfp) != 0)
+//                     // must check the parse node explicitly
+//                     problemReporter().illegalModifierForMethod(
+//                             methodBinding.declaringClass,
+//                             (AbstractMethodDeclaration) referenceContext);
 
                // check for incompatible modifiers in the visibility bits, isolate the visibility bits
                int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate);
@@ -149,10 +150,10 @@ public class MethodScope extends BlockScope {
                                        | AccProtected
                                        | AccAbstract
                                        | AccStatic
-                                       | AccFinal
-                                       | AccSynchronized
-                                       | AccNative
-                                       | AccStrictfp);
+                                       | AccFinal);
+//                                     | AccSynchronized
+//                                     | AccNative
+//                                     | AccStrictfp);
                if ((realModifiers & unexpectedModifiers) != 0)
                        problemReporter().illegalModifierForMethod(
                                methodBinding.declaringClass,
@@ -180,7 +181,7 @@ public class MethodScope extends BlockScope {
                // check for modifiers incompatible with abstract modifier
                if ((modifiers & AccAbstract) != 0) {
                        int incompatibleWithAbstract =
-                               AccPrivate | AccStatic | AccFinal | AccSynchronized | AccNative | AccStrictfp;
+                               AccPrivate | AccStatic | AccFinal;// | AccSynchronized | AccNative | AccStrictfp;
                        if ((modifiers & incompatibleWithAbstract) != 0)
                                problemReporter().illegalAbstractModifierCombinationForMethod(
                                        methodBinding.declaringClass,
@@ -197,10 +198,10 @@ public class MethodScope extends BlockScope {
                        modifiers |= AccFinal;
                */
                // native methods cannot also be tagged as strictfp
-               if ((modifiers & AccNative) != 0 && (modifiers & AccStrictfp) != 0)
-                       problemReporter().nativeMethodsCannotBeStrictfp(
-                               methodBinding.declaringClass,
-                               (AbstractMethodDeclaration) referenceContext);
+//             if ((modifiers & AccNative) != 0 && (modifiers & AccStrictfp) != 0)
+//                     problemReporter().nativeMethodsCannotBeStrictfp(
+//                             methodBinding.declaringClass,
+//                             (AbstractMethodDeclaration) referenceContext);
 
                // static members are only authorized in a static member or top level type
                if (((realModifiers & AccStatic) != 0)
@@ -213,6 +214,78 @@ public class MethodScope extends BlockScope {
                methodBinding.modifiers = modifiers;
        }
        
+       /* Compute variable positions in scopes given an initial position offset
+        * ignoring unused local variables.
+        * 
+        * Deal with arguments here, locals and subscopes are processed in BlockScope method
+        */
+//     public void computeLocalVariablePositions(int initOffset, CodeStream codeStream) {
+//
+//             boolean isReportingUnusedArgument = false;
+//
+//             if (referenceContext instanceof AbstractMethodDeclaration) {
+//                     AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration)referenceContext;
+//                     MethodBinding method = methodDecl.binding;
+//                     CompilerOptions options = compilationUnitScope().environment.options;
+//                     if (!(method.isAbstract()
+//                                     || (method.isImplementing() && !options.reportUnusedParameterWhenImplementingAbstract) 
+//                                     || (method.isOverriding() && !method.isImplementing() && !options.reportUnusedParameterWhenOverridingConcrete)
+//                                     || method.isMain())) {
+//                             isReportingUnusedArgument = true;
+//                     }
+//             }
+//             this.offset = initOffset;
+//             this.maxOffset = initOffset;
+//
+//             // manage arguments     
+//             int ilocal = 0, maxLocals = this.localIndex;    
+//             while (ilocal < maxLocals) {
+//                     LocalVariableBinding local = locals[ilocal];
+//                     if (local == null || !local.isArgument) break; // done with arguments
+//
+//                     // do not report fake used variable
+//                     if (isReportingUnusedArgument
+//                                     && local.useFlag == LocalVariableBinding.UNUSED
+//                                     && ((local.declaration.bits & ASTNode.IsLocalDeclarationReachableMASK) != 0)) { // declaration is reachable
+//                             this.problemReporter().unusedArgument(local.declaration);
+//                     }
+//
+//                     // record user-defined argument for attribute generation
+//                     codeStream.record(local); 
+//
+//                     // assign variable position
+//                     local.resolvedPosition = this.offset;
+//
+//                     if ((local.type == LongBinding) || (local.type == DoubleBinding)) {
+//                             this.offset += 2;
+//                     } else {
+//                             this.offset++;
+//                     }
+//                     // check for too many arguments/local variables
+//                     if (this.offset > 0xFF) { // no more than 255 words of arguments
+//                             this.problemReporter().noMoreAvailableSpaceForArgument(local, local.declaration);
+//                     }
+//                     ilocal++;
+//             }
+//             
+//             // sneak in extra argument before other local variables
+//             if (extraSyntheticArguments != null) {
+//                     for (int iarg = 0, maxArguments = extraSyntheticArguments.length; iarg < maxArguments; iarg++){
+//                             SyntheticArgumentBinding argument = extraSyntheticArguments[iarg];
+//                             argument.resolvedPosition = this.offset;
+//                             if ((argument.type == LongBinding) || (argument.type == DoubleBinding)){
+//                                     this.offset += 2;
+//                             } else {
+//                                     this.offset++;
+//                             }
+//                             if (this.offset > 0xFF) { // no more than 255 words of arguments
+//                                     this.problemReporter().noMoreAvailableSpaceForArgument(argument, (ASTNode)this.referenceContext); 
+//                             }
+//                     }
+//             }
+//             this.computeLocalVariablePositions(ilocal, this.offset, codeStream);
+//     }
+
        /* Error management:
         *              keep null for all the errors that prevent the method to be created
         *              otherwise return a correct method binding (but without the element
@@ -315,9 +388,8 @@ public class MethodScope extends BlockScope {
 
        public final int recordInitializationStates(FlowInfo flowInfo) {
 
-               if ((flowInfo == FlowInfo.DeadEnd) || (flowInfo.isFakeReachable())) {
-                       return -1;
-               }
+               if (!flowInfo.isReachable()) return -1;
+
                UnconditionalFlowInfo unconditionalFlowInfo = flowInfo.unconditionalInits();
                long[] extraInits = unconditionalFlowInfo.extraDefiniteInits;
                long inits = unconditionalFlowInfo.definiteInits;
@@ -373,7 +445,7 @@ public class MethodScope extends BlockScope {
 
        /* Answer the reference type of this scope.
        *
-       * i.e. the nearest enclosing type of this scope.
+       * It is the nearest enclosing type of this scope.
        */
        public TypeDeclaration referenceType() {
 
@@ -393,8 +465,10 @@ public class MethodScope extends BlockScope {
                        s += newLine + "\t" + locals[i].toString(); //$NON-NLS-1$
                s += newLine + "startIndex = " + startIndex; //$NON-NLS-1$
                s += newLine + "isConstructorCall = " + isConstructorCall; //$NON-NLS-1$
+               s += newLine + "initializedField = " + initializedField; //$NON-NLS-1$
                s += newLine + "fieldDeclarationIndex = " + fieldDeclarationIndex; //$NON-NLS-1$
+               s += newLine + "referenceContext = " + referenceContext; //$NON-NLS-1$
                return s;
        }
 
-}
\ No newline at end of file
+}