1 /*******************************************************************************
 
   2  * Copyright (c) 2000, 2003 IBM Corporation and others.
 
   3  * All rights reserved. This program and the accompanying materials 
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
   9  *     IBM Corporation - initial API and implementation
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpeclipse.internal.compiler.ast;
 
  13 import net.sourceforge.phpdt.core.compiler.CharOperation;
 
  14 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
 
  15 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
 
  16 import net.sourceforge.phpdt.internal.compiler.flow.ExceptionHandlingFlowContext;
 
  17 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
 
  18 import net.sourceforge.phpdt.internal.compiler.flow.InitializationFlowContext;
 
  19 import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope;
 
  20 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
 
  21 import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
 
  22 import net.sourceforge.phpdt.internal.compiler.problem.AbortMethod;
 
  24 public class MethodDeclaration extends AbstractMethodDeclaration {
 
  26   public TypeReference returnType;
 
  27   public static final int FUNCTION_DEFINITION = 1;
 
  28   public static final int METHOD_DEFINITION = 2;
 
  32    * MethodDeclaration constructor comment.
 
  34   public MethodDeclaration(CompilationResult compilationResult) {
 
  35     super(compilationResult);
 
  38   public void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo flowInfo) {
 
  40     // starting of the code analysis for methods
 
  41     if (ignoreFurtherInvestigation)
 
  47       if (this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
 
  48         if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
 
  49           scope.problemReporter().unusedPrivateMethod(this);
 
  53       // may be in a non necessary <clinit> for innerclass with static final constant fields
 
  54       if (binding.isAbstract()) // || binding.isNative())
 
  57       ExceptionHandlingFlowContext methodContext =
 
  58         new ExceptionHandlingFlowContext(initializationContext, this, binding.thrownExceptions, scope, FlowInfo.DEAD_END);
 
  60       // propagate to statements
 
  61       if (statements != null) {
 
  62         boolean didAlreadyComplain = false;
 
  63         for (int i = 0, count = statements.length; i < count; i++) {
 
  65           if (!flowInfo.complainIfUnreachable((stat = statements[i]), scope, didAlreadyComplain)) {
 
  66             flowInfo = stat.analyseCode(scope, methodContext, flowInfo);
 
  68             didAlreadyComplain = true;
 
  72       // check for missing returning path
 
  73       TypeBinding returnType = binding.returnType;
 
  74       if ((returnType == VoidBinding) || isAbstract()) {
 
  75         this.needFreeReturn = flowInfo.isReachable();
 
  77         if (flowInfo != FlowInfo.DEAD_END) {
 
  78           scope.problemReporter().shouldReturn(returnType, this);
 
  81     } catch (AbortMethod e) {
 
  82       this.ignoreFurtherInvestigation = true;
 
  86   public void parseStatements(UnitParser parser, CompilationUnitDeclaration unit) {
 
  88     //fill up the method body with statement
 
  89     if (ignoreFurtherInvestigation)
 
  91     parser.parse(this, unit);
 
  94   public void resolveStatements() {
 
  96     // ========= abort on fatal error =============
 
  97     if (this.returnType != null && this.binding != null) {
 
  98       this.returnType.resolvedType = this.binding.returnType;
 
  99       // record the return type binding
 
 101     // look if the name of the method is correct
 
 102     if (binding != null && isTypeUseDeprecated(binding.returnType, scope))
 
 103       scope.problemReporter().deprecatedType(binding.returnType, returnType);
 
 106       if (CharOperation.equals(scope.enclosingSourceType().sourceName, selector))
 
 107         scope.problemReporter().methodWithConstructorName(this);
 
 109       // by grammatical construction, interface methods are always abstract
 
 110       if (!scope.enclosingSourceType().isInterface()) {
 
 112         // if a method has an semicolon body and is not declared as abstract==>error
 
 113         // native methods may have a semicolon body 
 
 114         //                      if ((modifiers & AccSemicolonBody) != 0) {
 
 115         //                              if ((modifiers & AccNative) == 0)
 
 116         //                                      if ((modifiers & AccAbstract) == 0)
 
 117         //                                              scope.problemReporter().methodNeedingAbstractModifier(this);
 
 119         //                              // the method HAS a body --> abstract native modifiers are forbiden
 
 120         //                              if (((modifiers & AccNative) != 0) || ((modifiers & AccAbstract) != 0))
 
 121         //                                      scope.problemReporter().methodNeedingNoBody(this);
 
 125     super.resolveStatements();
 
 128   public String returnTypeToString(int tab) {
 
 130     if (returnType == null)
 
 131       return ""; //$NON-NLS-1$
 
 132     return returnType.toString(tab) + " "; //$NON-NLS-1$
 
 135   public void traverse(ASTVisitor visitor, ClassScope classScope) {
 
 137     if (visitor.visit(this, classScope)) {
 
 138       if (returnType != null)
 
 139         returnType.traverse(visitor, scope);
 
 140       if (arguments != null) {
 
 141         int argumentLength = arguments.length;
 
 142         for (int i = 0; i < argumentLength; i++)
 
 143           arguments[i].traverse(visitor, scope);
 
 145       if (thrownExceptions != null) {
 
 146         int thrownExceptionsLength = thrownExceptions.length;
 
 147         for (int i = 0; i < thrownExceptionsLength; i++)
 
 148           thrownExceptions[i].traverse(visitor, scope);
 
 150       if (statements != null) {
 
 151         int statementsLength = statements.length;
 
 152         for (int i = 0; i < statementsLength; i++)
 
 153           statements[i].traverse(visitor, scope);
 
 156     visitor.endVisit(this, classScope);