@@ -3,14 +3,13 @@ package org.jetbrains.dukat.model.commonLowerings
3
3
import org.jetbrains.dukat.astCommon.IdentifierEntity
4
4
import org.jetbrains.dukat.astCommon.NameEntity
5
5
import org.jetbrains.dukat.astCommon.rightMost
6
+ import org.jetbrains.dukat.astModel.ClassLikeModel
6
7
import org.jetbrains.dukat.astModel.ClassModel
7
8
import org.jetbrains.dukat.astModel.FunctionModel
8
9
import org.jetbrains.dukat.astModel.InterfaceModel
9
10
import org.jetbrains.dukat.astModel.MemberModel
10
11
import org.jetbrains.dukat.astModel.MethodModel
11
12
import org.jetbrains.dukat.astModel.ModuleModel
12
- import org.jetbrains.dukat.astModel.ParameterModel
13
- import org.jetbrains.dukat.astModel.TopLevelModel
14
13
import org.jetbrains.dukat.astModel.TypeModel
15
14
import org.jetbrains.dukat.astModel.TypeValueModel
16
15
import org.jetbrains.dukat.ownerContext.NodeOwner
@@ -22,54 +21,35 @@ private fun TypeModel.withoutMeta(): TypeModel {
22
21
}
23
22
}
24
23
25
- private fun ParameterModel.withoutMeta (): ParameterModel {
26
- return copy(type = type.withoutMeta())
27
- }
28
-
29
- private fun MemberModel.normalize (): MemberModel {
30
- return when (this ) {
31
- is MethodModel -> copy(
32
- parameters = parameters.map { it.withoutMeta() },
33
- override = null
34
- )
35
- else -> this
36
- }
37
- }
38
-
39
- private fun filterOutConflictingOverloads (members : List <MemberModel >): List <MemberModel > {
40
- return members.groupBy { it.normalize() }.map { (_, bucketMembers) ->
41
- if (bucketMembers.size > 1 ) {
42
- bucketMembers.first().normalize()
43
- } else {
44
- bucketMembers.first()
45
- }
46
- }
47
- }
48
-
49
24
private class ConflictingOverloads : TopLevelModelLowering {
50
-
51
25
override fun lowerInterfaceModel (ownerContext : NodeOwner <InterfaceModel >, parentModule : ModuleModel ): InterfaceModel ? {
52
- val node = ownerContext.node.copy(members = filterOutConflictingOverloads( ownerContext.node.members ))
26
+ val node = ownerContext.node.copy(members = ownerContext.node.resolveMembers( ))
53
27
return super .lowerInterfaceModel(ownerContext.copy(node = node), parentModule)
54
28
}
55
29
56
30
override fun lowerClassModel (ownerContext : NodeOwner <ClassModel >, parentModule : ModuleModel ): ClassModel ? {
57
- val node = ownerContext.node.copy(members = filterOutConflictingOverloads( ownerContext.node.members ))
31
+ val node = ownerContext.node.copy(members = ownerContext.node.resolveMembers( ))
58
32
return super .lowerClassModel(ownerContext.copy(node = node), parentModule)
59
33
}
60
34
}
61
35
62
36
private fun mergeTypeModels (a : TypeModel , b : TypeModel ): TypeModel {
63
37
return if ((a is TypeValueModel ) && (b is TypeValueModel )) {
64
- a.copy(metaDescription = listOfNotNull(a.metaDescription, b.metaDescription).joinToString(" | " ))
38
+ val metaDescription = listOfNotNull(a.metaDescription, b.metaDescription).distinct().let {
39
+ if (it.isEmpty()) {
40
+ null
41
+ } else {
42
+ it.joinToString(" | " )
43
+ }
44
+ }
45
+ a.copy(metaDescription = metaDescription)
65
46
} else {
66
47
a
67
48
}
68
49
}
69
50
70
51
private fun mergeTypeModelsAsReturn (a : TypeModel , b : TypeModel ): TypeModel {
71
52
return if ((a is TypeValueModel ) && (b is TypeValueModel )) {
72
- a.copy(metaDescription = listOfNotNull(a.metaDescription, b.metaDescription).joinToString(" | " ))
73
53
if (a.withoutMeta() == b.withoutMeta()) {
74
54
mergeTypeModels(a, b)
75
55
} else {
@@ -80,6 +60,13 @@ private fun mergeTypeModelsAsReturn(a: TypeModel, b: TypeModel): TypeModel {
80
60
}
81
61
}
82
62
63
+ private fun mergeMethodModels (a : MethodModel , b : MethodModel ): MethodModel {
64
+ val paramsMerged = a.parameters.zip(b.parameters).map { (paramA, paramB) ->
65
+ paramA.copy(type = mergeTypeModels(paramA.type, paramB.type))
66
+ }
67
+
68
+ return a.copy(parameters = paramsMerged, type = mergeTypeModelsAsReturn(a.type, b.type))
69
+ }
83
70
84
71
private fun mergeFunctionModels (a : FunctionModel , b : FunctionModel ): FunctionModel {
85
72
val paramsMerged = a.parameters.zip(b.parameters).map { (paramA, paramB) ->
@@ -89,21 +76,44 @@ private fun mergeFunctionModels(a: FunctionModel, b: FunctionModel): FunctionMod
89
76
return a.copy(parameters = paramsMerged, type = mergeTypeModelsAsReturn(a.type, b.type))
90
77
}
91
78
92
- typealias FunctionModelKey = Triple <NameEntity , List <TypeModel >, List <TypeModel >>
79
+ typealias CallableKey = Triple <NameEntity , List <TypeModel >, List <TypeModel >>
80
+
81
+ private fun ClassLikeModel.resolveMembers (): List <MemberModel > {
82
+ val keyCache = mutableMapOf<MethodModel , CallableKey >()
83
+
84
+ val methodsBucket = members.filterIsInstance(MethodModel ::class .java).groupBy { methodModel ->
85
+ val key = methodModel.getKey()
86
+ keyCache.put(methodModel, key)
87
+ key
88
+ }.toMutableMap()
89
+
90
+ return members.mapNotNull { memberModel ->
91
+ when (memberModel) {
92
+ is MethodModel -> {
93
+ methodsBucket.remove(keyCache[memberModel])?.reduce { a, b -> mergeMethodModels(a, b) }
94
+ }
95
+ else -> memberModel
96
+ }
97
+ }
98
+ }
99
+
100
+ private fun FunctionModel.getKey (): CallableKey {
101
+ return Triple (name, parameters.map { it.type.withoutMeta() }, typeParameters.map { it.type.withoutMeta() })
102
+ }
93
103
94
- private fun FunctionModel .getKey (): FunctionModelKey {
104
+ private fun MethodModel .getKey (): CallableKey {
95
105
return Triple (name, parameters.map { it.type.withoutMeta() }, typeParameters.map { it.type.withoutMeta() })
96
106
}
97
107
98
108
class RemoveConflictingOverloads : ModelLowering {
99
109
override fun lower (module : ModuleModel ): ModuleModel {
100
- val keyCache = mutableMapOf<FunctionModel , FunctionModelKey >()
110
+ val keyCache = mutableMapOf<FunctionModel , CallableKey >()
101
111
102
112
val functionsBucket = module.declarations.filterIsInstance(FunctionModel ::class .java).groupBy { functionModel ->
103
113
val key = functionModel.getKey()
104
114
keyCache.put(functionModel, key)
105
115
key
106
- }.toMutableMap()
116
+ }.toMutableMap()
107
117
108
118
val declarationsResolved = module.declarations.mapNotNull { topLevelModel ->
109
119
when (topLevelModel) {
0 commit comments