Skip to content

Commit 323bf18

Browse files
committed
GROOVY-10326
1 parent bcb5639 commit 323bf18

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java

+22
Original file line numberDiff line numberDiff line change
@@ -4206,4 +4206,26 @@ public void testTypeChecked10325() {
42064206

42074207
runConformTest(sources, "[foo:baz!]");
42084208
}
4209+
4210+
@Test
4211+
public void testTypeChecked10326() {
4212+
//@formatter:off
4213+
String[] sources = {
4214+
"Main.groovy",
4215+
"@groovy.transform.TypeChecked\n" +
4216+
"@SuppressWarnings('rawtypes')\n" +
4217+
"void test(Map map) {\n" +
4218+
" map*.key = null\n" +
4219+
"}\n",
4220+
};
4221+
//@formatter:on
4222+
4223+
runNegativeTest(sources,
4224+
"----------\n" +
4225+
"1. ERROR in Main.groovy (at line 4)\n" +
4226+
"\tmap*.key = null\n" +
4227+
"\t^^^^^^^^" + (isParrotParser() ? "" : "^") + "\n" +
4228+
"Groovy:[Static type checking] - Cannot set read-only property: key\n" +
4229+
"----------\n");
4230+
}
42094231
}

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -2095,12 +2095,20 @@ private ClassNode getTypeForMapPropertyExpression(ClassNode testClass, ClassNode
20952095
// GRECLIPSE end
20962096
// 0 is the key, 1 is the value
20972097
GenericsType[] types = intf.getGenericsTypes();
2098+
/* GRECLIPSE edit -- GROOVY-10326
20982099
if (types == null || types.length != 2) return OBJECT_TYPE;
2099-
2100+
*/
2101+
if (types == null || types.length != 2) types = new GenericsType[] {
2102+
OBJECT_TYPE.asGenericsType(), OBJECT_TYPE.asGenericsType()
2103+
};
2104+
// GRECLIPSE end
21002105
if (pexp.isSpreadSafe()) {
21012106
// map*.property syntax
21022107
// only "key" and "value" are allowed
21032108
if ("key".equals(pexp.getPropertyAsString())) {
2109+
// GRECLIPSE add -- GROOVY-10326
2110+
pexp.putNodeMetaData(StaticTypesMarker.READONLY_PROPERTY, Boolean.TRUE);
2111+
// GRECLIPSE end
21042112
ClassNode listKey = LIST_TYPE.getPlainNodeReference();
21052113
listKey.setGenericsTypes(new GenericsType[]{types[0]});
21062114
return listKey;

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -1969,15 +1969,20 @@ private ClassNode getTypeForMapPropertyExpression(final ClassNode testClass, fin
19691969
if (isOrImplements(testClass, MAP_TYPE)) {
19701970
ClassNode mapType = testClass.equals(MAP_TYPE) ? testClass
19711971
: GenericsUtils.parameterizeType(testClass, MAP_TYPE);
1972-
GenericsType[] gts = mapType.getGenericsTypes();//<K,V>
1973-
if (gts == null || gts.length != 2) return OBJECT_TYPE;
1972+
GenericsType[] gts = mapType.getGenericsTypes();//<K,V> params
1973+
if (gts == null || gts.length != 2) gts = new GenericsType[] {
1974+
OBJECT_TYPE.asGenericsType(), OBJECT_TYPE.asGenericsType()
1975+
};
19741976

19751977
if (!pexp.isSpreadSafe()) {
19761978
return getCombinedBoundType(gts[1]);
19771979
} else {
19781980
// map*.property syntax acts on Entry
19791981
switch (pexp.getPropertyAsString()) {
19801982
case "key":
1983+
// GRECLIPSE add -- GROOVY-10326
1984+
pexp.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE);
1985+
// GRECLIPSE end
19811986
ClassNode keyList = LIST_TYPE.getPlainNodeReference();
19821987
keyList.setGenericsTypes(new GenericsType[]{gts[0]});
19831988
return keyList;

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -1779,15 +1779,18 @@ private ClassNode getTypeForMapPropertyExpression(final ClassNode testClass, fin
17791779
if (isOrImplements(testClass, MAP_TYPE)) {
17801780
ClassNode mapType = testClass.equals(MAP_TYPE) ? testClass
17811781
: GenericsUtils.parameterizeType(testClass, MAP_TYPE);
1782-
GenericsType[] gts = mapType.getGenericsTypes();//<K,V>
1783-
if (gts == null || gts.length != 2) return OBJECT_TYPE;
1782+
GenericsType[] gts = mapType.getGenericsTypes();//<K,V> params
1783+
if (gts == null || gts.length != 2) gts = new GenericsType[] {
1784+
OBJECT_TYPE.asGenericsType(), OBJECT_TYPE.asGenericsType()
1785+
};
17841786

17851787
if (!pexp.isSpreadSafe()) {
17861788
return getCombinedBoundType(gts[1]);
17871789
} else {
17881790
// map*.property syntax acts on Entry
17891791
switch (pexp.getPropertyAsString()) {
17901792
case "key":
1793+
pexp.putNodeMetaData(READONLY_PROPERTY,Boolean.TRUE); // GROOVY-10326
17911794
return makeClassSafe0(LIST_TYPE, gts[0]);
17921795
case "value":
17931796
GenericsType v = gts[1];

0 commit comments

Comments
 (0)