Skip to content

Commit

Permalink
Fix Invalid type inferring for literal expression
Browse files Browse the repository at this point in the history
  • Loading branch information
SasinduDilshara committed Oct 3, 2022
1 parent c2a4c3b commit d215863
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -534,23 +534,45 @@ private BType getFiniteTypeMatchWithIntLiteral(BLangLiteral literalExpr, BFinite
if (intLiteralType != symTable.noType) {
return intLiteralType;
}

int typeTag = getPreferredMemberTypeTag(finiteType);
if (typeTag == TypeTags.NONE) {
return symTable.intType;
}

if (literalAssignableToFiniteType(literalExpr, finiteType, typeTag)) {
BType type = symTable.getTypeFromTag(typeTag);
setLiteralValueForFiniteType(literalExpr, type, data);
literalExpr.value = String.valueOf(literalValue);
return type;
}

// Handle out of range ints
if (literalValue instanceof Double) {
return symTable.floatType;
}
if (literalValue instanceof String) {
return symTable.decimalType;
}

BType matchingType = null;
for (int tag = TypeTags.FLOAT; tag <= TypeTags.DECIMAL; tag++) {
BType type = symTable.getTypeFromTag(tag);
for (BLangExpression memType : finiteType.getValueSpace()) {
if (memType.getBType().tag == tag) {
matchingType = type;
break;
}
}

if (matchingType != null) {
break;
}
}

if (matchingType != null && matchingType != symTable.semanticError && matchingType != symTable.noType) {
return matchingType;
}
return symTable.intType;
}

Expand Down Expand Up @@ -652,7 +674,36 @@ private BType getIntegerLiteralType(BLangLiteral literalExpr, Object literalValu
}
}

BType finiteType = getFiniteTypeWithValuesOfSingleType(expectedUnionType, symTable.intType);
BType matchingType = null;
for (int tag = TypeTags.FLOAT; tag <= TypeTags.DECIMAL; tag++) {
BType type = symTable.getTypeFromTag(tag);
for (BType memType : ((BUnionType) expectedType).getMemberTypes()) {
if (memType.tag == TypeTags.FINITE) {
for (BLangExpression finiteMemType : ((BFiniteType) memType).getValueSpace()) {
if (finiteMemType.getBType().tag == tag) {
matchingType = type;
break;
}
}
break;
}

if (memType.tag == tag) {
matchingType = type;
break;
}
}

if (matchingType != null) {
break;
}
}

if (matchingType == null || matchingType == symTable.semanticError || matchingType == symTable.noType) {
matchingType = symTable.intType;
}

BType finiteType = getFiniteTypeWithValuesOfSingleType(expectedUnionType, matchingType);
if (finiteType != symTable.semanticError) {
BType setType = setLiteralValueAndGetType(literalExpr, finiteType, data);
if (literalExpr.isFiniteContext) {
Expand Down Expand Up @@ -888,6 +939,27 @@ private BType getTypeMatchingFloatOrDecimal(BType finiteType, List<BType> member
}
}
}

BType matchingType = null;
if (finiteType.tag == TypeTags.FINITE) {
for (int tag = TypeTags.FLOAT; tag <= TypeTags.DECIMAL; tag++) {
BType type = symTable.getTypeFromTag(tag);
for (BLangExpression memType : ((BFiniteType) finiteType).getValueSpace()) {
if (memType.getBType().tag == tag) {
matchingType = type;
break;
}
}

if (matchingType != null) {
break;
}
}
}

