|
Lines 45-78
Link Here
|
| 45 |
FlowInfo flowInfo) { |
45 |
FlowInfo flowInfo) { |
| 46 |
|
46 |
|
| 47 |
// starting of the code analysis for methods |
47 |
// starting of the code analysis for methods |
| 48 |
if (ignoreFurtherInvestigation) |
48 |
if (this.ignoreFurtherInvestigation) |
| 49 |
return; |
49 |
return; |
| 50 |
try { |
50 |
try { |
| 51 |
if (binding == null) |
51 |
if (this.binding == null) |
| 52 |
return; |
52 |
return; |
| 53 |
|
53 |
|
| 54 |
if (!this.binding.isUsed() && |
54 |
if (!this.binding.isUsed() && |
| 55 |
(this.binding.isPrivate() |
55 |
(this.binding.isPrivate() |
| 56 |
|| (((this.binding.modifiers & (ExtraCompilerModifiers.AccOverriding|ExtraCompilerModifiers.AccImplementing)) == 0) && this.binding.declaringClass.isLocalType()))) { |
56 |
|| (((this.binding.modifiers & (ExtraCompilerModifiers.AccOverriding|ExtraCompilerModifiers.AccImplementing)) == 0) && this.binding.declaringClass.isLocalType()))) { |
| 57 |
if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { |
57 |
if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { |
| 58 |
scope.problemReporter().unusedPrivateMethod(this); |
58 |
this.scope.problemReporter().unusedPrivateMethod(this); |
| 59 |
} |
59 |
} |
| 60 |
} |
60 |
} |
| 61 |
|
61 |
|
| 62 |
// skip enum implicit methods |
62 |
// skip enum implicit methods |
| 63 |
if (binding.declaringClass.isEnum() && (this.selector == TypeConstants.VALUES || this.selector == TypeConstants.VALUEOF)) |
63 |
if (this.binding.declaringClass.isEnum() && (this.selector == TypeConstants.VALUES || this.selector == TypeConstants.VALUEOF)) |
| 64 |
return; |
64 |
return; |
| 65 |
|
65 |
|
| 66 |
// may be in a non necessary <clinit> for innerclass with static final constant fields |
66 |
// may be in a non necessary <clinit> for innerclass with static final constant fields |
| 67 |
if (binding.isAbstract() || binding.isNative()) |
67 |
if (this.binding.isAbstract() || this.binding.isNative()) |
| 68 |
return; |
68 |
return; |
| 69 |
|
69 |
|
| 70 |
ExceptionHandlingFlowContext methodContext = |
70 |
ExceptionHandlingFlowContext methodContext = |
| 71 |
new ExceptionHandlingFlowContext( |
71 |
new ExceptionHandlingFlowContext( |
| 72 |
initializationContext, |
72 |
initializationContext, |
| 73 |
this, |
73 |
this, |
| 74 |
binding.thrownExceptions, |
74 |
this.binding.thrownExceptions, |
| 75 |
scope, |
75 |
this.scope, |
| 76 |
FlowInfo.DEAD_END); |
76 |
FlowInfo.DEAD_END); |
| 77 |
|
77 |
|
| 78 |
// tag parameters as being set |
78 |
// tag parameters as being set |
|
Lines 82-146
Link Here
|
| 82 |
} |
82 |
} |
| 83 |
} |
83 |
} |
| 84 |
// propagate to statements |
84 |
// propagate to statements |
| 85 |
if (statements != null) { |
85 |
if (this.statements != null) { |
| 86 |
boolean didAlreadyComplain = false; |
86 |
boolean didAlreadyComplain = false; |
| 87 |
for (int i = 0, count = statements.length; i < count; i++) { |
87 |
for (int i = 0, count = this.statements.length; i < count; i++) { |
| 88 |
Statement stat = statements[i]; |
88 |
Statement stat = this.statements[i]; |
| 89 |
if (!stat.complainIfUnreachable(flowInfo, scope, didAlreadyComplain)) { |
89 |
if (!stat.complainIfUnreachable(flowInfo, this.scope, didAlreadyComplain)) { |
| 90 |
flowInfo = stat.analyseCode(scope, methodContext, flowInfo); |
90 |
flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo); |
| 91 |
} else { |
91 |
} else { |
| 92 |
didAlreadyComplain = true; |
92 |
didAlreadyComplain = true; |
| 93 |
} |
93 |
} |
| 94 |
} |
94 |
} |
| 95 |
} |
95 |
} |
| 96 |
// check for missing returning path |
96 |
// check for missing returning path |
| 97 |
TypeBinding returnTypeBinding = binding.returnType; |
97 |
TypeBinding returnTypeBinding = this.binding.returnType; |
| 98 |
if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) { |
98 |
if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) { |
| 99 |
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { |
99 |
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { |
| 100 |
this.bits |= ASTNode.NeedFreeReturn; |
100 |
this.bits |= ASTNode.NeedFreeReturn; |
| 101 |
} |
101 |
} |
| 102 |
} else { |
102 |
} else { |
| 103 |
if (flowInfo != FlowInfo.DEAD_END) { |
103 |
if (flowInfo != FlowInfo.DEAD_END) { |
| 104 |
scope.problemReporter().shouldReturn(returnTypeBinding, this); |
104 |
this.scope.problemReporter().shouldReturn(returnTypeBinding, this); |
| 105 |
} |
105 |
} |
| 106 |
} |
106 |
} |
| 107 |
// check unreachable catch blocks |
107 |
// check unreachable catch blocks |
| 108 |
methodContext.complainIfUnusedExceptionHandlers(this); |
108 |
methodContext.complainIfUnusedExceptionHandlers(this); |
| 109 |
// check unused parameters |
109 |
// check unused parameters |
| 110 |
scope.checkUnusedParameters(binding); |
110 |
this.scope.checkUnusedParameters(this.binding); |
| 111 |
} catch (AbortMethod e) { |
111 |
} catch (AbortMethod e) { |
| 112 |
this.ignoreFurtherInvestigation = true; |
112 |
this.ignoreFurtherInvestigation = true; |
| 113 |
} |
113 |
} |
| 114 |
} |
114 |
} |
| 115 |
|
115 |
|
| 116 |
public boolean isMethod() { |
116 |
public boolean isMethod() { |
| 117 |
|
|
|
| 118 |
return true; |
117 |
return true; |
| 119 |
} |
118 |
} |
| 120 |
|
119 |
|
| 121 |
public void parseStatements(Parser parser, CompilationUnitDeclaration unit) { |
120 |
public void parseStatements(Parser parser, CompilationUnitDeclaration unit) { |
| 122 |
|
|
|
| 123 |
//fill up the method body with statement |
121 |
//fill up the method body with statement |
| 124 |
if (ignoreFurtherInvestigation) |
|
|
| 125 |
return; |
| 126 |
parser.parse(this, unit); |
122 |
parser.parse(this, unit); |
| 127 |
} |
123 |
} |
| 128 |
|
124 |
|
| 129 |
public StringBuffer printReturnType(int indent, StringBuffer output) { |
125 |
public StringBuffer printReturnType(int indent, StringBuffer output) { |
| 130 |
|
126 |
if (this.returnType == null) return output; |
| 131 |
if (returnType == null) return output; |
127 |
return this.returnType.printExpression(0, output).append(' '); |
| 132 |
return returnType.printExpression(0, output).append(' '); |
|
|
| 133 |
} |
128 |
} |
| 134 |
|
129 |
|
| 135 |
public void resolveStatements() { |
130 |
public void resolveStatements() { |
| 136 |
|
|
|
| 137 |
// ========= abort on fatal error ============= |
131 |
// ========= abort on fatal error ============= |
| 138 |
if (this.returnType != null && this.binding != null) { |
132 |
if (this.returnType != null && this.binding != null) { |
| 139 |
this.returnType.resolvedType = this.binding.returnType; |
133 |
this.returnType.resolvedType = this.binding.returnType; |
| 140 |
// record the return type binding |
134 |
// record the return type binding |
| 141 |
} |
135 |
} |
| 142 |
// check if method with constructor name |
136 |
// check if method with constructor name |
| 143 |
if (CharOperation.equals(this.scope.enclosingSourceType().sourceName, selector)) { |
137 |
if (CharOperation.equals(this.scope.enclosingSourceType().sourceName, this.selector)) { |
| 144 |
this.scope.problemReporter().methodWithConstructorName(this); |
138 |
this.scope.problemReporter().methodWithConstructorName(this); |
| 145 |
} |
139 |
} |
| 146 |
|
140 |
|
|
Lines 215-249
Link Here
|
| 215 |
|
209 |
|
| 216 |
if (visitor.visit(this, classScope)) { |
210 |
if (visitor.visit(this, classScope)) { |
| 217 |
if (this.javadoc != null) { |
211 |
if (this.javadoc != null) { |
| 218 |
this.javadoc.traverse(visitor, scope); |
212 |
this.javadoc.traverse(visitor, this.scope); |
| 219 |
} |
213 |
} |
| 220 |
if (this.annotations != null) { |
214 |
if (this.annotations != null) { |
| 221 |
int annotationsLength = this.annotations.length; |
215 |
int annotationsLength = this.annotations.length; |
| 222 |
for (int i = 0; i < annotationsLength; i++) |
216 |
for (int i = 0; i < annotationsLength; i++) |
| 223 |
this.annotations[i].traverse(visitor, scope); |
217 |
this.annotations[i].traverse(visitor, this.scope); |
| 224 |
} |
218 |
} |
| 225 |
if (this.typeParameters != null) { |
219 |
if (this.typeParameters != null) { |
| 226 |
int typeParametersLength = this.typeParameters.length; |
220 |
int typeParametersLength = this.typeParameters.length; |
| 227 |
for (int i = 0; i < typeParametersLength; i++) { |
221 |
for (int i = 0; i < typeParametersLength; i++) { |
| 228 |
this.typeParameters[i].traverse(visitor, scope); |
222 |
this.typeParameters[i].traverse(visitor, this.scope); |
| 229 |
} |
223 |
} |
| 230 |
} |
224 |
} |
| 231 |
if (returnType != null) |
225 |
if (this.returnType != null) |
| 232 |
returnType.traverse(visitor, scope); |
226 |
this.returnType.traverse(visitor, this.scope); |
| 233 |
if (arguments != null) { |
227 |
if (this.arguments != null) { |
| 234 |
int argumentLength = arguments.length; |
228 |
int argumentLength = this.arguments.length; |
| 235 |
for (int i = 0; i < argumentLength; i++) |
229 |
for (int i = 0; i < argumentLength; i++) |
| 236 |
arguments[i].traverse(visitor, scope); |
230 |
this.arguments[i].traverse(visitor, this.scope); |
| 237 |
} |
231 |
} |
| 238 |
if (thrownExceptions != null) { |
232 |
if (this.thrownExceptions != null) { |
| 239 |
int thrownExceptionsLength = thrownExceptions.length; |
233 |
int thrownExceptionsLength = this.thrownExceptions.length; |
| 240 |
for (int i = 0; i < thrownExceptionsLength; i++) |
234 |
for (int i = 0; i < thrownExceptionsLength; i++) |
| 241 |
thrownExceptions[i].traverse(visitor, scope); |
235 |
this.thrownExceptions[i].traverse(visitor, this.scope); |
| 242 |
} |
236 |
} |
| 243 |
if (statements != null) { |
237 |
if (this.statements != null) { |
| 244 |
int statementsLength = statements.length; |
238 |
int statementsLength = this.statements.length; |
| 245 |
for (int i = 0; i < statementsLength; i++) |
239 |
for (int i = 0; i < statementsLength; i++) |
| 246 |
statements[i].traverse(visitor, scope); |
240 |
this.statements[i].traverse(visitor, this.scope); |
| 247 |
} |
241 |
} |
| 248 |
} |
242 |
} |
| 249 |
visitor.endVisit(this, classScope); |
243 |
visitor.endVisit(this, classScope); |