Skip to content
This repository was archived by the owner on Nov 6, 2019. It is now read-only.

Commit 02f28a9

Browse files
committed
Fix overriding of equals, hashCode, and toString to always compile
1 parent 3f9f7af commit 02f28a9

File tree

6 files changed

+30
-23
lines changed

6 files changed

+30
-23
lines changed

src/ast/typescript/typeScriptAstUtils.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import typescriptServices.ts.*
2525
val ANY = KtQualifiedName("Any")
2626
val NOTHING = KtQualifiedName("Nothing")
2727
val NUMBER = KtQualifiedName("Number")
28+
val INT = KtQualifiedName("Int")
2829
val STRING = KtQualifiedName("String")
2930
val BOOLEAN = KtQualifiedName("Boolean")
3031
val UNIT = KtQualifiedName("Unit")

src/converter/TypeScriptToKotlinBase.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,27 @@ abstract class TypeScriptToKotlinBase(
2020

2121
open fun addFunction(symbol: Symbol?, name: String, callSignature: KtCallSignature, extendsType: KtType? = null, needsNoImpl: Boolean = true, additionalAnnotations: List<KtAnnotation> = listOf(), isOverride: Boolean = false, isOperator: Boolean = false) {
2222
val annotations = defaultAnnotations + additionalAnnotations
23-
addDeclaration(symbol, KtFunction(KtName(name), callSignature, extendsType?.let { KtHeritageType(it) }, annotations, needsNoImpl = needsNoImpl, isOverride = isOverride, hasOpenModifier = hasMembersOpenModifier, isOperator = isOperator))
23+
var actualIsOverride = isOverride
24+
val overrideCallSignature = if ("hashCode" == name && callSignature.params.isEmpty()) {
25+
actualIsOverride = true
26+
//force hashCode to return an Int so it will compile
27+
callSignature.copy(returnType = callSignature.returnType.copy(type = KtType(INT)))
28+
} else if ("toString" == name && callSignature.params.isEmpty()) {
29+
actualIsOverride = true
30+
//force toString to return a String so it will compile
31+
callSignature.copy(returnType = callSignature.returnType.copy(type = KtType(STRING)))
32+
} else if ("equals" == name && callSignature.params.size == 1 && callSignature.params[0].type.type.qualifiedName == ANY) {
33+
actualIsOverride = true
34+
callSignature.copy(
35+
//force equals to take Any? (instead of Any) so that it overrides
36+
params = callSignature.params.map { it.copy(type = it.type.copy(type = KtType(ANY, isNullable = true))) },
37+
//force equals to return a Boolean so it will compile
38+
returnType = callSignature.returnType.copy(type = KtType(BOOLEAN)))
39+
} else {
40+
callSignature
41+
}
42+
val heritageType = extendsType?.let { KtHeritageType(it) }
43+
addDeclaration(symbol, KtFunction(KtName(name), overrideCallSignature, heritageType, annotations, needsNoImpl, actualIsOverride, hasMembersOpenModifier, isOperator))
2444
}
2545

2646
protected fun addDeclaration(symbol: Symbol?, declaration: KtMember) {

src/runner/translate.kt

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,6 @@ fun translate(srcPath: String, basePackageName: String, declareModifierIsOptiona
8686
// val fileNode = languageService.getSourceFile(normalizeSrcPath)
8787
val fileNode = languageService.getProgram().getSourceFile(normalizeSrcPath)
8888

89-
inline fun isAnyMember(node: MethodDeclaration): Boolean {
90-
val params = node.parameters.arr
91-
92-
return when (node.propertyName?.text) {
93-
"equals" ->
94-
params.size == 1 && params[0].type?.let { it.kind === SyntaxKind.AnyKeyword } ?: true
95-
// TODO check return type ???
96-
"hashCode", "toString" ->
97-
params.size == 0
98-
else ->
99-
false
100-
}
101-
}
102-
10389
/*inline*/ fun isOverrideHelper(
10490
node: Declaration,
10591
/*crossinline*/ f: (TypeChecker, Type, String) -> Boolean
@@ -172,8 +158,6 @@ fun translate(srcPath: String, basePackageName: String, declareModifierIsOptiona
172158
}
173159

174160
fun isOverride(node: MethodDeclaration): Boolean {
175-
if (isAnyMember(node)) return true
176-
177161
var nodeSignature: Signature? = null
178162

179163
return isOverrideHelper(node) { typechecker, type, nodeName ->

testData/class/override/anyMembers.d.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package anyMembers
22

33
external open class ExpectedOverrides {
4-
override fun equals(a: Any): Unit = definedExternally
5-
override fun hashCode(): Number = definedExternally
4+
override fun equals(a: Any?): Boolean = definedExternally
5+
override fun hashCode(): Int = definedExternally
66
override fun toString(): String = definedExternally
77
}
88
external open class ExpectedOverrides2 {
9-
override fun equals(a: Any): Unit = definedExternally
9+
override fun equals(a: Any?): Boolean = definedExternally
10+
override fun toString(): String = definedExternally
1011
}
1112
external open class ExpectedNoOverrides {
1213
open fun equals(): Unit = definedExternally

testData/class/override/anyMembers.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ declare class ExpectedOverrides {
66

77
declare class ExpectedOverrides2 {
88
equals(a);
9+
toString();
910
}
1011

1112
declare class ExpectedNoOverrides {

testData/interface/override/anyMembers.d.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package anyMembers
22

33
external interface ExpectedOverrides {
4-
override fun equals(a: Any)
5-
override fun hashCode(): Number
4+
override fun equals(a: Any?): Boolean
5+
override fun hashCode(): Int
66
override fun toString(): String
77
}
88
external interface ExpectedOverrides2 {
9-
override fun equals(a: Any)
9+
override fun equals(a: Any?): Boolean
1010
}
1111
external interface ExpectedNoOverrides {
1212
fun equals()

0 commit comments

Comments
 (0)