if (matchingType != null && matchingType != symTable.semanticError && matchingType != symTable.noType) {
return matchingType;
}
return symTable.intType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void testSubtractStmtNegativeCases() {
BAssertUtil.validateError(resultNegative, index++, "operator '>=' not defined for " +
"'NumberSet[]' and 'NumberSet[]'", 158, 18);
BAssertUtil.validateError(resultNegative, index++, "incompatible types: expected 'OneOrTwo', found " +
"'int'", 167, 21);
"'float'", 168, 21);
BAssertUtil.validateError(resultNegative, index++, "operator '<' not defined for 'OneOrTwo[]' and " +
"'OneOrTwo[]'", 169, 18);
BAssertUtil.validateError(resultNegative, index++, "operator '<=' not defined for 'OneOrTwo[]' and " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ public void testFiniteTypeWithConstants() {
public void testFiniteTypeWithNumericConstants() {
Object val = BRunUtil.invoke(result, "testFiniteTypeWithNumericConstants");
BArray returns = (BArray) val;
Assert.assertTrue(returns.get(0) instanceof Long, "Type mismatch");
Assert.assertEquals(returns.get(0), 5L, "Value mismatch");
Assert.assertTrue(returns.get(0) instanceof Double, "Type mismatch");
Assert.assertEquals(returns.get(0), 5.0, "Value mismatch");
Assert.assertTrue(returns.get(1) instanceof Double, "Type mismatch");
Assert.assertEquals(returns.get(1), 5.0, "Value mismatch");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,28 @@ public void testAssignmentNegativeCases() {
"found 'table<record {| |}>'", 138, 11);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'int', " +
"found 'table<record {| |}>'", 141, 12);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo', " +
"found 'float'", 147, 13);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo2', " +
"found 'float'", 154, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo2', " +
"found 'float'", 157, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo2', " +
"found 'float'", 158, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo2', " +
"found 'float'", 159, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo2', " +
"found 'float'", 160, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo3', " +
"found 'float'", 166, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo3', " +
"found 'float'", 169, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo3', " +
"found 'float'", 170, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo3', " +
"found 'float'", 171, 14);
BAssertUtil.validateError(resultNegative, i++, "incompatible types: expected 'Foo3', " +
"found 'float'", 172, 14);
Assert.assertEquals(resultNegative.getErrorCount(), i);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,6 @@ public Object[] finiteTypeAsBroaderTypesAndFiniteTypeFunctions() {
"testFiniteTypeInUnionAsComplexFiniteTypes_4",
"testFiniteTypeInUnionAsComplexFiniteTypes_5",
"testFiniteTypeInUnionAsComplexFiniteTypes_6",
"testFiniteTypeInUnionAsComplexFiniteTypes_7",
"testFiniteTypeAsFiniteTypeWithIntersectionPositive",
"testFiniteTypeAsBroaderTypeInStructurePositive"
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,19 @@ public void testInvalidLiteralAssignment() {
102, 13);
validateError(resultNegativeTwo, i++, "incompatible types: expected '(t|t2)', found 'decimal'",
107, 14);
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Foo', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Foo', found 'float'",
116, 14);
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Foo2', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Foo2', found 'decimal'",
117, 15);
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Foo4', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Foo4', found 'float'",
118, 15);
validateError(resultNegativeTwo, i++, "incompatible types: expected '\"chiran\"', found 'int'",
119, 18);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'float'",
123, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.0f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.0f', found 'float'",
124, 13);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.121f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.121f', found 'float'",
125, 15);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2e12f', found 'float'",
126, 16);
Expand All @@ -104,7 +104,7 @@ public void testInvalidLiteralAssignment() {
128, 18);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2e12f', found 'decimal'",
129, 16);
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'decimal'",
131, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2d', found 'float'",
132, 14);
Expand All @@ -118,17 +118,17 @@ public void testInvalidLiteralAssignment() {
139, 22);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2e12f', found 'decimal'",
140, 20);
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'decimal'",
142, 16);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2d', found 'float'",
143, 18);
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Float1', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected 'Float1', found 'float'",
148, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'float'",
150, 8);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.0f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.0f', found 'float'",
151, 9);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.121f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.121f', found 'float'",
152, 11);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2e12f', found 'float'",
153, 12);
Expand All @@ -138,7 +138,7 @@ public void testInvalidLiteralAssignment() {
155, 14);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2e12f', found 'decimal'",
156, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'decimal'",
158, 8);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1.2d', found 'float'",
159, 10);
Expand All @@ -148,19 +148,19 @@ public void testInvalidLiteralAssignment() {
"found 'decimal'", 161, 15);
validateError(resultNegativeTwo, i++, "incompatible types: expected '12.1d', found 'float'",
162, 11);
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'decimal'",
165, 9);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'float'",
165, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '0.1219e-1f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '0.1219e-1f', found 'float'",
166, 9);
validateError(resultNegativeTwo, i++, "incompatible types: expected '0x.12p12f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '0x.12p12f', found 'float'",
166, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found '1f'",
178, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '3f', found '2d'",
179, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'int'",
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'float'",
183, 12);
validateError(resultNegativeTwo, i++, "incompatible types: expected '2d', found 'string'",
187, 12);
Expand Down Expand Up @@ -242,7 +242,7 @@ public void testInvalidLiteralAssignment() {
290, 20);
validateError(resultNegativeTwo, i++, "incompatible types: expected '1f', found 'float'",
296, 12);
validateError(resultNegativeTwo, i, "incompatible types: expected '1f', found 'int'",
validateError(resultNegativeTwo, i, "incompatible types: expected '1f', found 'float'",
297, 12);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ public void testFiniteTypeWithConstants() {
@Test
public void testFiniteTypeWithNumericConstants() {
BArray returns = (BArray) BRunUtil.invoke(result, "testFiniteTypeWithNumericConstants");
Assert.assertTrue(returns.get(0) instanceof Long, "Type mismatch");
Assert.assertEquals(returns.get(0), 5L, "Value mismatch");
Assert.assertTrue(returns.get(0) instanceof Double, "Type mismatch");
Assert.assertEquals(returns.get(0), 5.0d, "Value mismatch");
Assert.assertTrue(returns.get(1) instanceof Double, "Type mismatch");
Assert.assertEquals(returns.get(1), 5.0d, "Value mismatch");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function testIntLiteralAsFloatInUnion() returns boolean {
boolean result = x is float && f == x;

Qux|float y = 12;
return result && y is float && f == y;
return result && y is decimal && d == y;
}

function testIntLiteralAsFloatInUnion_2() returns boolean {
Expand Down Expand Up @@ -134,7 +134,7 @@ function testIntLiteralAsIntViaFiniteType() returns boolean {
boolean result = y is int && i == y;

float|Foo|Bar z = 12;
return result && z is int && i == z;
return result && z is float && f == z;
}

function testIntLiteralAsByteViaFiniteType() returns boolean {
Expand All @@ -152,7 +152,7 @@ function testIntLiteralAsFloatViaFiniteType() returns boolean {
boolean result = y is float && f == y;

decimal|Bar|Qux z = 12;
return result && z is float && f == z;
return result && z is decimal && d == z;
}

function testIntLiteralAsDecimalViaFiniteType() returns boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,34 @@ function assignTableCtrToIncompatibleType() {
[int, string] a = [1, "a"];
a[0] = table[]; // error
}

type Foo decimal|2f;

function assignCustomTypeToFloat() {
Foo _ = 3; // error: incompatible types: expected 'Foo', found 'float'
Foo _ = 2;
}

type Foo2 decimal|3d|1|5d|3f|4d|2f|7d|6;

function assignCustomTypeToFloat2() {
Foo2 _ = 1; // error: incompatible types: expected 'Foo2', found 'float'
Foo2 _ = 2;
Foo2 _ = 3;
Foo2 _ = 4; // error: incompatible types: expected 'Foo2', found 'float'
Foo2 _ = 5; // error: incompatible types: expected 'Foo2', found 'float'
Foo2 _ = 6; // error: incompatible types: expected 'Foo2', found 'float'
Foo2 _ = 7; // error: incompatible types: expected 'Foo2', found 'float'
}

type Foo3 decimal|1|5d|3f|4d|2f|7d|6;

function assignCustomTypeToFloat3() {
Foo3 _ = 1; // error: incompatible types: expected 'Foo3', found 'float'
Foo3 _ = 2;
Foo3 _ = 3;
Foo3 _ = 4; // error: incompatible types: expected 'Foo3', found 'float'
Foo3 _ = 5; // error: incompatible types: expected 'Foo3', found 'float'
Foo3 _ = 6; // error: incompatible types: expected 'Foo3', found 'float'
Foo3 _ = 7; // error: incompatible types: expected 'Foo3', found 'float'
}
Original file line number Diff line number Diff line change
Expand Up @@ -668,18 +668,12 @@ function testFiniteTypeInUnionAsComplexFiniteTypes_4() returns boolean {
}

function testFiniteTypeInUnionAsComplexFiniteTypes_5() returns boolean {
FooBarOneTwoBoolean f = 1;
[string, FooBarInt|OneTwo|boolean] [s, v] = finiteTypeAsComplexFiniteTypesHelperTwo(f);
return s == "FooBarInt" && f == v;
}

function testFiniteTypeInUnionAsComplexFiniteTypes_6() returns boolean {
FooBarOneTwoBoolean f = 2.0;
[string, FooBarInt|OneTwo|boolean] [s, v] = finiteTypeAsComplexFiniteTypesHelperTwo(f);
return s == "OneTwo" && f == v;
}

function testFiniteTypeInUnionAsComplexFiniteTypes_7() returns boolean {
function testFiniteTypeInUnionAsComplexFiniteTypes_6() returns boolean {
FooBarOneTwoBoolean f = false;
[string, FooBarInt|OneTwo|boolean] [s, v] = finiteTypeAsComplexFiniteTypesHelperTwo(f);
return s == "boolean" && f == v;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ const decimal DCONST = 5;
type Number DCONST|FCONST|ICONST|BCONST;

function testFiniteTypeWithNumericConstants() returns [Number, Number] {
Number n1 = 5;
Number n1 = 5.0;
Number n2 = 5.0;
return [n1, n2];
}
Expand Down

0 comments on commit d215863

Please sign in to comment.