Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes Typed Arrays to allow Native Components #919

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/Scope.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { UnionType } from './types/UnionType';
import { isFunctionStatement, isNamespaceStatement } from './astUtils/reflection';
import { ArrayType } from './types/ArrayType';
import { AssociativeArrayType } from './types/AssociativeArrayType';
import { InterfaceType } from '.';
import { ComponentType } from './types/ComponentType';

describe('Scope', () => {
let sinon = sinonImport.createSandbox();
Expand Down Expand Up @@ -2940,6 +2942,66 @@ describe('Scope', () => {
expect((unionDefaultType as UnionType).types).to.include(StringType.instance);
expect((unionDefaultType as UnionType).types).to.include(IntegerType.instance);
});

it('should allow built in component types', () => {
let utilFile = program.setFile('source/util.bs', `
sub process(data as roAssociativeArray[])
for each datum in data
print datum
end for
end sub
`);
program.validate();
expectZeroDiagnostics(program);
const processFnScope = utilFile.getFunctionScopeAtPosition(util.createPosition(2, 24));
const symbolTable = processFnScope.symbolTable;
const opts = { flags: SymbolTypeFlag.runtime };
expectTypeToBe(symbolTable.getSymbolType('data', opts), ArrayType);
expectTypeToBe(symbolTable.getSymbolType('datum', opts), InterfaceType);
});

it('should allow class types', () => {
let utilFile = program.setFile('source/util.bs', `
sub process(data as Klass[])
for each datum in data
print datum.name
end for
end sub


class Klass
name as string
end class
`);
program.validate();
expectZeroDiagnostics(program);
const processFnScope = utilFile.getFunctionScopeAtPosition(util.createPosition(2, 24));
const symbolTable = processFnScope.symbolTable;
const opts = { flags: SymbolTypeFlag.runtime };
const dataType = symbolTable.getSymbolType('data', opts);
expectTypeToBe(dataType, ArrayType);
expectTypeToBe((dataType as ArrayType).defaultType, ClassType);
expect((dataType as ArrayType).defaultType.toString()).to.equal('Klass');
});

it('should allow component types', () => {
let utilFile = program.setFile('source/util.bs', `
sub process(labels as roSgNodeLabel[])
for each label in labels
print label.text
end for
end sub
`);
program.validate();
expectZeroDiagnostics(program);
const processFnScope = utilFile.getFunctionScopeAtPosition(util.createPosition(2, 24));
const symbolTable = processFnScope.symbolTable;
const opts = { flags: SymbolTypeFlag.runtime };
const dataType = symbolTable.getSymbolType('labels', opts);
expectTypeToBe(dataType, ArrayType);
expectTypeToBe((dataType as ArrayType).defaultType, ComponentType);
expect((dataType as ArrayType).defaultType.toString()).to.equal('roSGNodeLabel');
});
});

