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.phpdt.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;
 
  28         public static final int FUNCTION_DEFINITION = 1;
 
  30         public static final int METHOD_DEFINITION = 2;
 
  35          * MethodDeclaration constructor comment.
 
  37         public MethodDeclaration(CompilationResult compilationResult) {
 
  38                 super(compilationResult);
 
  41         public void analyseCode(ClassScope classScope,
 
  42                         InitializationFlowContext initializationContext, FlowInfo flowInfo) {
 
  44                 // starting of the code analysis for methods
 
  45                 if (ignoreFurtherInvestigation)
 
  51                         if (this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
 
  52                                 if (!classScope.referenceCompilationUnit().compilationResult
 
  54                                         scope.problemReporter().unusedPrivateMethod(this);
 
  58                         // may be in a non necessary <clinit> for innerclass with static
 
  59                         // final constant fields
 
  60                         if (binding.isAbstract()) // || binding.isNative())
 
  63                         ExceptionHandlingFlowContext methodContext = new ExceptionHandlingFlowContext(
 
  64                                         initializationContext, this, binding.thrownExceptions,
 
  65                                         scope, FlowInfo.DEAD_END);
 
  67                         // propagate to statements
 
  68                         if (statements != null) {
 
  69                                 boolean didAlreadyComplain = false;
 
  70                                 for (int i = 0, count = statements.length; i < count; i++) {
 
  72                                         if (!flowInfo.complainIfUnreachable((stat = statements[i]),
 
  73                                                         scope, didAlreadyComplain)) {
 
  74                                                 flowInfo = stat.analyseCode(scope, methodContext,
 
  77                                                 didAlreadyComplain = true;
 
  81                         // check for missing returning path
 
  82                         TypeBinding returnType = binding.returnType;
 
  83                         if ((returnType == VoidBinding) || isAbstract()) {
 
  84                                 this.needFreeReturn = flowInfo.isReachable();
 
  86                                 if (flowInfo != FlowInfo.DEAD_END) {
 
  87                                         scope.problemReporter().shouldReturn(returnType, this);
 
  90                 } catch (AbortMethod e) {
 
  91                         this.ignoreFurtherInvestigation = true;
 
  95         public void parseStatements(UnitParser parser,
 
  96                         CompilationUnitDeclaration unit) {
 
  98                 // fill up the method body with statement
 
  99                 if (ignoreFurtherInvestigation)
 
 101                 parser.parse(this, unit);
 
 104         public void resolveStatements() {
 
 106                 // ========= abort on fatal error =============
 
 107                 if (this.returnType != null && this.binding != null) {
 
 108                         this.returnType.resolvedType = this.binding.returnType;
 
 109                         // record the return type binding
 
 111                 // look if the name of the method is correct
 
 112                 if (binding != null && isTypeUseDeprecated(binding.returnType, scope))
 
 113                         scope.problemReporter().deprecatedType(binding.returnType,
 
 117                         if (CharOperation.equals(scope.enclosingSourceType().sourceName,
 
 119                                 scope.problemReporter().methodWithConstructorName(this);
 
 121                         // by grammatical construction, interface methods are always
 
 123                         if (!scope.enclosingSourceType().isInterface()) {
 
 125                                 // if a method has an semicolon body and is not declared as
 
 127                                 // native methods may have a semicolon body
 
 128                                 // if ((modifiers & AccSemicolonBody) != 0) {
 
 129                                 // if ((modifiers & AccNative) == 0)
 
 130                                 // if ((modifiers & AccAbstract) == 0)
 
 131                                 // scope.problemReporter().methodNeedingAbstractModifier(this);
 
 133                                 // // the method HAS a body --> abstract native modifiers are
 
 135                                 // if (((modifiers & AccNative) != 0) || ((modifiers &
 
 136                                 // AccAbstract) != 0))
 
 137                                 // scope.problemReporter().methodNeedingNoBody(this);
 
 141                 super.resolveStatements();
 
 144         public String returnTypeToString(int tab) {
 
 146                 if (returnType == null)
 
 147                         return ""; //$NON-NLS-1$
 
 148                 return returnType.toString(tab) + " "; //$NON-NLS-1$
 
 151         public void traverse(ASTVisitor visitor, ClassScope classScope) {
 
 153                 if (visitor.visit(this, classScope)) {
 
 154                         if (returnType != null)
 
 155                                 returnType.traverse(visitor, scope);
 
 156                         if (arguments != null) {
 
 157                                 int argumentLength = arguments.length;
 
 158                                 for (int i = 0; i < argumentLength; i++)
 
 159                                         arguments[i].traverse(visitor, scope);
 
 161                         if (thrownExceptions != null) {
 
 162                                 int thrownExceptionsLength = thrownExceptions.length;
 
 163                                 for (int i = 0; i < thrownExceptionsLength; i++)
 
 164                                         thrownExceptions[i].traverse(visitor, scope);
 
 166                         if (statements != null) {
 
 167                                 int statementsLength = statements.length;
 
 168                                 for (int i = 0; i < statementsLength; i++)
 
 169                                         statements[i].traverse(visitor, scope);
 
 172                 visitor.endVisit(this, classScope);