Validate the child expressions and operator are valid
(fieldTypeDescriptor FieldTypeDescriptor)
| 541 | |
| 542 | // Validate the child expressions and operator are valid |
| 543 | func (binaryExpression *BinaryExpression) Validate(fieldTypeDescriptor FieldTypeDescriptor) (errors []error) { |
| 544 | if !binaryExpression.IsComparison() { |
| 545 | if logicalExpression, ok := binaryExpression.lhs.(LogicalExpression); !ok { |
| 546 | errors = append(errors, GenerateExpressionError(binaryExpression, "Operands of a logical operator must resolve to boolean values")) |
| 547 | } else { |
| 548 | errors = append(errors, logicalExpression.Validate(fieldTypeDescriptor)...) |
| 549 | } |
| 550 | |
| 551 | if logicalExpression, ok := binaryExpression.rhs.(LogicalExpression); !ok { |
| 552 | errors = append(errors, GenerateExpressionError(binaryExpression, "Operands of a logical operator must resolve to boolean values")) |
| 553 | } else { |
| 554 | errors = append(errors, logicalExpression.Validate(fieldTypeDescriptor)...) |
| 555 | } |
| 556 | |
| 557 | return |
| 558 | } |
| 559 | |
| 560 | if validatableExpression, ok := binaryExpression.lhs.(ValidatableExpression); ok { |
| 561 | errors = append(errors, validatableExpression.Validate(fieldTypeDescriptor)...) |
| 562 | } |
| 563 | |
| 564 | if validatableExpression, ok := binaryExpression.rhs.(ValidatableExpression); ok { |
| 565 | errors = append(errors, validatableExpression.Validate(fieldTypeDescriptor)...) |
| 566 | } |
| 567 | |
| 568 | lhsType, isLHSValueType := determineFieldType(binaryExpression.lhs, fieldTypeDescriptor) |
| 569 | rhsType, isRHSValueType := determineFieldType(binaryExpression.rhs, fieldTypeDescriptor) |
| 570 | |
| 571 | if !(isLHSValueType && isRHSValueType) { |
| 572 | errors = append(errors, GenerateExpressionError(binaryExpression, "Comparison expressions must compare value types")) |
| 573 | } else if binaryExpression.operator.isOperandTypeRestricted() { |
| 574 | if !(lhsType == FtInvalid || rhsType == FtInvalid) { |
| 575 | if !binaryExpression.operator.isValidArgument(bopLeft, lhsType) { |
| 576 | errors = append(errors, GenerateExpressionError(binaryExpression, "Argument on LHS has invalid type: %v. Allowed types are: %v", |
| 577 | fieldTypeNames[lhsType], fieldTypeNamesString(binaryExpression.operator.allowedTypes(bopLeft)))) |
| 578 | } |
| 579 | |
| 580 | if !binaryExpression.operator.isValidArgument(bopRight, rhsType) { |
| 581 | errors = append(errors, GenerateExpressionError(binaryExpression, "Argument on RHS has invalid type: %v. Allowed types are: %v", |
| 582 | fieldTypeNames[rhsType], fieldTypeNamesString(binaryExpression.operator.allowedTypes(bopRight)))) |
| 583 | } |
| 584 | } |
| 585 | } else if lhsType != rhsType && !(lhsType == FtInvalid || rhsType == FtInvalid) { |
| 586 | errors = append(errors, GenerateExpressionError(binaryExpression, "Attempting to compare different types - LHS Type: %v vs RHS Type: %v", |
| 587 | fieldTypeNames[lhsType], fieldTypeNames[rhsType])) |
| 588 | } |
| 589 | |
| 590 | return |
| 591 | } |
| 592 | |
| 593 | func determineFieldType(expression Expression, fieldTypeDescriptor FieldTypeDescriptor) (fieldType FieldType, isValueType bool) { |
| 594 | if typeDescriptor, ok := expression.(TypeDescriptor); ok { |
nothing calls this directly
no test coverage detected