Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Master] Fix Invalid type inferring for literal expression #38029

Merged
merged 20 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
510c79e
Fix Invalid type inferring for literal expression
SasinduDilshara Oct 1, 2022
add240e
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Oct 18, 2022
7780a3e
Fix invalid types referring for numeric literals
SasinduDilshara Nov 1, 2022
989da17
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Jan 11, 2023
c9505a5
Update silentCompatibleLiteralTypeCheck method
SasinduDilshara Jan 11, 2023
435276d
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Mar 14, 2023
3d73e9f
Update unit tests in BFloatValue unit tests
SasinduDilshara Mar 15, 2023
6bd984d
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara May 23, 2023
a6f7948
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Jun 15, 2023
3006b46
Update getTypeOfDecimalFloatingPointLiteral method
SasinduDilshara Jul 6, 2023
b784458
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Jul 6, 2023
851e920
Update type checker for finite int value space
SasinduDilshara Jul 10, 2023
0feac9c
Merge branch 'issue-37750' of https://github.com/SasinduDilshara/ball…
SasinduDilshara Jul 10, 2023
2d6ed67
Remove unnecessary tests in symbol exposure tests
SasinduDilshara Jul 11, 2023
ed6afec
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Aug 9, 2023
7860a45
Merge branch 'issue-37750' of https://github.com/SasinduDilshara/ball…
SasinduDilshara Aug 9, 2023
6688034
Add tests for byte type with int literals
SasinduDilshara Aug 9, 2023
fcd9a03
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Aug 15, 2023
85bec8e
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Aug 17, 2023
e57a4ab
Merge branch 'master' of https://github.com/ballerina-platform/baller…
SasinduDilshara Aug 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,13 @@
}

