@@ -7,6 +7,7 @@ import org.jetbrains.dukat.tsmodel.FunctionDeclaration
7
7
import org.jetbrains.dukat.tsmodel.FunctionOwnerDeclaration
8
8
import org.jetbrains.dukat.tsmodel.IfStatementDeclaration
9
9
import org.jetbrains.dukat.tsmodel.SourceSetDeclaration
10
+ import org.jetbrains.dukat.tsmodel.StatementDeclaration
10
11
import org.jetbrains.dukat.tsmodel.VariableDeclaration
11
12
import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration
12
13
import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration
@@ -15,12 +16,33 @@ import org.jetbrains.dukat.tsmodel.expression.ExpressionDeclaration
15
16
import org.jetbrains.dukat.tsmodel.expression.ParenthesizedExpressionDeclaration
16
17
import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration
17
18
import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration
19
+ import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration
20
+ import org.jetbrains.dukat.tsmodel.types.TypeDeclaration
21
+ import java.util.*
18
22
19
23
private class ProcessNullabilityChecksLowering (private val typeContext : StatementTypeContext ) : DeclarationLowering {
20
24
21
25
private val booleanUnaryOperators = listOf (" !" )
22
26
private val booleanBinaryOperators = listOf (" &&" , " ||" )
23
27
28
+ private var counter = 1 ;
29
+
30
+ private fun generateVariableName (): String {
31
+ return " _vn${counter++ } "
32
+ }
33
+
34
+ private fun createReplacementVariable (expression : ExpressionDeclaration ): VariableDeclaration {
35
+ return VariableDeclaration (
36
+ name = generateVariableName(),
37
+ type = TypeDeclaration (IdentifierEntity (" Any" ), emptyList()),
38
+ modifiers = setOf (),
39
+ initializer = expression,
40
+ definitionsInfo = listOf (),
41
+ uid = " " ,
42
+ explicitlyDeclaredType = false
43
+ )
44
+ }
45
+
24
46
private fun ExpressionDeclaration.convertToNonNullCheck (): ExpressionDeclaration {
25
47
return BinaryExpressionDeclaration (
26
48
left = this ,
@@ -39,13 +61,19 @@ private class ProcessNullabilityChecksLowering(private val typeContext: Statemen
39
61
40
62
private fun processConditionNonNull (condition : ExpressionDeclaration ): ExpressionDeclaration {
41
63
if (! typeContext.hasBooleanType(condition)) {
64
+ if (condition !is IdentifierExpressionDeclaration ) {
65
+ typeContext.addExpressionToReplace(condition)
66
+ }
42
67
return ParenthesizedExpressionDeclaration (condition.convertToNonNullCheck())
43
68
}
44
69
return condition
45
70
}
46
71
47
72
private fun processEqualsNull (condition : UnaryExpressionDeclaration ): ExpressionDeclaration {
48
73
if (! typeContext.hasBooleanType(condition.operand)) {
74
+ if (condition.operand !is IdentifierExpressionDeclaration ) {
75
+ typeContext.addExpressionToReplace(condition.operand)
76
+ }
49
77
return ParenthesizedExpressionDeclaration (condition.operand.convertToEqualsNullCheck())
50
78
}
51
79
return condition
@@ -91,11 +119,31 @@ private class ProcessNullabilityChecksLowering(private val typeContext: Statemen
91
119
)
92
120
}
93
121
94
- override fun lowerBlockStatement ( block : BlockDeclaration ): BlockDeclaration {
122
+ override fun lowerBlock ( statement : BlockDeclaration ): BlockDeclaration {
95
123
typeContext.startScope()
96
- val newBlock = super .lowerBlockStatement(block)
124
+ val newStatements = mutableListOf<StatementDeclaration >()
125
+ var statementsToProcess = ArrayDeque (statement.statements)
126
+ while (statementsToProcess.isNotEmpty()) {
127
+ val nextStatement = super .lower(statementsToProcess.removeFirst())
128
+ val expressionsToReplace = typeContext.getRelevantExpressionsToReplace()
129
+ if (expressionsToReplace.isNotEmpty()) {
130
+ val replacementVariables = expressionsToReplace.map { createReplacementVariable(it) }
131
+ val replacementLowering = ReplaceExpressionsLowering (
132
+ replacementVariables.map { variable ->
133
+ variable.initializer!! to IdentifierExpressionDeclaration (IdentifierEntity (variable.name))
134
+ }.toMap()
135
+ )
136
+
137
+ statementsToProcess = ArrayDeque (statementsToProcess.map {
138
+ replacementLowering.lower(it)
139
+ })
140
+ newStatements + = replacementVariables + replacementLowering.lower(nextStatement)
141
+ } else {
142
+ newStatements + = nextStatement
143
+ }
144
+ }
97
145
typeContext.endScope()
98
- return newBlock
146
+ return BlockDeclaration (newStatements)
99
147
}
100
148
101
149
override fun lowerVariableDeclaration (declaration : VariableDeclaration ): VariableDeclaration {
0 commit comments