Skip to content

Commit

Permalink
Fixed issue with using a variable assigned from an unknown variable
Browse files Browse the repository at this point in the history
  • Loading branch information
markwpearce committed Nov 21, 2023
1 parent 460e8c5 commit aafc083
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
16 changes: 16 additions & 0 deletions src/bscPlugin/validation/ScopeValidator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1434,6 +1434,22 @@ describe('ScopeValidator', () => {
]);
});

it('does not have a diagnostic for using a variable the result of an assignment with unresolved value', () => {
program.setFile('source/util.bs', `
sub doStuff()
myValue = UndeclaredValue
if myValue > 0
print "hello"
end if
end sub
`);
program.validate();
//should have only 1 error - cannot find "UndeclaredValue"
expectDiagnostics(program, [
DiagnosticMessages.cannotFindName('UndeclaredValue').message
]);
});

});

describe('returnTypeMismatch', () => {
Expand Down
22 changes: 16 additions & 6 deletions src/bscPlugin/validation/ScopeValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Cache } from '../../Cache';
import { DiagnosticMessages } from '../../DiagnosticMessages';
import type { BrsFile } from '../../files/BrsFile';
import { DiagnosticOrigin } from '../../interfaces';
import type { BsDiagnostic, BsDiagnosticWithOrigin, OnScopeValidateEvent, TypeChainEntry, TypeCompatibilityData } from '../../interfaces';
import type { BsDiagnostic, BsDiagnosticWithOrigin, ExtraSymbolData, OnScopeValidateEvent, TypeChainEntry, TypeCompatibilityData } from '../../interfaces';
import { SymbolTypeFlag } from '../../SymbolTable';
import type { AssignmentStatement, DottedSetStatement, EnumStatement, ReturnStatement } from '../../parser/Statement';
import util from '../../util';
Expand All @@ -19,6 +19,7 @@ import { createVisitor } from '../../astUtils/visitors';
import type { BscType } from '../../types';
import type { File } from '../../files/File';
import { InsideSegmentWalkMode } from '../../AstValidationSegmenter';
import { TokenKind } from '../../lexer/TokenKind';

/**
* The lower-case names of all platform-included scenegraph nodes
Expand Down Expand Up @@ -127,12 +128,19 @@ export class ScopeValidator {
/**
* If this is the lhs of an assignment, we don't need to flag it as unresolved
*/
private ignoreUnresolvedAssignmentLHS(expression: Expression, exprType: BscType) {
private ignoreUnresolvedAssignmentLHS(expression: Expression, exprType: BscType, definingNode?: AstNode) {
if (!isVariableExpression(expression)) {
return false;
}
const assignmentAncestor: AssignmentStatement = expression?.findAncestor(isAssignmentStatement);
return assignmentAncestor?.name === expression?.name && isUnionType(exprType); // the left hand side is not a union, which means it was never assigned
let assignmentAncestor: AssignmentStatement;
if (isAssignmentStatement(definingNode) && definingNode.equals.kind === TokenKind.Equal) {
// this symbol was defined in a "normal" assignment (eg. not a compound assignment)
assignmentAncestor = definingNode;
return assignmentAncestor?.name?.text.toLowerCase() === expression?.name?.text.toLowerCase();
} else {
assignmentAncestor = expression?.findAncestor(isAssignmentStatement);
}
return assignmentAncestor?.name === expression?.name && isUnionType(exprType);
}

/**
Expand Down Expand Up @@ -494,12 +502,14 @@ export class ScopeValidator {
// Do a complete type check on all DottedGet and Variable expressions
// this will create a diagnostic if an invalid member is accessed
const typeChain: TypeChainEntry[] = [];
const typeData = {} as ExtraSymbolData;
let exprType = expression.getType({
flags: symbolType,
typeChain: typeChain
typeChain: typeChain,
data: typeData
});

const shouldIgnoreLHS = this.ignoreUnresolvedAssignmentLHS(expression, exprType);
const shouldIgnoreLHS = this.ignoreUnresolvedAssignmentLHS(expression, exprType, typeData?.definingNode);

if (!this.isTypeKnown(exprType) && !shouldIgnoreLHS) {
if (expression.getType({ flags: oppositeSymbolType })?.isResolvable()) {
Expand Down

0 comments on commit aafc083

Please sign in to comment.