Refactored packagename to net.sourceforge.phpdt.internal.compiler.ast
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / Clinit.java
index 3c4fe7b..bbd37e2 100644 (file)
@@ -1,22 +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.ast;
 
+import net.sourceforge.phpdt.internal.compiler.CompilationResult;
 import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import net.sourceforge.phpdt.internal.compiler.*;
-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.parser.*;
-import net.sourceforge.phpdt.internal.compiler.problem.*;
+import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext;
+import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
+import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext;
+import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding;
+import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
+import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod;
 
 public class Clinit extends AbstractMethodDeclaration {
        
@@ -45,11 +49,10 @@ public class Clinit extends AbstractMethodDeclaration {
                                        this,
                                        NoExceptions,
                                        scope,
-                                       FlowInfo.DeadEnd);
+                                       FlowInfo.DEAD_END);
 
                        // check for missing returning path
-                       needFreeReturn =
-                               !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable());
+                       this.needFreeReturn = flowInfo.isReachable();
 
                        // check missing blank final field initializations
                        flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn);
@@ -78,126 +81,124 @@ public class Clinit extends AbstractMethodDeclaration {
        /**
         * Bytecode generation for a <clinit> method
         *
-        * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
-        * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+        * @param classScope net.sourceforge.phpdt.internal.compiler.lookup.ClassScope
+        * @param classFile net.sourceforge.phpdt.internal.compiler.codegen.ClassFile
         */
-       public void generateCode(ClassScope classScope, ClassFile classFile) {
-
-               int clinitOffset = 0;
-               if (ignoreFurtherInvestigation) {
-                       // should never have to add any <clinit> problem method
-                       return;
-               }
-               try {
-                       clinitOffset = classFile.contentsOffset;
-                       this.generateCode(classScope, classFile, clinitOffset);
-               } catch (AbortMethod e) {
-                       // should never occur
-                       // the clinit referenceContext is the type declaration
-                       // All clinit problems will be reported against the type: AbortType instead of AbortMethod
-                       // reset the contentsOffset to the value before generating the clinit code
-                       // decrement the number of method info as well.
-                       // This is done in the addProblemMethod and addProblemConstructor for other
-                       // cases.
-                       if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
-                               // a branch target required a goto_w, restart code gen in wide mode.
-                               try {
-                                       if (statements != null) {
-                                               for (int i = 0, max = statements.length; i < max; i++)
-                                                       statements[i].resetStateForCodeGeneration();
-                                       }
-                                       classFile.contentsOffset = clinitOffset;
-                                       classFile.methodCount--;
-                                       classFile.codeStream.wideMode = true; // request wide mode 
-                                       this.generateCode(classScope, classFile, clinitOffset);
-                                       // restart method generation
-                               } catch (AbortMethod e2) {
-                                       classFile.contentsOffset = clinitOffset;
-                                       classFile.methodCount--;
-                               }
-                       } else {
-                               // produce a problem method accounting for this fatal error
-                               classFile.contentsOffset = clinitOffset;
-                               classFile.methodCount--;
-                       }
-               }
-       }
+//     public void generateCode(ClassScope classScope, ClassFile classFile) {
+//
+//             int clinitOffset = 0;
+//             if (ignoreFurtherInvestigation) {
+//                     // should never have to add any <clinit> problem method
+//                     return;
+//             }
+//             try {
+//                     clinitOffset = classFile.contentsOffset;
+//                     this.generateCode(classScope, classFile, clinitOffset);
+//             } catch (AbortMethod e) {
+//                     // should never occur
+//                     // the clinit referenceContext is the type declaration
+//                     // All clinit problems will be reported against the type: AbortType instead of AbortMethod
+//                     // reset the contentsOffset to the value before generating the clinit code
+//                     // decrement the number of method info as well.
+//                     // This is done in the addProblemMethod and addProblemConstructor for other
+//                     // cases.
+//                     if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
+//                             // a branch target required a goto_w, restart code gen in wide mode.
+//                             try {
+//                                     if (statements != null) {
+//                                             for (int i = 0, max = statements.length; i < max; i++)
+//                                                     statements[i].resetStateForCodeGeneration();
+//                                     }
+//                                     classFile.contentsOffset = clinitOffset;
+//                                     classFile.methodCount--;
+//                                     classFile.codeStream.wideMode = true; // request wide mode 
+//                                     this.generateCode(classScope, classFile, clinitOffset);
+//                                     // restart method generation
+//                             } catch (AbortMethod e2) {
+//                                     classFile.contentsOffset = clinitOffset;
+//                                     classFile.methodCount--;
+//                             }
+//                     } else {
+//                             // produce a problem method accounting for this fatal error
+//                             classFile.contentsOffset = clinitOffset;
+//                             classFile.methodCount--;
+//                     }
+//             }
+//     }
 
        /**
         * Bytecode generation for a <clinit> method
         *
-        * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
-        * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+        * @param classScope net.sourceforge.phpdt.internal.compiler.lookup.ClassScope
+        * @param classFile net.sourceforge.phpdt.internal.compiler.codegen.ClassFile
         */
