1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ASTVisitor; 15 import org.eclipse.jdt.internal.compiler.CompilationResult; 16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 17 import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext; 18 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 19 import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext; 20 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 21 import org.eclipse.jdt.internal.compiler.lookup.ClassScope; 22 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; 23 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 24 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 25 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 26 import org.eclipse.jdt.internal.compiler.parser.Parser; 27 import org.eclipse.jdt.internal.compiler.problem.AbortMethod; 28 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; 29 30 public class MethodDeclaration extends AbstractMethodDeclaration { 31 32 public TypeReference returnType; 33 public TypeParameter[] typeParameters; 34 35 38 public MethodDeclaration(CompilationResult compilationResult) { 39 super(compilationResult); 40 } 41 42 public void analyseCode( 43 ClassScope classScope, 44 InitializationFlowContext initializationContext, 45 FlowInfo flowInfo) { 46 47 if (ignoreFurtherInvestigation) 49 return; 50 try { 51 if (binding == null) 52 return; 53 54 if (!this.binding.isUsed() && 55 (this.binding.isPrivate() 56 || (((this.binding.modifiers & (ExtraCompilerModifiers.AccOverriding|ExtraCompilerModifiers.AccImplementing)) == 0) && this.binding.declaringClass.isLocalType()))) { 57 if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { 58 scope.problemReporter().unusedPrivateMethod(this); 59 } 60 } 61 62 if (binding.declaringClass.isEnum() && (this.selector == TypeConstants.VALUES || this.selector == TypeConstants.VALUEOF)) 64 return; 65 66 if (binding.isAbstract() || binding.isNative()) 68 return; 69 70 ExceptionHandlingFlowContext methodContext = 71 new ExceptionHandlingFlowContext( 72 initializationContext, 73 this, 74 binding.thrownExceptions, 75 scope, 76 FlowInfo.DEAD_END); 77 78 if (this.arguments != null) { 80 for (int i = 0, count = this.arguments.length; i < count; i++) { 81 flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); 82 } 83 } 84 if (statements != null) { 86 boolean didAlreadyComplain = false; 87 for (int i = 0, count = statements.length; i < count; i++) { 88 Statement stat = statements[i]; 89 if (!stat.complainIfUnreachable(flowInfo, scope, didAlreadyComplain)) { 90 flowInfo = stat.analyseCode(scope, methodContext, flowInfo); 91 } else { 92 didAlreadyComplain = true; 93 } 94 } 95 } 96 TypeBinding returnTypeBinding = binding.returnType; 98 if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) { 99 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 100 this.bits |= ASTNode.NeedFreeReturn; 101 } 102 } else { 103 if (flowInfo != FlowInfo.DEAD_END) { 104 scope.problemReporter().shouldReturn(returnTypeBinding, this); 105 } 106 } 107 methodContext.complainIfUnusedExceptionHandlers(this); 109 } catch (AbortMethod e) { 110 this.ignoreFurtherInvestigation = true; 111 } 112 } 113 114 public boolean isMethod() { 115 116 return true; 117 } 118 119 public void parseStatements(Parser parser, CompilationUnitDeclaration unit) { 120 121 if (ignoreFurtherInvestigation) 123 return; 124 parser.parse(this, unit); 125 } 126 127 public StringBuffer printReturnType(int indent, StringBuffer output) { 128 129 if (returnType == null) return output; 130 return returnType.printExpression(0, output).append(' '); 131 } 132 133 public void resolveStatements() { 134 135 if (this.returnType != null && this.binding != null) { 137 this.returnType.resolvedType = this.binding.returnType; 138 } 140 if (CharOperation.equals(this.scope.enclosingSourceType().sourceName, selector)) { 142 this.scope.problemReporter().methodWithConstructorName(this); 143 } 144 145 if (this.typeParameters != null) { 146 for (int i = 0, length = this.typeParameters.length; i < length; i++) { 147 this.typeParameters[i].resolve(this.scope); 148 } 149 } 150 151 final CompilerOptions compilerOptions = this.scope.compilerOptions(); 153 checkOverride: { 154 if (this.binding == null) break checkOverride; 155 long sourceLevel = compilerOptions.sourceLevel; 156 if (sourceLevel < ClassFileConstants.JDK1_5) break checkOverride; 157 int bindingModifiers = this.binding.modifiers; 158 boolean hasOverrideAnnotation = (this.binding.tagBits & TagBits.AnnotationOverride) != 0; 159 boolean isInterfaceMethod = this.binding.declaringClass.isInterface(); 160 if (hasOverrideAnnotation) { 161 if (!isInterfaceMethod && (bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccOverriding)) == ExtraCompilerModifiers.AccOverriding) 163 break checkOverride; 164 if (sourceLevel >= ClassFileConstants.JDK1_6 167 && ((bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccImplementing)) == ExtraCompilerModifiers.AccImplementing)) 168 break checkOverride; 169 this.scope.problemReporter().methodMustOverride(this); 171 } else if (!isInterfaceMethod 172 && (bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccOverriding)) == ExtraCompilerModifiers.AccOverriding) { 173 this.scope.problemReporter().missingOverrideAnnotation(this); 175 } 176 } 177 178 switch (TypeDeclaration.kind(this.scope.referenceType().modifiers)) { 180 case TypeDeclaration.ENUM_DECL : 181 if (this.selector == TypeConstants.VALUES) break; 182 if (this.selector == TypeConstants.VALUEOF) break; 183 case TypeDeclaration.CLASS_DECL : 184 if ((this.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) { 187 if ((this.modifiers & ClassFileConstants.AccNative) == 0) 188 if ((this.modifiers & ClassFileConstants.AccAbstract) == 0) 189 this.scope.problemReporter().methodNeedBody(this); 190 } else { 191 if (((this.modifiers & ClassFileConstants.AccNative) != 0) || ((this.modifiers & ClassFileConstants.AccAbstract) != 0)) 193 this.scope.problemReporter().methodNeedingNoBody(this); 194 } 195 } 196 super.resolveStatements(); 197 198 if (compilerOptions.getSeverity(CompilerOptions.OverridingMethodWithoutSuperInvocation) != ProblemSeverities.Ignore) { 200 if (this.binding != null) { 201 int bindingModifiers = this.binding.modifiers; 202 if ((bindingModifiers & (ExtraCompilerModifiers.AccOverriding|ExtraCompilerModifiers.AccImplementing)) == ExtraCompilerModifiers.AccOverriding 203 && (this.bits & ASTNode.OverridingMethodWithSupercall) == 0) { 204 this.scope.problemReporter().overridesMethodWithoutSuperInvocation(this.binding); 205 } 206 } 207 } 208 } 209 210 public void traverse( 211 ASTVisitor visitor, 212 ClassScope classScope) { 213 214 if (visitor.visit(this, classScope)) { 215 if (this.javadoc != null) { 216 this.javadoc.traverse(visitor, scope); 217 } 218 if (this.annotations != null) { 219 int annotationsLength = this.annotations.length; 220 for (int i = 0; i < annotationsLength; i++) 221 this.annotations[i].traverse(visitor, scope); 222 } 223 if (this.typeParameters != null) { 224 int typeParametersLength = this.typeParameters.length; 225 for (int i = 0; i < typeParametersLength; i++) { 226 this.typeParameters[i].traverse(visitor, scope); 227 } 228 } 229 if (returnType != null) 230 returnType.traverse(visitor, scope); 231 if (arguments != null) { 232 int argumentLength = arguments.length; 233 for (int i = 0; i < argumentLength; i++) 234 arguments[i].traverse(visitor, scope); 235 } 236 if (thrownExceptions != null) { 237 int thrownExceptionsLength = thrownExceptions.length; 238 for (int i = 0; i < thrownExceptionsLength; i++) 239 thrownExceptions[i].traverse(visitor, scope); 240 } 241 if (statements != null) { 242 int statementsLength = statements.length; 243 for (int i = 0; i < statementsLength; i++) 244 statements[i].traverse(visitor, scope); 245 } 246 } 247 visitor.endVisit(this, classScope); 248 } 249 public TypeParameter[] typeParameters() { 250 return this.typeParameters; 251 } 252 } 253 | Popular Tags |