Skip to content

Commit 7b3fac3

Browse files
committed
GROOVY-6328
1 parent 79530b5 commit 7b3fac3

File tree

2 files changed

+69
-12
lines changed

2 files changed

+69
-12
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/STCScriptsTests.java

+48-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2020 the original author or authors.
2+
* Copyright 2009-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,7 +15,9 @@
1515
*/
1616
package org.eclipse.jdt.core.groovy.tests.builder;
1717

18+
import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isAtLeastGroovy;
1819
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assume.assumeTrue;
1921

2022
import java.util.Arrays;
2123

@@ -67,12 +69,12 @@ public void testStaticTypeCheckingDSL1() throws Exception {
6769
" storeType(var, robotClass)\n" +
6870
" handled = true\n" +
6971
" }\n" +
70-
"}");
72+
"}\n");
7173
env.addGroovyClass(projPath.append("src"), "Robot",
7274
"@groovy.transform.TypeChecked(extensions = 'RobotMove.groovy')\n" +
7375
"void operate() {\n" +
7476
" robot.move \"left\"\n" +
75-
"}");
77+
"}\n");
7678
//@formatter:on
7779

7880
env.fullBuild(projPath);
@@ -97,7 +99,7 @@ public void testStaticTypeCheckingDSL2() throws Exception {
9799
" storeType(var, robotClass)\n" +
98100
" handled = true\n" +
99101
" }\n" +
100-
"}");
102+
"}\n");
101103
env.addGroovyClass(projPath.append("src"), "RobotScript",
102104
"import groovy.transform.TypeChecked\n" +
103105
"class Robot {\n" +
@@ -107,11 +109,52 @@ public void testStaticTypeCheckingDSL2() throws Exception {
107109
"@TypeChecked(extensions = 'RobotMove.groovy')\n" +
108110
"void operate() {\n" +
109111
" robot.move \"left\"\n" +
110-
"}");
112+
"}\n");
111113
//@formatter:on
112114

113115
env.fullBuild(projPath);
114116
Problem[] problems = env.getProblemsFor(projPath);
115117
assertEquals("Should have found no problems in:\n" + Arrays.toString(problems), 0, problems.length);
116118
}
119+
120+
@Test // GROOVY-6328
121+
public void testStaticTypeCheckingDSL3() throws Exception { assumeTrue(isAtLeastGroovy(40));
122+
Activator.getInstancePreferences().putBoolean(Activator.GROOVY_SCRIPT_FILTERS_ENABLED, true);
123+
Activator.getInstancePreferences().put(Activator.GROOVY_SCRIPT_FILTERS, "src/*Checker.groovy,y");
124+
125+
IPath projPath = createGenericProject();
126+
//@formatter:off
127+
env.addGroovyClass(projPath.append("src"), "TypeChecker",
128+
"onMethodSelection { expr, node ->\n" +
129+
" context.enclosingBinaryExpression.putNodeMetaData('notified', true)\n" +
130+
"}\n");
131+
//@formatter:on
132+
133+
for (String methods : new String[] {"", "void setS(String s) {this.s = s}"}) {
134+
env.addGroovyClass(projPath.append("src"), "TestScript",
135+
"import static org.codehaus.groovy.control.CompilePhase.INSTRUCTION_SELECTION\n" +
136+
"class C {\n" +
137+
" String s\n" +
138+
" " + methods + "\n" +
139+
"}\n" +
140+
"C make(@DelegatesTo(value=C.class, strategy=Closure.DELEGATE_FIRST) Closure closure) {\n" +
141+
" new C().tap(closure)\n" +
142+
"}\n" +
143+
"@groovy.transform.ASTTest(phase=INSTRUCTION_SELECTION, value={\n" +
144+
" def assignment = lookup.call('here')[0].expression\n" +
145+
" assert assignment.getNodeMetaData('notified')\n" +
146+
"})\n" +
147+
"@groovy.transform.TypeChecked(extensions='TypeChecker.groovy')\n" +
148+
"void test() {\n" +
149+
" def c = make {\n" +
150+
" here: s = 'foo'\n" + // expecting onMethodSelection for setter
151+
" }\n" +
152+
"}\n");
153+
//@formatter:on
154+
155+
env.fullBuild(projPath);
156+
Problem[] problems = env.getProblemsFor(projPath);
157+
assertEquals("Should have found no problems in:\n" + Arrays.toString(problems), 0, problems.length);
158+
}
159+
}
117160
}

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+21-7
Original file line numberDiff line numberDiff line change
@@ -1636,11 +1636,12 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
16361636
}
16371637
}
16381638
}
1639-
foundGetterOrSetter = (foundGetterOrSetter || !setters.isEmpty() || getter != null);
16401639