-       private void generateCode(
-               ClassScope classScope,
-               ClassFile classFile,
-               int clinitOffset) {
-
-               ConstantPool constantPool = classFile.constantPool;
-               int constantPoolOffset = constantPool.currentOffset;
-               int constantPoolIndex = constantPool.currentIndex;
-               classFile.generateMethodInfoHeaderForClinit();
-               int codeAttributeOffset = classFile.contentsOffset;
-               classFile.generateCodeAttributeHeader();
-               CodeStream codeStream = classFile.codeStream;
-               this.resolve(classScope);
-
-               codeStream.reset(this, classFile);
-               TypeDeclaration declaringType = classScope.referenceContext;
-
-               // initialize local positions - including initializer scope.
-               scope.computeLocalVariablePositions(0, codeStream); // should not be necessary
-               MethodScope staticInitializerScope = declaringType.staticInitializerScope;
-               staticInitializerScope.computeLocalVariablePositions(0, codeStream);
-               // offset by the argument size
-
-               // 1.4 feature
-               // This has to be done before any other initialization
-               if (this.assertionSyntheticFieldBinding != null) {
-                       // generate code related to the activation of assertion for this class
-                       codeStream.generateClassLiteralAccessForType(
-                               classScope.enclosingSourceType(),
-                               classLiteralSyntheticField);
-                       codeStream.invokeJavaLangClassDesiredAssertionStatus();
-                       Label falseLabel = new Label(codeStream);
-                       codeStream.ifne(falseLabel);
-                       codeStream.iconst_1();
-                       Label jumpLabel = new Label(codeStream);
-                       codeStream.goto_(jumpLabel);
-                       falseLabel.place();
-                       codeStream.iconst_0();
-                       jumpLabel.place();
-                       codeStream.putstatic(this.assertionSyntheticFieldBinding);
-               }
-               // generate initializers
-               if (declaringType.fields != null) {
-                       for (int i = 0, max = declaringType.fields.length; i < max; i++) {
-                               FieldDeclaration fieldDecl;
-                               if ((fieldDecl = declaringType.fields[i]).isStatic()) {
-                                       fieldDecl.generateCode(staticInitializerScope, codeStream);
-                               }
-                       }
-               }
-               if (codeStream.position == 0) {
-                       // do not need to output a Clinit if no bytecodes
-                       // so we reset the offset inside the byte array contents.
-                       classFile.contentsOffset = clinitOffset;
-                       // like we don't addd a method we need to undo the increment on the method count
-                       classFile.methodCount--;
-                       // reset the constant pool to its state before the clinit
-                       constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
-               } else {
-                       if (needFreeReturn) {
-                               int oldPosition = codeStream.position;
-                               codeStream.return_();
-                               codeStream.updateLocalVariablesAttribute(oldPosition);
-                       }
-                       // Record the end of the clinit: point to the declaration of the class
-                       codeStream.recordPositionsFrom(0, declaringType.sourceStart);
-                       classFile.completeCodeAttributeForClinit(codeAttributeOffset);
-               }
-       }
+//     private void generateCode(
+//             ClassScope classScope,
+//             ClassFile classFile,
+//             int clinitOffset) {
+//
+//             ConstantPool constantPool = classFile.constantPool;
+//             int constantPoolOffset = constantPool.currentOffset;
+//             int constantPoolIndex = constantPool.currentIndex;
+//             classFile.generateMethodInfoHeaderForClinit();
+//             int codeAttributeOffset = classFile.contentsOffset;
+//             classFile.generateCodeAttributeHeader();
+//             CodeStream codeStream = classFile.codeStream;
+//             this.resolve(classScope);
+//
+//             codeStream.reset(this, classFile);
+//             TypeDeclaration declaringType = classScope.referenceContext;
+//
+//             // initialize local positions - including initializer scope.
+//             MethodScope staticInitializerScope = declaringType.staticInitializerScope;
+//             staticInitializerScope.computeLocalVariablePositions(0, codeStream);
+//
+//             // 1.4 feature
+//             // This has to be done before any other initialization
+//             if (this.assertionSyntheticFieldBinding != null) {
+//                     // generate code related to the activation of assertion for this class
+//                     codeStream.generateClassLiteralAccessForType(
+//                             classScope.enclosingSourceType(),
+//                             classLiteralSyntheticField);
+//                     codeStream.invokeJavaLangClassDesiredAssertionStatus();
+//                     Label falseLabel = new Label(codeStream);
+//                     codeStream.ifne(falseLabel);
+//                     codeStream.iconst_1();
+//                     Label jumpLabel = new Label(codeStream);
+//                     codeStream.goto_(jumpLabel);
+//                     falseLabel.place();
+//                     codeStream.iconst_0();
+//                     jumpLabel.place();
+//                     codeStream.putstatic(this.assertionSyntheticFieldBinding);
+//             }
+//             // generate initializers
+//             if (declaringType.fields != null) {
+//                     for (int i = 0, max = declaringType.fields.length; i < max; i++) {
+//                             FieldDeclaration fieldDecl;
+//                             if ((fieldDecl = declaringType.fields[i]).isStatic()) {
+//                                     fieldDecl.generateCode(staticInitializerScope, codeStream);
+//                             }
+//                     }
+//             }
+//             if (codeStream.position == 0) {
+//                     // do not need to output a Clinit if no bytecodes
+//                     // so we reset the offset inside the byte array contents.
+//                     classFile.contentsOffset = clinitOffset;
+//                     // like we don't addd a method we need to undo the increment on the method count
+//                     classFile.methodCount--;
+//                     // reset the constant pool to its state before the clinit
+//                     constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
+//             } else {
+//                     if (this.needFreeReturn) {
+//                             int oldPosition = codeStream.position;
+//                             codeStream.return_();
+//                             codeStream.updateLocalVariablesAttribute(oldPosition);
+//                     }
+//                     // Record the end of the clinit: point to the declaration of the class
+//                     codeStream.recordPositionsFrom(0, declaringType.sourceStart);
+//                     classFile.completeCodeAttributeForClinit(codeAttributeOffset);
+//             }
+//     }
 
        public boolean isClinit() {
 
@@ -214,10 +215,15 @@ public class Clinit extends AbstractMethodDeclaration {
                return true;
        }
 
-       public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+       public void parseStatements(UnitParser parser, CompilationUnitDeclaration unit) {
                //the clinit is filled by hand .... 
        }
+       public StringBuffer print(int tab, StringBuffer output) {
 
+               printIndent(tab, output).append("<clinit>()"); //$NON-NLS-1$
+               printBody(tab + 1, output);
+               return output;
+       }
        public void resolve(ClassScope scope) {
 
                this.scope = new MethodScope(scope, scope.referenceContext, true);
@@ -252,4 +258,4 @@ public class Clinit extends AbstractMethodDeclaration {
                        sourceType.addSyntheticField(sourceType, scope);
        }
 
-}
\ No newline at end of file
+}