@@ -7,6 +7,7 @@ import org.jetbrains.dukat.tsmodel.FunctionDeclaration
77import org.jetbrains.dukat.tsmodel.FunctionOwnerDeclaration
88import org.jetbrains.dukat.tsmodel.IfStatementDeclaration
99import org.jetbrains.dukat.tsmodel.SourceSetDeclaration
10+ import org.jetbrains.dukat.tsmodel.StatementDeclaration
1011import org.jetbrains.dukat.tsmodel.VariableDeclaration
1112import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration
1213import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration
@@ -15,12 +16,33 @@ import org.jetbrains.dukat.tsmodel.expression.ExpressionDeclaration
1516import org.jetbrains.dukat.tsmodel.expression.ParenthesizedExpressionDeclaration
1617import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration
1718import 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.*
1822
1923private class ProcessNullabilityChecksLowering (private val typeContext : StatementTypeContext ) : DeclarationLowering {
2024
2125 private val booleanUnaryOperators = listOf (" !" )
2226 private val booleanBinaryOperators = listOf (" &&" , " ||" )
2327
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+
2446 private fun ExpressionDeclaration.convertToNonNullCheck (): ExpressionDeclaration {
2547 return BinaryExpressionDeclaration (
2648 left = this ,
@@ -39,13 +61,19 @@ private class ProcessNullabilityChecksLowering(private val typeContext: Statemen
3961
4062 private fun processConditionNonNull (condition : ExpressionDeclaration ): ExpressionDeclaration {
4163 if (! typeContext.hasBooleanType(condition)) {
64+ if (condition !is IdentifierExpressionDeclaration ) {
65+ typeContext.addExpressionToReplace(condition)
66+ }
4267 return ParenthesizedExpressionDeclaration (condition.convertToNonNullCheck())
4368 }
4469 return condition
4570 }
4671
4772 private fun processEqualsNull (condition : UnaryExpressionDeclaration ): ExpressionDeclaration {
4873 if (! typeContext.hasBooleanType(condition.operand)) {
74+ if (condition.operand !is IdentifierExpressionDeclaration ) {
75+ typeContext.addExpressionToReplace(condition.operand)
76+ }
4977 return ParenthesizedExpressionDeclaration (condition.operand.convertToEqualsNullCheck())
5078 }
5179 return condition
@@ -91,11 +119,31 @@ private class ProcessNullabilityChecksLowering(private val typeContext: Statemen
91119 )
92120 }
93121
94- override fun lowerBlockStatement ( block : BlockDeclaration ): BlockDeclaration {
122+ override fun lowerBlock ( statement : BlockDeclaration ): BlockDeclaration {
95123 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+ }
97145 typeContext.endScope()
98- return newBlock
146+ return BlockDeclaration (newStatements)
99147 }
100148
101149 override fun lowerVariableDeclaration (declaration : VariableDeclaration ): VariableDeclaration {
0 commit comments