diff --git a/src/CrossScopeValidator.ts b/src/CrossScopeValidator.ts index 2007f1c71..135d746bf 100644 --- a/src/CrossScopeValidator.ts +++ b/src/CrossScopeValidator.ts @@ -263,6 +263,11 @@ export class CrossScopeValidator { getRequiredMap(scope: Scope) { const map = new Map(); scope.enumerateBrsFiles((file) => { + //typedef files (.d.bs) are ambient declarations only - never validated for diagnostics, + //so don't flag their own unresolved type references as missing symbols + if (file.isTypedef) { + return; + } for (const symbol of file.requiredSymbols) { const symbolKeysArray = this.symbolMapKeys(symbol); for (const symbolKeys of symbolKeysArray) { diff --git a/src/bscPlugin/validation/ScopeValidator.spec.ts b/src/bscPlugin/validation/ScopeValidator.spec.ts index 0007d5406..f5439b9df 100644 --- a/src/bscPlugin/validation/ScopeValidator.spec.ts +++ b/src/bscPlugin/validation/ScopeValidator.spec.ts @@ -4013,6 +4013,19 @@ describe('ScopeValidator', () => { program.validate(); expectZeroDiagnostics(program); }); + + it('does not report cannot-find-name for unresolvable types referenced in .d.bs files', () => { + //simulates a .d.bs typedef whose namespace-qualified types don't actually resolve + //(e.g. produced by a buggy third-party rewrite tool), which should never produce diagnostics + program.setFile('source/util.d.bs', ` + namespace SomeNamespace + function getSomething(a as SomeNamespace.ifDraw2d) as SomeNamespace.roAssociativeArray + end function + end namespace + `); + program.validate(); + expectZeroDiagnostics(program); + }); }); describe('assignmentTypeMismatch', () => { diff --git a/src/bscPlugin/validation/ScopeValidator.ts b/src/bscPlugin/validation/ScopeValidator.ts index 635029794..e06965be2 100644 --- a/src/bscPlugin/validation/ScopeValidator.ts +++ b/src/bscPlugin/validation/ScopeValidator.ts @@ -154,7 +154,7 @@ export class ScopeValidator { //do many per-file checks for every file in this (and parent) scopes this.event.scope.enumerateBrsFiles((file) => { - if (!isBrsFile(file)) { + if (!isBrsFile(file) || file.isTypedef) { return; } @@ -169,6 +169,11 @@ export class ScopeValidator { this.event.scope.enumerateOwnFiles((file) => { if (isBrsFile(file)) { + //typedef files (.d.bs) are ambient declarations only - never validated for diagnostics + if (file.isTypedef) { + return; + } + if (this.event.program.diagnostics.canSkipScopeValidationForFile(file)) { return; } @@ -277,9 +282,6 @@ export class ScopeValidator { }); }, FunctionExpression: (func) => { - if (file.isTypedef) { - return; - } this.addValidationKindMetric('FunctionExpression', () => { this.validateFunctionExpressionForReturn(func); });