Skip to content

Commit fd70f04

Browse files
committed
Fix namedobj vs obj when type checking multiple args
1 parent b807b25 commit fd70f04

File tree

2 files changed

+39
-16
lines changed

2 files changed

+39
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- Allowed empty lines in sym files.
2020
- Symbols can now be resolved from sub directories.
2121
- Allow for clientscript/command to be looked up in "Search Everywhere".
22+
- Fixed namedobj vs obj when type checking multiple args.
2223

2324
## [1.5.1] - 2024-04-15
2425

src/main/kotlin/io/runescript/plugin/lang/psi/type/inference/RsTypeInferenceVisitor.kt

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement
55
import com.intellij.psi.util.findParentOfType
66
import com.intellij.psi.util.parentOfType
77
import com.intellij.refactoring.suggested.startOffset
8+
import com.intellij.util.SmartList
89
import io.runescript.plugin.ide.RsBundle
910
import io.runescript.plugin.lang.psi.*
1011
import io.runescript.plugin.lang.psi.refs.RsDynamicExpressionReference
@@ -107,6 +108,20 @@ class RsTypeInferenceVisitor(private val myInferenceData: RsTypeInference) : RsV
107108
return this
108109
}
109110

111+
private fun RsType?.flatten(): SmartList<RsType> {
112+
if (this == null) {
113+
return SmartList()
114+
}
115+
if (this is RsTupleType) {
116+
val result = SmartList<RsType>()
117+
types.forEach {
118+
result.addAll(it.flatten())
119+
}
120+
return result
121+
}
122+
return SmartList(this)
123+
}
124+
110125
private fun Collection<RsType>?.fold(): RsType {
111126
if (this == null) {
112127
return RsUnitType
@@ -117,10 +132,6 @@ class RsTypeInferenceVisitor(private val myInferenceData: RsTypeInference) : RsV
117132
return RsTupleType(flatten())
118133
}
119134

120-
private fun checkTypeMismatchAll(context: PsiElement, actualType: RsType?, expectedTypes: List<RsType>): Boolean {
121-
return expectedTypes.all { checkTypeMismatch(context, actualType, it, false) }
122-
}
123-
124135
private fun checkTypeMismatch(
125136
context: PsiElement,
126137
actualType: RsType?,
@@ -138,6 +149,26 @@ class RsTypeInferenceVisitor(private val myInferenceData: RsTypeInference) : RsV
138149
if (unfoldedExpectedType is RsTupleType && RsErrorType in unfoldedExpectedType.types) {
139150
return false
140151
}
152+
val flattenedActualType = unfoldedActualType.flatten()
153+
val flattenedExpectedType = unfoldedExpectedType.flatten()
154+
if (flattenedActualType.size != flattenedExpectedType.size
155+
|| !flattenedActualType.zip(flattenedExpectedType).all { isSingleTypeMatch(it.second, it.first) }
156+
) {
157+
if (reportError) {
158+
context.error(
159+
TYPE_MISMATCH_ERROR.format(
160+
unfoldedActualType.representation,
161+
unfoldedExpectedType.representation
162+
)
163+
)
164+
}
165+
return false
166+
}
167+
return true
168+
}
169+
170+
private fun isSingleTypeMatch(unfoldedExpectedType: RsType, unfoldedActualType: RsType): Boolean {
171+
check(unfoldedActualType !is RsTupleType && unfoldedExpectedType !is RsTupleType)
141172
if (unfoldedExpectedType == RsPrimitiveType.OBJ && unfoldedActualType == RsPrimitiveType.NAMEDOBJ) {
142173
// namedobj extends obj
143174
return true
@@ -150,18 +181,7 @@ class RsTypeInferenceVisitor(private val myInferenceData: RsTypeInference) : RsV
150181
// hooks are just strings that are parsed different.
151182
return true
152183
}
153-
if (unfoldedActualType != unfoldedExpectedType) {
154-
if (reportError) {
155-
context.error(
156-
TYPE_MISMATCH_ERROR.format(
157-
unfoldedActualType.representation,
158-
unfoldedExpectedType.representation
159-
)
160-
)
161-
}
162-
return false
163-
}
164-
return true
184+
return unfoldedActualType == unfoldedExpectedType
165185
}
166186

167187
override fun visitGosubExpression(o: RsGosubExpression) {
@@ -598,6 +618,7 @@ class RsTypeInferenceVisitor(private val myInferenceData: RsTypeInference) : RsV
598618
o.error("Could not convert constant value '${value}' to a long number.")
599619
}
600620
}
621+
601622
else -> {
602623
val configReference = RsSymbolIndex.lookup(o.project, type, value)
603624
if (configReference == null) {
@@ -676,6 +697,7 @@ class RsTypeInferenceVisitor(private val myInferenceData: RsTypeInference) : RsV
676697
?.toTypedArray<RsType>()
677698
checkExpressionList(o, o.expressionList, expectedReturnList ?: emptyArray<RsType>())
678699
}
700+
679701
companion object {
680702
private const val TYPE_MISMATCH_ERROR = "Type mismatch: '%s' was given but '%s' was expected"
681703
private const val INVALID_OPERATOR_ERROR = "Operator '%s' cannot be applied to '%s', '%s'"

0 commit comments

Comments
 (0)