private int getPreferredMemberTypeTag(BFiniteType finiteType) {
for (BLangExpression valueExpr : finiteType.getValueSpace()) {
int typeTag = Types.getImpliedType(valueExpr.getBType()).tag;
if (typeTag > TypeTags.DECIMAL) {
continue;
}
for (int i = TypeTags.INT; i <= TypeTags.DECIMAL; i++) {
for (int i = TypeTags.INT; i <= TypeTags.DECIMAL; i++) {
for (BLangExpression valueExpr : finiteType.getValueSpace()) {
int typeTag = Types.getImpliedType(valueExpr.getBType()).tag;
if (typeTag > TypeTags.DECIMAL) {
continue;
}

if (typeTag == i) {
return i;
}
Expand Down Expand Up @@ -535,29 +536,35 @@
}

private BType getFiniteTypeMatchWithIntLiteral(BLangLiteral literalExpr, BFiniteType finiteType,
Object literalValue, AnalyzerData data) {
Object literalValue, BType compatibleType, AnalyzerData data) {
BType intLiteralType = getFiniteTypeMatchWithIntType(literalExpr, finiteType, data);
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;
}
return symTable.intType;
if (compatibleType.tag == TypeTags.BYTE) {
return symTable.intType;

Check warning on line 565 in compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java

View check run for this annotation

Codecov / codecov/patch

compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java#L565

Added line #L565 was not covered by tests
SasinduDilshara marked this conversation as resolved.
Show resolved Hide resolved
}
return compatibleType;
}

private BType silentIntTypeCheck(BLangLiteral literalExpr, Object literalValue, BType expType,
Expand All @@ -580,15 +587,23 @@
}

private BType silentCompatibleLiteralTypeCheck(BFiniteType finiteType, BLangLiteral literalExpr,
Object literalValue, AnalyzerData data) {
BType resIntType = symTable.semanticError;
Object literalValue, AnalyzerData data) {
BType resIntegerLiteralType = symTable.semanticError;
List<BType> compatibleTypes = new ArrayList<>();
for (BLangExpression valueExpr : finiteType.getValueSpace()) {
resIntType = silentIntTypeCheck(literalExpr, literalValue, valueExpr.getBType(), data);
if (resIntType != symTable.semanticError) {
return resIntType;
resIntegerLiteralType = silentIntTypeCheck(literalExpr, literalValue, valueExpr.getBType(), data);
if (resIntegerLiteralType != symTable.semanticError) {
compatibleTypes.add(resIntegerLiteralType);
}
}
return resIntType;
for (int i = TypeTags.INT; i <= TypeTags.DECIMAL; i++) {
for (BType type: compatibleTypes) {
if (Types.getReferredType(type).tag == i) {
return type;
}
}
}
return resIntegerLiteralType;
}

private BType checkIfOutOfRangeAndReturnType(BFiniteType finiteType, BLangLiteral literalExpr, Object literalValue,
Expand Down Expand Up @@ -633,7 +648,7 @@
if (compatibleType == symTable.semanticError) {
return compatibleType;
} else {
return getFiniteTypeMatchWithIntLiteral(literalExpr, finiteType, literalValue, data);
return getFiniteTypeMatchWithIntLiteral(literalExpr, finiteType, literalValue, compatibleType, data);
}
} else if (expectedType.tag == TypeTags.UNION) {
BUnionType expectedUnionType = (BUnionType) expectedType;
Expand Down Expand Up @@ -749,12 +764,29 @@
} else if (expectedType.tag == TypeTags.FINITE) {
BFiniteType finiteType = (BFiniteType) expectedType;
for (int tag = TypeTags.FLOAT; tag <= TypeTags.DECIMAL; tag++) {
if (literalAssignableToFiniteType(literalExpr, finiteType, tag)) {
BType valueType = setLiteralValueAndGetType(literalExpr, symTable.getTypeFromTag(tag), data);
setLiteralValueForFiniteType(literalExpr, valueType, data);
return valueType;
BType literalValueType = null;
for (BLangExpression valueExpr : finiteType.getValueSpace()) {
if (valueExpr.getBType().tag == tag) {
if (types.checkLiteralAssignabilityBasedOnType((BLangLiteral) valueExpr, literalExpr)) {
BType valueType = setLiteralValueAndGetType(literalExpr,
symTable.getTypeFromTag(tag), data);
setLiteralValueForFiniteType(literalExpr, valueType, data);
return valueType;
}
literalValueType = valueExpr.getBType();
}
}
if (literalValueType != null) {
return literalValueType;
}
}
return literalExpr.getBType();
} else if (expectedType.tag == TypeTags.FLOAT) {
if (!types.validateFloatLiteral(literalExpr.pos, numericLiteral)) {
data.resultType = symTable.semanticError;
return symTable.semanticError;

Check warning on line 787 in compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java

View check run for this annotation

Codecov / codecov/patch

compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java#L786-L787

Added lines #L786 - L787 were not covered by tests
}
return symTable.floatType;

Check warning on line 789 in compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java

View check run for this annotation

Codecov / codecov/patch

compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java#L789

Added line #L789 was not covered by tests
} else if (expectedType.tag == TypeTags.UNION) {
BUnionType unionType = (BUnionType) expectedType;
for (int tag = TypeTags.FLOAT; tag <= TypeTags.DECIMAL; tag++) {
Expand Down Expand Up @@ -913,6 +945,9 @@
}
}
}
if (finiteType.tag == TypeTags.FINITE) {
return checkIfOutOfRangeAndReturnType((BFiniteType) finiteType, literalExpr, literalExpr.value, data);
}
return symTable.intType;
}

Expand All @@ -934,7 +969,7 @@
BType finiteType = getFiniteTypeWithValuesOfSingleType(expType, desiredType);
if (finiteType != symTable.semanticError) {
BType setType = setLiteralValueAndGetType(literalExpr, finiteType, data);
if (literalExpr.isFiniteContext) {
if (setType != symTable.semanticError) {
// i.e., a match was found for a finite type
return setType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public void testNegative() {
BAssertUtil.validateError(compileResult, i++, "incompatible types: expected 'FloatTypeWithoutType'," +
" found 'float'", offset += 7, 30);
BAssertUtil.validateError(compileResult, i++, "incompatible types: expected 'DecimalTypeWithType'," +
" found 'float'", offset += 9, 29);
" found 'decimal'", offset += 9, 29);
BAssertUtil.validateError(compileResult, i++, "incompatible types: expected 'StringTypeWithType'," +
" found 'string'", offset += 9, 28);
BAssertUtil.validateError(compileResult, i++, "incompatible types: expected 'StringTypeWithoutType'," +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2023, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.ballerinalang.test.bala.literals;

import org.ballerinalang.test.BAssertUtil;
import org.ballerinalang.test.BCompileUtil;
import org.ballerinalang.test.CompileResult;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

/**
* Negative test cases for numeric literals in ballerina.
*/
public class NumericLiteralNegativeTest {
private CompileResult negativeResult;

@BeforeClass
public void setup() {
BCompileUtil.compileAndCacheBala("test-src/bala/test_projects/test_numeric_literals");
negativeResult = BCompileUtil
.compile("test-src/bala/test_bala/literals/test_numeric_literal_negative_test.bal");
}

@Test(description = "Test numeric literal assignment statement with errors")
public void testNumericLiteralAssignmentNegativeCases() {
int index = 0;
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo', found 'float'", 20, 21);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo', found 'float'", 23, 21);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo', found 'float'", 24, 21);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo', found 'float'", 26, 21);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo2', found 'int'", 30, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo2', found 'int'", 31, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo2', found 'int'", 32, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo2', found 'int'", 33, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo2', found 'int'", 35, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo2', found 'float'", 36, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo3', found 'float'", 39, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo3', found 'float'", 40, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo3', found 'float'", 41, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo3', found 'float'", 42, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'int'", 50, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 51, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 52, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 53, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 54, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 56, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'int'", 59, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 60, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 61, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 64, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'int'", 67, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 68, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 69, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 72, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'int'", 75, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 76, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 77, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 78, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 80, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 85, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 86, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 88, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 89, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 90, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'float'", 92, 22);
BAssertUtil.validateError(negativeResult, index++, "incompatible types: expected " +
"'numericliteral/testproject:0.1.0:Foo5', found 'int'", 93, 22);
Assert.assertEquals(negativeResult.getErrorCount(), index);
}
}
Loading
Loading