1641-
if (property != null && storeProperty(property, pexp, receiverType, visitor, receiver.getData())) return true;
1640+
if (property != null && storeProperty(property, pexp, receiverType, visitor, receiver.getData(), !readMode)) return true;
16421641

16431642
if (field != null && storeField(field, pexp, receiverType, visitor, receiver.getData(), !readMode)) return true;
1643+
1644+
foundGetterOrSetter = (foundGetterOrSetter || !setters.isEmpty() || getter != null);
16441645
}
16451646

16461647
// GROOVY-5568: the property may be defined by DGM
@@ -1854,16 +1855,29 @@ private boolean storeField(final FieldNode field, final PropertyExpression expre
18541855
return true;
18551856
}
18561857

1857-
private boolean storeProperty(final PropertyNode property, final PropertyExpression expressionToStoreOn, final ClassNode receiver, final ClassCodeVisitorSupport visitor, final String delegationData) {
1858+
private boolean storeProperty(final PropertyNode property, final PropertyExpression expression, final ClassNode receiver, final ClassCodeVisitorSupport visitor, final String delegationData, final boolean lhsOfAssignment) {
18581859
if (visitor != null) visitor.visitProperty(property);
1859-
storeWithResolve(property.getOriginType(), receiver, property.getDeclaringClass(), property.isStatic(), expressionToStoreOn);
1860+
ClassNode propertyType = property.getOriginType();
1861+
1862+
storeWithResolve(propertyType, receiver, property.getDeclaringClass(), property.isStatic(), expression);
1863+
18601864
if (delegationData != null) {
1861-
expressionToStoreOn.putNodeMetaData(IMPLICIT_RECEIVER, delegationData);
1865+
expression.putNodeMetaData(IMPLICIT_RECEIVER, delegationData);
18621866
}
18631867
if (Modifier.isFinal(property.getModifiers())) {
1864-
expressionToStoreOn.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE);
1868+
expression.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE);
1869+
if (!lhsOfAssignment) {
1870+
MethodNode implicitGetter = new MethodNode(property.getGetterNameOrDefault(), Opcodes.ACC_PUBLIC, propertyType, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
1871+
implicitGetter.setDeclaringClass(property.getDeclaringClass());
1872+
extension.onMethodSelection(expression, implicitGetter);
1873+
}
18651874
} else {
1866-
expressionToStoreOn.removeNodeMetaData(READONLY_PROPERTY);
1875+
expression.removeNodeMetaData(READONLY_PROPERTY);
1876+
if (lhsOfAssignment) {
1877+
MethodNode implicitSetter = new MethodNode(property.getSetterNameOrDefault(), Opcodes.ACC_PUBLIC, VOID_TYPE, new Parameter[] {new Parameter(propertyType, "value")}, ClassNode.EMPTY_ARRAY, null);
1878+
implicitSetter.setDeclaringClass(property.getDeclaringClass());
1879+
extension.onMethodSelection(expression, implicitSetter);
1880+
}
18671881
}
18681882
return true;
18691883
}

0 commit comments

Comments
 (0)