describe('callFunc invocations', () => {
Expand Down
5 changes: 4 additions & 1 deletion src/astUtils/reflection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Body, AssignmentStatement, Block, ExpressionStatement, CommentStatement, ExitForStatement, ExitWhileStatement, FunctionStatement, IfStatement, IncrementStatement, PrintStatement, GotoStatement, LabelStatement, ReturnStatement, EndStatement, StopStatement, ForStatement, ForEachStatement, WhileStatement, DottedSetStatement, IndexedSetStatement, LibraryStatement, NamespaceStatement, ImportStatement, ClassStatement, InterfaceFieldStatement, InterfaceMethodStatement, InterfaceStatement, EnumStatement, EnumMemberStatement, TryCatchStatement, CatchStatement, ThrowStatement, MethodStatement, FieldStatement, ConstStatement, ContinueStatement } from '../parser/Statement';
import type { LiteralExpression, BinaryExpression, CallExpression, FunctionExpression, DottedGetExpression, XmlAttributeGetExpression, IndexedGetExpression, GroupingExpression, EscapedCharCodeLiteralExpression, ArrayLiteralExpression, AALiteralExpression, UnaryExpression, VariableExpression, SourceLiteralExpression, NewExpression, CallfuncExpression, TemplateStringQuasiExpression, TemplateStringExpression, TaggedTemplateStringExpression, AnnotationExpression, FunctionParameterExpression, AAMemberExpression, TypeExpression, TypeCastExpression } from '../parser/Expression';
import type { LiteralExpression, BinaryExpression, CallExpression, FunctionExpression, DottedGetExpression, XmlAttributeGetExpression, IndexedGetExpression, GroupingExpression, EscapedCharCodeLiteralExpression, ArrayLiteralExpression, AALiteralExpression, UnaryExpression, VariableExpression, SourceLiteralExpression, NewExpression, CallfuncExpression, TemplateStringQuasiExpression, TemplateStringExpression, TaggedTemplateStringExpression, AnnotationExpression, FunctionParameterExpression, AAMemberExpression, TypeExpression, TypeCastExpression, TypedArrayExpression } from '../parser/Expression';
import type { BrsFile } from '../files/BrsFile';
import type { XmlFile } from '../files/XmlFile';
import type { BscFile, File, TypedefProvider } from '../interfaces';
Expand Down Expand Up @@ -262,6 +262,9 @@ export function isTypeExpression(element: any): element is TypeExpression {
export function isTypeCastExpression(element: any): element is TypeCastExpression {
return element?.kind === AstNodeKind.TypeCastExpression;
}
export function isTypedArrayExpression(element: any): element is TypedArrayExpression {
return element?.kind === AstNodeKind.TypedArrayExpression;
}

// BscType reflection
export function isStringType(value: any): value is StringType {
Expand Down
10 changes: 6 additions & 4 deletions src/bscPlugin/validation/ScopeValidator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { URI } from 'vscode-uri';
import { isAssignmentStatement, isBinaryExpression, isBrsFile, isClassType, isDynamicType, isEnumMemberType, isEnumType, isFunctionExpression, isLiteralExpression, isNamespaceStatement, isObjectType, isPrimitiveType, isTypeExpression, isTypedFunctionType, isUnionType, isVariableExpression, isXmlScope } from '../../astUtils/reflection';
import { isAssignmentStatement, isBinaryExpression, isBrsFile, isClassType, isDynamicType, isEnumMemberType, isEnumType, isFunctionExpression, isLiteralExpression, isNamespaceStatement, isObjectType, isPrimitiveType, isTypeExpression, isTypedArrayExpression, isTypedFunctionType, isUnionType, isVariableExpression, isXmlScope } from '../../astUtils/reflection';
import { Cache } from '../../Cache';
import { DiagnosticMessages } from '../../DiagnosticMessages';
import type { BrsFile } from '../../files/BrsFile';
Expand Down Expand Up @@ -80,17 +80,19 @@ export class ScopeValidator {


private checkIfUsedAsTypeExpression(expression: AstNode): boolean {
//TODO: this is much faster than node.findAncestor(), but will not work for "complicated" type expressions like UnionTypes
//TODO: this is much faster than node.findAncestor(), but may need to be updated for "complicated" type expressions
if (isTypeExpression(expression) ||
isTypeExpression(expression.parent)) {
isTypeExpression(expression.parent) ||
isTypedArrayExpression(expression) ||
isTypedArrayExpression(expression.parent)) {
return true;
}
if (isBinaryExpression(expression.parent)) {
let currentExpr: AstNode = expression.parent;
while (isBinaryExpression(currentExpr) && currentExpr.operator.kind === TokenKind.Or) {
currentExpr = currentExpr.parent;
}
return isTypeExpression(currentExpr);
return isTypeExpression(currentExpr) || isTypedArrayExpression(currentExpr);
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/parser/AstNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,5 @@ export enum AstNodeKind {
Block = 'Block',
TypeExpression = 'TypeExpression',
TypeCastExpression = 'TypeCastExpression',
ArrayTypeExpression = 'ArrayTypeExpression'
TypedArrayExpression = 'TypedArrayExpression'
}
2 changes: 1 addition & 1 deletion src/parser/Expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,7 @@ export class TypedArrayExpression extends Expression {
);
}

public readonly kind = AstNodeKind.ArrayTypeExpression;
public readonly kind = AstNodeKind.TypedArrayExpression;

public range: Range;

Expand Down