Skip to content

Commit

Permalink
Reset unknownTypeRefs after silent type checking
Browse files Browse the repository at this point in the history
  • Loading branch information
rdulmina committed Jan 21, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 7264bbb commit 65afcd1
Showing 5 changed files with 78 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -488,7 +488,7 @@ private void defineConstructs(BLangPackage pkgNode, SymbolEnv pkgEnv) {
}
}
}
typeResolver.clearUnknowTypeRefs();
typeResolver.clearUnknownTypeRefs();
}

private void defineDependentFields(List<BLangNode> typeDefNodes, SymbolEnv pkgEnv) {
Original file line number Diff line number Diff line change
@@ -254,6 +254,7 @@ public class TypeChecker extends SimpleBLangNodeAnalyzer<TypeChecker.AnalyzerDat
private final Types types;
private final Unifier unifier;
protected final QueryTypeChecker queryTypeChecker;
private final TypeResolver typeResolver;

static {
LIST_LENGTH_MODIFIER_FUNCTIONS.add(FUNCTION_NAME_PUSH);
@@ -324,6 +325,7 @@ public TypeChecker(CompilerContext context) {
this.missingNodesHelper = BLangMissingNodesHelper.getInstance(context);
this.unifier = new Unifier();
this.queryTypeChecker = QueryTypeChecker.getInstance(context);
this.typeResolver = TypeResolver.getInstance(context);
}

public TypeChecker(CompilerContext context, CompilerContext.Key<TypeChecker> key) {
@@ -343,6 +345,7 @@ public TypeChecker(CompilerContext context, CompilerContext.Key<TypeChecker> 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<BType> 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<BType> 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,26 +5732,25 @@ 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;
for (BType type : expectedType.getMemberTypes()) {
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<BLangExpression> concatSimilarKindXMLNodes(List<BLangExpression> 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<BRecordType> 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<String> queryVariables;
}

/**
* @since 2201.12.0
*/
public static class GlobalStateData {
HashSet<TypeResolver.LocationData> unknownTypeRefs;
int errorCount;
}
}
Original file line number Diff line number Diff line change
@@ -164,7 +164,7 @@ public class TypeResolver {
private final HashSet<BLangClassDefinition> resolvedClassDef = new HashSet<>();
private final Map<String, BLangNode> modTable = new LinkedHashMap<>();
private final Map<String, BLangConstantValue> constantMap = new HashMap<>();
private final HashSet<LocationData> unknownTypeRefs;
public HashSet<LocationData> unknownTypeRefs;
private SymbolEnv pkgEnv;
private int currentDepth;
private Deque<BType> 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;
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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> i;

float result = <J>1 + 2.0;

int result2 = true? <J>1 : 2;

var result3 = <H> new J();

0 comments on commit 65afcd1

Please sign in to comment.