Skip to content

Commit 1c36201

Browse files
committed
fixes
1 parent ccdc03f commit 1c36201

3 files changed

Lines changed: 91 additions & 6 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/AttrExprType.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,17 @@ public static WurstType calculate(ExprVarArrayAccess term) {
103103
return ((WurstTypeArray) varDefType).getBaseType();
104104
}
105105
if (term.getIndexes().size() == 1) {
106-
FuncLink overload = AttrFuncDef.getIndexGetOperator(term, varDefType, term.getIndexes().get(0).attrTyp());
107-
if (overload != null) {
108-
return overload.getReturnType();
106+
WurstType indexType = term.getIndexes().get(0).attrTyp();
107+
FuncLink getOverload = AttrFuncDef.getIndexGetOperator(term, varDefType, indexType);
108+
if (getOverload != null) {
109+
return getOverload.getReturnType();
110+
}
111+
if (isWriteAccess(term)) {
112+
FuncLink setOverload = AttrFuncDef.getIndexSetOperatorByIndex(term, varDefType, indexType);
113+
if (setOverload != null) {
114+
return setOverload.getParameterType(1);
115+
}
116+
return WurstTypeUnknown.instance();
109117
}
110118
}
111119
term.addError("Variable " + varDef.getName() + " is of type " + varDefType +
@@ -419,9 +427,17 @@ public static WurstType calculate(ExprMemberArrayVarDot term) {
419427
return ar.getBaseType();
420428
}
421429
if (term.getIndexes().size() == 1) {
422-
FuncLink overload = AttrFuncDef.getIndexGetOperator(term, typ, term.getIndexes().get(0).attrTyp());
423-
if (overload != null) {
424-
return overload.getReturnType();
430+
WurstType indexType = term.getIndexes().get(0).attrTyp();
431+
FuncLink getOverload = AttrFuncDef.getIndexGetOperator(term, typ, indexType);
432+
if (getOverload != null) {
433+
return getOverload.getReturnType();
434+
}
435+
if (isWriteAccess(term)) {
436+
FuncLink setOverload = AttrFuncDef.getIndexSetOperatorByIndex(term, typ, indexType);
437+
if (setOverload != null) {
438+
return setOverload.getParameterType(1);
439+
}
440+
return WurstTypeUnknown.instance();
425441
}
426442
}
427443
term.addError("Variable " + term.getVarName() + " is not an array and has no " + AttrFuncDef.overloadingIndexGet + " overload.");
@@ -604,4 +620,12 @@ public static WurstType calculate(ExprArrayLength exprArrayLength) {
604620
exprArrayLength.addError(".length is only valid on arrays.");
605621
return de.peeeq.wurstscript.types.WurstTypeUnknown.instance();
606622
}
623+
624+
private static boolean isWriteAccess(NameRef node) {
625+
if (node.getParent() instanceof StmtSet) {
626+
StmtSet stmtSet = (StmtSet) node.getParent();
627+
return stmtSet.getUpdatedExpr() == node;
628+
}
629+
return false;
630+
}
607631
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/AttrFuncDef.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,41 @@ private static boolean isConstructorThisCall(ExprFunctionCall node) {
226226
return candidate;
227227
}
228228

229+
public static @Nullable FuncLink getIndexSetOperatorByIndex(Expr node, WurstType receiverType, WurstType indexType) {
230+
Collection<FuncLink> funcs1 = node.lookupMemberFuncs(receiverType, overloadingIndexSet);
231+
if (funcs1.isEmpty()) {
232+
return null;
233+
}
234+
List<FuncLink> funcs = filterInvisible(overloadingIndexSet, node, funcs1);
235+
funcs = filterByReceiverType(node, overloadingIndexSet, funcs);
236+
List<FuncLink> byParamCount = Lists.newArrayList();
237+
for (FuncLink f : funcs) {
238+
if (f.getParameterTypes().size() == 2) {
239+
byParamCount.add(f);
240+
}
241+
}
242+
if (byParamCount.isEmpty()) {
243+
return null;
244+
}
245+
List<FuncLink> byIndexType = Lists.newArrayList();
246+
for (FuncLink f : byParamCount) {
247+
VariableBinding mapping = f.getVariableBinding();
248+
WurstType expectedIndexType = f.getParameterType(0);
249+
VariableBinding m2 = indexType.matchAgainstSupertype(expectedIndexType, node, mapping, VariablePosition.RIGHT);
250+
if (m2 != null) {
251+
byIndexType.add(f);
252+
}
253+
}
254+
if (byIndexType.isEmpty()) {
255+
return null;
256+
}
257+
if (byIndexType.size() == 1) {
258+
return byIndexType.get(0);
259+
}
260+
// ambiguous write-only expected type context: pick deterministic first
261+
return byIndexType.get(0);
262+
}
263+
229264
private static boolean matchesArguments(Element node, FuncLink f, List<WurstType> argumentTypes) {
230265
if (f.getParameterTypes().size() != argumentTypes.size()) {
231266
return false;

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/OpOverloading.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,5 +268,31 @@ public void testOverloading_indexWriteWrongIndexType() {
268268
"endpackage");
269269
}
270270

271+
@Test
272+
public void testOverloading_indexWriteOnlySetter() {
273+
testAssertOkLines(false,
274+
"package test",
275+
" class ListLike",
276+
" function op_indexAssign(int i, int v)",
277+
" init",
278+
" ListLike l = new ListLike()",
279+
" l[1] = 2",
280+
"endpackage");
281+
}
282+
283+
@Test
284+
public void testOverloading_memberIndexWriteOnlySetter() {
285+
testAssertOkLines(false,
286+
"package test",
287+
" class ListLike",
288+
" function op_indexAssign(int i, int v)",
289+
" class Box",
290+
" ListLike l = new ListLike()",
291+
" init",
292+
" Box b = new Box()",
293+
" b.l[1] = 2",
294+
"endpackage");
295+
}
296+
271297

272298
}

0 commit comments

Comments
 (0)