Skip to content

Commit

Permalink
Fixes issue with AA overriding built-in properties (#1106)
Browse files Browse the repository at this point in the history
Co-authored-by: Bronley Plumb <bronley@gmail.com>
  • Loading branch information
markwpearce and TwitchBronBron authored Mar 11, 2024
1 parent 6e0158a commit 5b9384e
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
56 changes: 55 additions & 1 deletion src/bscPlugin/validation/ScopeValidator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import type { TypeCompatibilityData } from '../../interfaces';
import { IntegerType } from '../../types/IntegerType';
import { StringType } from '../../types/StringType';
import type { BrsFile } from '../../files/BrsFile';
import { FloatType } from '../../types';
import { FloatType, InterfaceType } from '../../types';
import { SymbolTypeFlag } from '../../SymbolTypeFlag';
import { AssociativeArrayType } from '../../types/AssociativeArrayType';

describe('ScopeValidator', () => {

Expand Down Expand Up @@ -2057,6 +2058,59 @@ describe('ScopeValidator', () => {
program.validate();
expectZeroDiagnostics(program);
});


it('allows AA with overidden props to meet interface', () => {
program.setFile('source/code.bs', `
namespace alpha.beta
interface Stream
thumbnailTiler as Thumbnail
end interface
interface Thumbnail
count as integer
end interface
function createStreamObject() as Stream
return {
thumbnailTiler: {
count: 1
}
}
end function
end namespace
`);
program.validate();
expectZeroDiagnostics(program);
});

it('allows AA with inside AA to be validated properly', () => {
program.setFile('source/code.bs', `
namespace alpha.beta
interface Stream
thumbnailTiler as Thumbnail
end interface
interface Thumbnail
count as integer
end interface
function createStreamObject() as Stream
return {
thumbnailTiler: {
count: "hello"
}
}
end function
end namespace
`);
program.validate();
expectDiagnostics(program, [
DiagnosticMessages.returnTypeMismatch('roAssociativeArray', 'alpha.beta.Stream', {
fieldMismatches: [{ name: 'thumbnailTiler', expectedType: new InterfaceType('alpha.beta.Thumbnail'), actualType: new AssociativeArrayType() }]
}).message
]);
});
});

describe('assignmentTypeMismatch', () => {
Expand Down
1 change: 1 addition & 0 deletions src/parser/Expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,7 @@ export class AALiteralExpression extends Expression {

getType(options: GetTypeOptions): BscType {
const resultType = new AssociativeArrayType();
resultType.addBuiltInInterfaces();
for (const element of this.elements) {
if (isAAMemberExpression(element)) {
resultType.addMember(element.tokens.key.text, { definingNode: element }, element.getType(options), SymbolTypeFlag.runtime);
Expand Down
13 changes: 13 additions & 0 deletions src/types/AssociativeArrayType.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SymbolTable } from '../SymbolTable';
import { SymbolTypeFlag } from '../SymbolTypeFlag';
import { isAssociativeArrayType, isClassType, isDynamicType, isObjectType } from '../astUtils/reflection';
import type { GetTypeOptions, TypeCompatibilityData } from '../interfaces';
Expand Down Expand Up @@ -44,4 +45,16 @@ export class AssociativeArrayType extends BscType {
isEqual(otherType: BscType) {
return isAssociativeArrayType(otherType) && this.checkCompatibilityBasedOnMembers(otherType, SymbolTypeFlag.runtime);
}

private builtInMemberTable: SymbolTable;

getBuiltInMemberTable(): SymbolTable {
if (this.builtInMemberTable) {
return this.builtInMemberTable;
}
this.builtInMemberTable = new SymbolTable(`${this.__identifier} Built-in Members`);
this.pushMemberProvider(() => this.builtInMemberTable);
return this.builtInMemberTable;

}
}

0 comments on commit 5b9384e

Please sign in to comment.