Skip to content

Commit

Permalink
Fix for #878: static reference to instance method works in Groovy 3
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Apr 28, 2019
1 parent 475920e commit f64ec5e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -28,6 +28,7 @@
import java.util.stream.Stream;

import groovy.lang.Closure;
import groovy.lang.GroovySystem;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
Expand All @@ -54,6 +55,7 @@
import org.codehaus.groovy.ast.expr.FieldExpression;
import org.codehaus.groovy.ast.expr.GStringExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.MethodPointerExpression;
import org.codehaus.groovy.ast.expr.PropertyExpression;
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
import org.codehaus.groovy.ast.expr.TupleExpression;
Expand Down Expand Up @@ -410,7 +412,7 @@ protected TypeLookupResult findTypeForNameWithKnownObjectExpression(final String
}
} else if (declaration instanceof MethodNode) {
MethodNode method = (MethodNode) declaration;
if (isStaticObjectExpression && !method.isStatic()) {
if (isStaticObjectExpression && !method.isStatic() && !isStaticReferenceToInstanceMethod(scope)) {
confidence = TypeConfidence.UNKNOWN;
} else if (Flags.isPrivate(method.getModifiers()) && isThisObjectExpression(scope) && isNotThisOrOuterClass(declaringType, resolvedDeclaringType)) {
// "this.method()" reference to private method of super class yields MissingMethodException; "super.method()" is okay
Expand Down Expand Up @@ -934,6 +936,15 @@ protected static boolean isSuperObjectExpression(final VariableScope scope) {
return (expr instanceof VariableExpression && ((VariableExpression) expr).isSuperExpression());
}

protected static boolean isStaticReferenceToInstanceMethod(final VariableScope scope) {
if (scope.getEnclosingNode() instanceof MethodPointerExpression && scope.getCurrentNode() instanceof ConstantExpression) {
// "Type.&instanceMethod" and "Type::instanceMethod" are supported starting in Groovy 3
int majorVersion = Integer.parseInt(GroovySystem.getVersion().split("\\.")[0], 10);
return (majorVersion >= 3);
}
return false;
}

protected static boolean isCompatible(final AnnotatedNode declaration, final boolean isStaticExpression) {
if (declaration != null) {
boolean isStatic = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package org.codehaus.groovy.eclipse.test.ui

import static org.codehaus.groovy.eclipse.editor.highlighting.HighlightedTypedPosition.HighlightKind.*
import static org.codehaus.groovy.eclipse.editor.highlighting.HighlightedTypedPosition.HighlightKind.GROOVY_CALL as GSTRING
import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isAtLeastGroovy
import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isParrotParser
import static org.junit.Assert.assertEquals
import static org.junit.Assume.assumeTrue
Expand Down Expand Up @@ -2324,6 +2325,30 @@ final class SemanticHighlightingTests extends GroovyEclipseTestSuite {
new HighlightedTypedPosition(contents.indexOf('toLowerCase'), 'toLowerCase'.length(), METHOD_CALL))
}

@Test
void testMethodPointer3() {
String contents = '''\
String.&toLowerCase
'''.stripIndent()

assertHighlighting(contents,
new HighlightedTypedPosition(contents.indexOf('toLowerCase'), 'toLowerCase'.length(), isAtLeastGroovy(30) ? METHOD_CALL : UNKNOWN))
}

@Test
void testMethodReference() {
assumeTrue(isParrotParser())

String contents = '''\
String::toLowerCase
Integer::toHexString
'''.stripIndent()

assertHighlighting(contents,
new HighlightedTypedPosition(contents.indexOf('toLowerCase'), 'toLowerCase'.length(), METHOD_CALL),
new HighlightedTypedPosition(contents.indexOf('toHexString'), 'toHexString'.length(), STATIC_CALL))
}

@Test
void testMethodOverloads() {
// overloads with generics caused confusion in TypeInferencingVisitor
Expand Down

0 comments on commit f64ec5e

Please sign in to comment.