Merge branch 'pr-258'

This commit is contained in:
Andreas Dangel
2017-02-20 15:50:21 +01:00
3 changed files with 63 additions and 44 deletions

View File

@ -127,6 +127,14 @@ public class ClassScope extends AbstractJavaScope {
List<NameOccurrence> nameOccurrences = getMethodDeclarations().get(decl);
if (nameOccurrences == null) {
// TODO may be a class name: Foo.this.super();
// search inner classes
for (ClassNameDeclaration innerClass : getClassDeclarations().keySet()) {
Scope innerClassScope = innerClass.getScope();
if (innerClassScope.contains(javaOccurrence)) {
innerClassScope.addNameOccurrence(javaOccurrence);
}
}
} else {
nameOccurrences.add(javaOccurrence);
Node n = javaOccurrence.getLocation();
@ -174,48 +182,17 @@ public class ClassScope extends AbstractJavaScope {
Set<NameDeclaration> result = new HashSet<>();
if (occurrence.isMethodOrConstructorInvocation()) {
final boolean hasAuxclasspath = getEnclosingScope(SourceFileScope.class).hasAuxclasspath();
for (MethodNameDeclaration mnd : methodDeclarations.keySet()) {
if (mnd.getImage().equals(occurrence.getImage())) {
List<TypedNameDeclaration> parameterTypes = determineParameterTypes(mnd);
List<TypedNameDeclaration> argumentTypes = determineArgumentTypes(occurrence, parameterTypes);
matchMethodDeclaration(occurrence, methodDeclarations.keySet(), hasAuxclasspath, result);
if (!mnd.isVarargs() && occurrence.getArgumentCount() == mnd.getParameterCount()
&& (!hasAuxclasspath || parameterTypes.equals(argumentTypes))) {
result.add(mnd);
} else if (mnd.isVarargs()) {
int varArgIndex = parameterTypes.size() - 1;
TypedNameDeclaration varArgType = parameterTypes.get(varArgIndex);
// first parameter is varArg, calling method might have
// 0 or more arguments
// or the calling method has enough arguments to fill in
// the parameters before the vararg
if ((varArgIndex == 0 || argumentTypes.size() >= varArgIndex)
&& (!hasAuxclasspath || parameterTypes
.subList(0, varArgIndex).equals(argumentTypes.subList(0, varArgIndex)))) {
if (!hasAuxclasspath) {
result.add(mnd);
continue;
}
boolean sameType = true;
for (int i = varArgIndex; i < argumentTypes.size(); i++) {
if (!varArgType.equals(argumentTypes.get(i))) {
sameType = false;
break;
}
}
if (sameType) {
result.add(mnd);
}
}
}
}
}
if (isEnum && "valueOf".equals(occurrence.getImage())) {
result.add(createBuiltInMethodDeclaration("valueOf", "String"));
}
if (result.isEmpty()) {
for (ClassNameDeclaration innerClass : getClassDeclarations().keySet()) {
matchMethodDeclaration(occurrence, innerClass.getScope().getDeclarations(MethodNameDeclaration.class).keySet(), hasAuxclasspath, result);
}
}
return result;
}
if (occurrence.isMethodReference()) {
@ -255,6 +232,50 @@ public class ClassScope extends AbstractJavaScope {
return result;
}
private void matchMethodDeclaration(JavaNameOccurrence occurrence,
Set<MethodNameDeclaration> methodDeclarations, final boolean hasAuxclasspath,
Set<NameDeclaration> result) {
for (MethodNameDeclaration mnd : methodDeclarations) {
if (mnd.getImage().equals(occurrence.getImage())) {
List<TypedNameDeclaration> parameterTypes = determineParameterTypes(mnd);
List<TypedNameDeclaration> argumentTypes = determineArgumentTypes(occurrence, parameterTypes);
if (!mnd.isVarargs() && occurrence.getArgumentCount() == mnd.getParameterCount()
&& (!hasAuxclasspath || parameterTypes.equals(argumentTypes))) {
result.add(mnd);
} else if (mnd.isVarargs()) {
int varArgIndex = parameterTypes.size() - 1;
TypedNameDeclaration varArgType = parameterTypes.get(varArgIndex);
// first parameter is varArg, calling method might have
// 0 or more arguments
// or the calling method has enough arguments to fill in
// the parameters before the vararg
if ((varArgIndex == 0 || argumentTypes.size() >= varArgIndex)
&& (!hasAuxclasspath || parameterTypes
.subList(0, varArgIndex).equals(argumentTypes.subList(0, varArgIndex)))) {
if (!hasAuxclasspath) {
result.add(mnd);
continue;
}
boolean sameType = true;
for (int i = varArgIndex; i < argumentTypes.size(); i++) {
if (!varArgType.equals(argumentTypes.get(i))) {
sameType = false;
break;
}
}
if (sameType) {
result.add(mnd);
}
}
}
}
}
}
/**
* Creates a fake method name declaration for built-in methods from Java
* like the Enum Method "valueOf".

View File

@ -121,12 +121,12 @@ public class Foo {
}
]]></code>
</test-code>
<test-code regressionTest="false">
<test-code>
<description><![CDATA[
IGNORED - outer class accesses private method of inner class
outer class accesses private method of inner class
]]></description>
<expected-problems>1</expected-problems>
<expected-linenumbers>9</expected-linenumbers>
<expected-linenumbers>8</expected-linenumbers>
<code><![CDATA[
public class Foo {
public class InnerClass {
@ -135,7 +135,6 @@ public class Foo {
}
private void outerSecret() {
// FIXME : This is not detected right now. Name searches are not taking qualifiers into account...
new InnerClass().secret(); // violation, accesing a private method
}
}