Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
To be more robust and keep a logic in our code, split the type `Number`. This change imply to correct lot of tests to consider the new types. However, the production code was not a big change. This commit does the following: * Correct antlr definition to identify both integers and numbers * Create type `IntegerValue` to recognize an integer instead of a number * Rename controls `CalculatorOperandsAreNumber` and `OrderOperandsAreNumber` to be more expressive * Calculator and orders must be on the same numeric type to avoid risks in target languages * Correct tests to use the right numeric type when there was a confusion between the two * Add test ensuring that the same numeric type is used in calculator and order expressions
- Loading branch information
Gaëtan Rizio
committed
Aug 11, 2018
1 parent
f205a7b
commit f3e2435
Showing
51 changed files
with
366 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 0 additions & 40 deletions
40
src/main/scala/definiti/core/validation/controls/CalculatorOperandsAreNumberControl.scala
This file was deleted.
Oops, something went wrong.
56 changes: 56 additions & 0 deletions
56
...ain/scala/definiti/core/validation/controls/CalculatorOperandsAreSameNumericControl.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package definiti.core.validation.controls | ||
|
||
import definiti.common.ast._ | ||
import definiti.common.control.{Control, ControlLevel, ControlResult} | ||
import definiti.common.validation.Alert | ||
import definiti.core.validation.helpers.{ExpressionControlHelper, TypeReferenceControlHelper} | ||
|
||
private[core] object CalculatorOperandsAreSameNumericControl extends Control[Root] with ExpressionControlHelper with TypeReferenceControlHelper { | ||
override val description: String = "Check if all operands of calculator expression are number expressions" | ||
override val defaultLevel: ControlLevel.Value = ControlLevel.error | ||
|
||
override def control(root: Root, library: Library): ControlResult = { | ||
testAllExpressions(library) { expression => | ||
deepControl(expression) { | ||
case calculatorExpression: CalculatorExpression => | ||
controlCalculatorExpression(calculatorExpression, library) | ||
} | ||
} | ||
} | ||
|
||
private def controlCalculatorExpression(expression: CalculatorExpression, library: Library): ControlResult = { | ||
val leftIsNumber = isNumber(expression.left.returnType, library) | ||
val rightIsNumber = isNumber(expression.right.returnType, library) | ||
|
||
val leftIsInteger = isInteger(expression.left.returnType, library) | ||
val rightIsInteger = isInteger(expression.right.returnType, library) | ||
|
||
val leftIsNumeric = leftIsNumber || leftIsInteger | ||
val rightIsNumeric = rightIsNumber || rightIsInteger | ||
|
||
if (leftIsNumeric && rightIsNumeric) { | ||
if (leftIsNumber && rightIsNumber || leftIsInteger && rightIsInteger) { | ||
OK | ||
} else { | ||
ControlResult(differentNumeric(expression.left.returnType, expression.right.returnType, expression.location)) | ||
} | ||
} else if (leftIsNumeric) { | ||
ControlResult(errorNotNumeric(expression.right.returnType, expression.right.location)) | ||
} else if (rightIsNumeric) { | ||
ControlResult(errorNotNumeric(expression.left.returnType, expression.left.location)) | ||
} else { | ||
ControlResult( | ||
errorNotNumeric(expression.left.returnType, expression.left.location), | ||
errorNotNumeric(expression.right.returnType, expression.right.location) | ||
) | ||
} | ||
} | ||
|
||
def errorNotNumeric(returnType: AbstractTypeReference, location: Location): Alert = { | ||
alert(s"Numeric expected, got: ${returnType.readableString}", location) | ||
} | ||
|
||
def differentNumeric(left: AbstractTypeReference, right: AbstractTypeReference, location: Location): Alert = { | ||
alert(s"Numeric types are different: ${left.readableString} and ${right.readableString}", location) | ||
} | ||
} |
47 changes: 0 additions & 47 deletions
47
src/main/scala/definiti/core/validation/controls/OrderOperandsAreNumberControl.scala
This file was deleted.
Oops, something went wrong.
63 changes: 63 additions & 0 deletions
63
src/main/scala/definiti/core/validation/controls/OrderOperandsAreSameNumericControl.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package definiti.core.validation.controls | ||
|
||
import definiti.common.ast._ | ||
import definiti.common.control.{Control, ControlLevel, ControlResult} | ||
import definiti.common.validation.Alert | ||
import definiti.core.validation.helpers.{ExpressionControlHelper, TypeReferenceControlHelper} | ||
|
||
private[core] object OrderOperandsAreSameNumericControl extends Control[Root] with ExpressionControlHelper with TypeReferenceControlHelper { | ||
override val description: String = "Check if all operands of logical expression are number expressions for >, <, >= and <=" | ||
override val defaultLevel: ControlLevel.Value = ControlLevel.error | ||
|
||
override def control(root: Root, library: Library): ControlResult = { | ||
testAllExpressions(library) { expression => | ||
deepControl(expression) { | ||
case logicalExpression: LogicalExpression if shouldBeControlled(logicalExpression) => | ||
controlLogicalExpression(logicalExpression, library) | ||
} | ||
} | ||
} | ||
|
||
private def shouldBeControlled(logicalExpression: LogicalExpression): Boolean = { | ||
logicalExpression.operator == LogicalOperator.Lower || | ||
logicalExpression.operator == LogicalOperator.Upper || | ||
logicalExpression.operator == LogicalOperator.LowerOrEqual || | ||
logicalExpression.operator == LogicalOperator.UpperOrEqual | ||
} | ||
|
||
private def controlLogicalExpression(expression: LogicalExpression, library: Library): ControlResult = { | ||
val leftIsNumber = isNumber(expression.left.returnType, library) | ||
val rightIsNumber = isNumber(expression.right.returnType, library) | ||
|
||
val leftIsInteger = isInteger(expression.left.returnType, library) | ||
val rightIsInteger = isInteger(expression.right.returnType, library) | ||
|
||
val leftIsNumeric = leftIsNumber || leftIsInteger | ||
val rightIsNumeric = rightIsNumber || rightIsInteger | ||
|
||
if (leftIsNumeric && rightIsNumeric) { | ||
if (leftIsNumber && rightIsNumber || leftIsInteger && rightIsInteger) { | ||
OK | ||
} else { | ||
ControlResult(differentNumeric(expression.left.returnType, expression.right.returnType, expression.location)) | ||
} | ||
} else if (leftIsNumeric) { | ||
ControlResult(errorNotNumeric(expression.right.returnType, expression.right.location)) | ||
} else if (rightIsNumeric) { | ||
ControlResult(errorNotNumeric(expression.left.returnType, expression.left.location)) | ||
} else { | ||
ControlResult( | ||
errorNotNumeric(expression.left.returnType, expression.left.location), | ||
errorNotNumeric(expression.right.returnType, expression.right.location) | ||
) | ||
} | ||
} | ||
|
||
def errorNotNumeric(returnType: AbstractTypeReference, location: Location): Alert = { | ||
alert(s"Number expected, got: ${returnType.readableString}", location) | ||
} | ||
|
||
def differentNumeric(left: AbstractTypeReference, right: AbstractTypeReference, location: Location): Alert = { | ||
alert(s"Numeric types are different: ${left.readableString} and ${right.readableString}", location) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
src/test/resources/samples/controls/calculatorOperandsAreSameNumeric/differentNumeric.def
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
def compare(number: Number, integer: Integer): Boolean => { | ||
number / integer | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
Oops, something went wrong.