From 8eed105fc3f6086f17fabcef8ef6f4b08ebac0a6 Mon Sep 17 00:00:00 2001 From: rdulmina Date: Mon, 6 Jan 2025 12:44:51 +0530 Subject: [PATCH 1/5] Add null check before accessing `type.tsymbol` --- .../compiler/semantics/analyzer/CodeAnalyzer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java index a3920e3d2720..5f72c9672acf 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java @@ -2804,7 +2804,8 @@ public void visit(BLangTypeInit cIExpr, AnalyzerData data) { analyzeExprs(cIExpr.argsExpr, data); analyzeExpr(cIExpr.initInvocation, data); BType type = cIExpr.getBType(); - if (cIExpr.userDefinedType != null && Symbols.isFlagOn(type.tsymbol.flags, Flags.DEPRECATED)) { + if (cIExpr.userDefinedType != null && type.tsymbol != null && + Symbols.isFlagOn(type.tsymbol.flags, Flags.DEPRECATED)) { logDeprecatedWaring(((BLangUserDefinedType) cIExpr.userDefinedType).typeName.toString(), type.tsymbol, cIExpr.pos); } From 2558cd69b58e041f03d82c8ee0f4d6714fbe0e82 Mon Sep 17 00:00:00 2001 From: rdulmina Date: Thu, 9 Jan 2025 12:47:11 +0530 Subject: [PATCH 2/5] Revert "Add null check before accessing `type.tsymbol`" This reverts commit 8eed105fc3f6086f17fabcef8ef6f4b08ebac0a6. --- .../compiler/semantics/analyzer/CodeAnalyzer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java index 5f72c9672acf..a3920e3d2720 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java @@ -2804,8 +2804,7 @@ public void visit(BLangTypeInit cIExpr, AnalyzerData data) { analyzeExprs(cIExpr.argsExpr, data); analyzeExpr(cIExpr.initInvocation, data); BType type = cIExpr.getBType(); - if (cIExpr.userDefinedType != null && type.tsymbol != null && - Symbols.isFlagOn(type.tsymbol.flags, Flags.DEPRECATED)) { + if (cIExpr.userDefinedType != null && Symbols.isFlagOn(type.tsymbol.flags, Flags.DEPRECATED)) { logDeprecatedWaring(((BLangUserDefinedType) cIExpr.userDefinedType).typeName.toString(), type.tsymbol, cIExpr.pos); } From 65afcd1c26bb8fd9ad9a30a6492a7e298a390467 Mon Sep 17 00:00:00 2001 From: rdulmina Date: Tue, 21 Jan 2025 12:17:49 +0530 Subject: [PATCH 3/5] Reset `unknownTypeRefs` after silent type checking --- .../semantics/analyzer/SymbolEnter.java | 2 +- .../semantics/analyzer/TypeChecker.java | 86 ++++++++++++------- .../semantics/analyzer/TypeResolver.java | 6 +- .../typedefs/TypeDefinitionsNegativeTest.java | 6 ++ .../type-definitions-semantics-negative.bal | 14 +++ 5 files changed, 78 insertions(+), 36 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java index f09f95cc6040..c8f899bcb53c 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java @@ -488,7 +488,7 @@ private void defineConstructs(BLangPackage pkgNode, SymbolEnv pkgEnv) { } } } - typeResolver.clearUnknowTypeRefs(); + typeResolver.clearUnknownTypeRefs(); } private void defineDependentFields(List typeDefNodes, SymbolEnv pkgEnv) { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java index cef5cdbdf1a3..95fcfa20f7e7 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java @@ -254,6 +254,7 @@ public class TypeChecker extends SimpleBLangNodeAnalyzer key) { @@ -343,6 +345,7 @@ public TypeChecker(CompilerContext context, CompilerContext.Key key this.missingNodesHelper = BLangMissingNodesHelper.getInstance(context); this.unifier = new Unifier(); this.queryTypeChecker = null; + this.typeResolver = TypeResolver.getInstance(context); } private BType checkExpr(BLangExpression expr, SymbolEnv env, AnalyzerData data) { @@ -600,14 +603,13 @@ private BType silentIntTypeCheck(BLangLiteral literalExpr, Object literalValue, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprCompatibleType = getIntegerLiteralType(nodeCloner.cloneNode(literalExpr), literalValue, expType, data); data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - this.dlog.setErrorCount(prevErrorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); @@ -1224,7 +1226,7 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr, AnalyzerData d boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int errorCount = this.dlog.errorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); List matchingTypes = new ArrayList<>(); @@ -1246,7 +1248,7 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr, AnalyzerData d } data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - this.dlog.setErrorCount(errorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -1803,7 +1805,7 @@ private BType checkListConstructorCompatibility(BType referredType, BType origin int tag = referredType.tag; if (tag == TypeTags.UNION) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; - int errorCount = this.dlog.errorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); data.commonAnalyzerData.nonErrorLoggingCheck = true; this.dlog.mute(); @@ -1832,7 +1834,7 @@ private BType checkListConstructorCompatibility(BType referredType, BType origin } data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - this.dlog.setErrorCount(errorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -2545,7 +2547,7 @@ public BType checkMappingConstructorCompatibility(BType bType, BLangRecordLitera if (tag == TypeTags.UNION) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int errorCount = this.dlog.errorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); List compatibleTypes = new ArrayList<>(); @@ -2574,7 +2576,7 @@ public BType checkMappingConstructorCompatibility(BType bType, BLangRecordLitera } data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - dlog.setErrorCount(errorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -3928,13 +3930,13 @@ private void validateErrorConstructorPositionalArgs(BLangErrorConstructorExpr er protected BType checkExprSilent(BLangExpression expr, BType expType, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int errorCount = this.dlog.errorCount(); this.dlog.mute(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); BType type = checkExpr(expr, expType, data); data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - dlog.setErrorCount(errorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -5469,15 +5471,14 @@ public boolean isOptionalFloatOrDecimal(BType expectedType) { private BType checkAndGetType(BLangExpression expr, SymbolEnv env, BLangBinaryExpr binaryExpr, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); expr.cloneAttempt++; BType exprCompatibleType = checkExpr(nodeCloner.cloneNode(expr), env, binaryExpr.expectedType, data); data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; int errorCount = this.dlog.errorCount(); - this.dlog.setErrorCount(prevErrorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -5731,8 +5732,7 @@ public boolean silentCompatibleFiniteMembersInUnionTypeCheck(BLangUnaryExpr unar AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType compatibleTypeOfUnaryExpression; @@ -5740,17 +5740,17 @@ public boolean silentCompatibleFiniteMembersInUnionTypeCheck(BLangUnaryExpr unar compatibleTypeOfUnaryExpression = checkExpr(nodeCloner.cloneNode(unaryExpr), Types.getImpliedType(type), data); if (Types.getImpliedType(compatibleTypeOfUnaryExpression).tag == TypeTags.FINITE) { - unmuteDlog(data, prevNonErrorLoggingCheck, prevErrorCount); + unmuteDlog(data, prevNonErrorLoggingCheck, previousGlobalState); return true; } } - unmuteDlog(data, prevNonErrorLoggingCheck, prevErrorCount); + unmuteDlog(data, prevNonErrorLoggingCheck, previousGlobalState); return false; } - private void unmuteDlog(AnalyzerData data, boolean prevNonErrorLoggingCheck, int prevErrorCount) { + private void unmuteDlog(AnalyzerData data, boolean prevNonErrorLoggingCheck, GlobalStateData previousGlobalState) { data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - this.dlog.setErrorCount(prevErrorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -5759,13 +5759,12 @@ private void unmuteDlog(AnalyzerData data, boolean prevNonErrorLoggingCheck, int public BType silentTypeCheckExpr(BLangExpression expr, BType referredType, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprCompatibleType = checkExpr(nodeCloner.cloneNode(expr), referredType, data); - unmuteDlog(data, prevNonErrorLoggingCheck, prevErrorCount); + unmuteDlog(data, prevNonErrorLoggingCheck, previousGlobalState); return exprCompatibleType; } @@ -5823,14 +5822,13 @@ public void visit(BLangTypeConversionExpr conversionExpr, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprCompatibleType = checkExpr(nodeCloner.cloneNode(expr), targetType, data); data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; int errorCount = this.dlog.errorCount(); - this.dlog.setErrorCount(prevErrorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); @@ -6609,9 +6607,8 @@ private BType getCandidateLaxType(BLangNode expr, BType rhsType) { private BType getCandidateType(BLangCheckedExpr checkedExpr, BType checkExprCandidateType, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); this.dlog.mute(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); checkedExpr.expr.cloneAttempt++; BLangExpression clone = nodeCloner.cloneNode(checkedExpr.expr); @@ -6622,7 +6619,7 @@ private BType getCandidateType(BLangCheckedExpr checkedExpr, BType checkExprCand rhsType = checkExpr(clone, checkExprCandidateType, data); } data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; - this.dlog.setErrorCount(prevErrorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); } @@ -8243,15 +8240,14 @@ private List concatSimilarKindXMLNodes(List ex for (BLangExpression expr : exprs) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - int prevErrorCount = this.dlog.errorCount(); - this.dlog.resetErrorCount(); + GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprType = checkExpr(nodeCloner.cloneNode(expr), xmlElementEnv, symTable.xmlType, data); data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; int errorCount = this.dlog.errorCount(); - this.dlog.setErrorCount(prevErrorCount); + restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { this.dlog.unmute(); @@ -9918,6 +9914,24 @@ String recordsToString(Set recordTypeSet) { } } + public GlobalStateData getGlobalStateSnapshotAndResetGlobalState() { + // Preserve global state + GlobalStateData globalStateData = new GlobalStateData(); + globalStateData.unknownTypeRefs = typeResolver.unknownTypeRefs; + globalStateData.errorCount = this.dlog.errorCount(); + + // Reset global state + typeResolver.unknownTypeRefs = new HashSet<>(); + this.dlog.resetErrorCount(); + + return globalStateData; + } + + public void restoreGlobalState(GlobalStateData globalStateData) { + typeResolver.unknownTypeRefs = globalStateData.unknownTypeRefs; + this.dlog.setErrorCount(globalStateData.errorCount); + } + /** * @since 2.0.0 */ @@ -9933,4 +9947,12 @@ public static class AnalyzerData { QueryTypeChecker.AnalyzerData queryData = new QueryTypeChecker.AnalyzerData(); Set queryVariables; } + + /** + * @since 2201.12.0 + */ + public static class GlobalStateData { + HashSet unknownTypeRefs; + int errorCount; + } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java index 189a1504468d..08df6895c5c4 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java @@ -164,7 +164,7 @@ public class TypeResolver { private final HashSet resolvedClassDef = new HashSet<>(); private final Map modTable = new LinkedHashMap<>(); private final Map constantMap = new HashMap<>(); - private final HashSet unknownTypeRefs; + public HashSet unknownTypeRefs; private SymbolEnv pkgEnv; private int currentDepth; private Deque resolvingTypes; @@ -188,7 +188,7 @@ public TypeResolver(CompilerContext context) { this.unknownTypeRefs = new HashSet<>(); } - public void clearUnknowTypeRefs() { + public void clearUnknownTypeRefs() { unknownTypeRefs.clear(); } @@ -2133,7 +2133,7 @@ private static class ResolverData { * * @since 2201.7.0 */ - private static class LocationData { + protected static class LocationData { private final String name; private final int row; private final int column; diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/typedefs/TypeDefinitionsNegativeTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/typedefs/TypeDefinitionsNegativeTest.java index 9737f366969e..7e684d9b2422 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/typedefs/TypeDefinitionsNegativeTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/typedefs/TypeDefinitionsNegativeTest.java @@ -74,6 +74,12 @@ public void testSemanticsNegative() { "'function () returns (int)', found 'function () returns (MyTuple)'", 37, 33); BAssertUtil.validateError(compileResult, index++, "incompatible types: expected 'Foo', found 'string'", 43, 13); + BAssertUtil.validateError(compileResult, index++, "unknown type 'I'", 48, 19); + BAssertUtil.validateError(compileResult, index++, "unknown type 'I'", 52, 35); + BAssertUtil.validateError(compileResult, index++, "unknown type 'J'", 54, 17); + BAssertUtil.validateError(compileResult, index++, "unknown type 'J'", 56, 22); + BAssertUtil.validateError(compileResult, index++, "unknown type 'J'", 58, 23); + Assert.assertEquals(compileResult.getErrorCount(), index); } } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/type-definitions-semantics-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/type-definitions-semantics-negative.bal index 19c3ed59e243..ee0248f1c7ce 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/type-definitions-semantics-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/type-definitions-semantics-negative.bal @@ -42,3 +42,17 @@ type Foo boolean|null; function testNullFiniteType() { Foo _ = "null"; // error } + +class H {}; + +H res = check new I(); + +int[] a = [1, 2, 3, 4, 5]; + +int[] b = from var i in a select i; + +float result = 1 + 2.0; + +int result2 = true? 1 : 2; + +var result3 = new J(); From 4640af17467cc112e05a9f83fdeccfa57940153f Mon Sep 17 00:00:00 2001 From: rdulmina Date: Tue, 28 Jan 2025 13:49:42 +0530 Subject: [PATCH 4/5] Address review suggestions --- .../compiler/semantics/analyzer/TypeChecker.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java index 95fcfa20f7e7..c20b7447571f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java @@ -9916,9 +9916,7 @@ String recordsToString(Set recordTypeSet) { public GlobalStateData getGlobalStateSnapshotAndResetGlobalState() { // Preserve global state - GlobalStateData globalStateData = new GlobalStateData(); - globalStateData.unknownTypeRefs = typeResolver.unknownTypeRefs; - globalStateData.errorCount = this.dlog.errorCount(); + GlobalStateData globalStateData = new GlobalStateData(typeResolver.unknownTypeRefs, this.dlog.errorCount()); // Reset global state typeResolver.unknownTypeRefs = new HashSet<>(); @@ -9951,8 +9949,6 @@ public static class AnalyzerData { /** * @since 2201.12.0 */ - public static class GlobalStateData { - HashSet unknownTypeRefs; - int errorCount; + public record GlobalStateData(HashSet unknownTypeRefs, int errorCount) { } } From 9333af540a9d7420435f82b6278e85874ce55d8d Mon Sep 17 00:00:00 2001 From: rdulmina Date: Fri, 31 Jan 2025 11:25:24 +0530 Subject: [PATCH 5/5] Address review suggestions --- .../semantics/analyzer/TypeChecker.java | 45 ++++++++++--------- .../semantics/analyzer/TypeResolver.java | 10 ++++- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java index c20b7447571f..ce1a07f723da 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java @@ -603,7 +603,7 @@ private BType silentIntTypeCheck(BLangLiteral literalExpr, Object literalValue, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprCompatibleType = getIntegerLiteralType(nodeCloner.cloneNode(literalExpr), literalValue, expType, @@ -1226,7 +1226,7 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr, AnalyzerData d boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); List matchingTypes = new ArrayList<>(); @@ -1805,7 +1805,7 @@ private BType checkListConstructorCompatibility(BType referredType, BType origin int tag = referredType.tag; if (tag == TypeTags.UNION) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); data.commonAnalyzerData.nonErrorLoggingCheck = true; this.dlog.mute(); @@ -2547,7 +2547,7 @@ public BType checkMappingConstructorCompatibility(BType bType, BLangRecordLitera if (tag == TypeTags.UNION) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); List compatibleTypes = new ArrayList<>(); @@ -3931,7 +3931,7 @@ protected BType checkExprSilent(BLangExpression expr, BType expType, AnalyzerDat boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; this.dlog.mute(); - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); BType type = checkExpr(expr, expType, data); @@ -5471,7 +5471,7 @@ public boolean isOptionalFloatOrDecimal(BType expectedType) { private BType checkAndGetType(BLangExpression expr, SymbolEnv env, BLangBinaryExpr binaryExpr, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); expr.cloneAttempt++; @@ -5732,7 +5732,7 @@ public boolean silentCompatibleFiniteMembersInUnionTypeCheck(BLangUnaryExpr unar AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType compatibleTypeOfUnaryExpression; @@ -5748,7 +5748,8 @@ public boolean silentCompatibleFiniteMembersInUnionTypeCheck(BLangUnaryExpr unar return false; } - private void unmuteDlog(AnalyzerData data, boolean prevNonErrorLoggingCheck, GlobalStateData previousGlobalState) { + private void unmuteDlog(AnalyzerData data, boolean prevNonErrorLoggingCheck, + GlobalStateSnapshot previousGlobalState) { data.commonAnalyzerData.nonErrorLoggingCheck = prevNonErrorLoggingCheck; restoreGlobalState(previousGlobalState); if (!prevNonErrorLoggingCheck) { @@ -5759,7 +5760,7 @@ private void unmuteDlog(AnalyzerData data, boolean prevNonErrorLoggingCheck, Glo public BType silentTypeCheckExpr(BLangExpression expr, BType referredType, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprCompatibleType = checkExpr(nodeCloner.cloneNode(expr), referredType, data); @@ -5822,7 +5823,7 @@ public void visit(BLangTypeConversionExpr conversionExpr, AnalyzerData data) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprCompatibleType = checkExpr(nodeCloner.cloneNode(expr), targetType, data); @@ -6608,7 +6609,7 @@ private BType getCandidateType(BLangCheckedExpr checkedExpr, BType checkExprCand boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; this.dlog.mute(); - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); checkedExpr.expr.cloneAttempt++; BLangExpression clone = nodeCloner.cloneNode(checkedExpr.expr); @@ -8240,7 +8241,7 @@ private List concatSimilarKindXMLNodes(List ex for (BLangExpression expr : exprs) { boolean prevNonErrorLoggingCheck = data.commonAnalyzerData.nonErrorLoggingCheck; data.commonAnalyzerData.nonErrorLoggingCheck = true; - GlobalStateData previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); + GlobalStateSnapshot previousGlobalState = getGlobalStateSnapshotAndResetGlobalState(); this.dlog.mute(); BType exprType = checkExpr(nodeCloner.cloneNode(expr), xmlElementEnv, symTable.xmlType, data); @@ -9914,20 +9915,21 @@ String recordsToString(Set recordTypeSet) { } } - public GlobalStateData getGlobalStateSnapshotAndResetGlobalState() { + public GlobalStateSnapshot getGlobalStateSnapshotAndResetGlobalState() { // Preserve global state - GlobalStateData globalStateData = new GlobalStateData(typeResolver.unknownTypeRefs, this.dlog.errorCount()); + GlobalStateSnapshot globalStateSnapshot = new GlobalStateSnapshot(typeResolver.getUnknownTypeRefs(), + this.dlog.errorCount()); // Reset global state - typeResolver.unknownTypeRefs = new HashSet<>(); + typeResolver.setUnknownTypeRefs(new HashSet<>()); this.dlog.resetErrorCount(); - return globalStateData; + return globalStateSnapshot; } - public void restoreGlobalState(GlobalStateData globalStateData) { - typeResolver.unknownTypeRefs = globalStateData.unknownTypeRefs; - this.dlog.setErrorCount(globalStateData.errorCount); + public void restoreGlobalState(GlobalStateSnapshot globalStateSnapshot) { + typeResolver.setUnknownTypeRefs(globalStateSnapshot.unknownTypeRefs); + this.dlog.setErrorCount(globalStateSnapshot.errorCount); } /** @@ -9947,8 +9949,11 @@ public static class AnalyzerData { } /** + * This record is used to hold a snapshot of the global fields of multiple class objects. + * @param unknownTypeRefs current unknownTypeRefs set + * @param errorCount current errorCount * @since 2201.12.0 */ - public record GlobalStateData(HashSet unknownTypeRefs, int errorCount) { + public record GlobalStateSnapshot(HashSet unknownTypeRefs, int errorCount) { } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java index 08df6895c5c4..e1b6179cfe28 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeResolver.java @@ -164,7 +164,7 @@ public class TypeResolver { private final HashSet resolvedClassDef = new HashSet<>(); private final Map modTable = new LinkedHashMap<>(); private final Map constantMap = new HashMap<>(); - public HashSet unknownTypeRefs; + private HashSet unknownTypeRefs; private SymbolEnv pkgEnv; private int currentDepth; private Deque resolvingTypes; @@ -211,6 +211,14 @@ public static TypeResolver getInstance(CompilerContext context) { return typeResolver; } + public HashSet getUnknownTypeRefs() { + return unknownTypeRefs; + } + + public void setUnknownTypeRefs(HashSet unknownTypeRefs) { + this.unknownTypeRefs = unknownTypeRefs; + } + public void defineBTypes(List moduleDefs, SymbolEnv pkgEnv) { this.pkgEnv = pkgEnv; typePrecedence = 0;