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

Rename ClassFieldStatement and ClassMethodStatement #582

Merged
merged 2 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 11 additions & 4 deletions src/astUtils/creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TokenKind } from '../lexer/TokenKind';
import type { Expression, NamespacedVariableNameExpression } from '../parser/Expression';
import { LiteralExpression, CallExpression, DottedGetExpression, VariableExpression, FunctionExpression } from '../parser/Expression';
import type { SGAttribute } from '../parser/SGTypes';
import { Block, ClassMethodStatement } from '../parser/Statement';
import { Block, MethodStatement } from '../parser/Statement';

/**
* A range that points to the beginning of the file. Used to give non-null ranges to programmatically-added source code.
Expand Down Expand Up @@ -148,15 +148,22 @@ export function createFunctionExpression(kind: TokenKind.Sub | TokenKind.Functio
);
}

export function createClassMethodStatement(name: string, kind: TokenKind.Sub | TokenKind.Function = TokenKind.Function, accessModifier?: Token) {
return new ClassMethodStatement(
accessModifier,
export function createMethodStatement(name: string, kind: TokenKind.Sub | TokenKind.Function = TokenKind.Function, modifiers?: Token[]) {
return new MethodStatement(
modifiers,
createIdentifier(name),
createFunctionExpression(kind),
null
);
}

/**
* @deprecated use `createMethodStatement`
*/
export function createClassMethodStatement(name: string, kind: TokenKind.Sub | TokenKind.Function = TokenKind.Function, accessModifier?: Token) {
return createMethodStatement(name, kind, [accessModifier]);
}

export function createCall(callee: Expression, args?: Expression[], namespaceName?: NamespacedVariableNameExpression) {
return new CallExpression(
callee,
Expand Down
20 changes: 17 additions & 3 deletions src/astUtils/reflection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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, ClassFieldStatement, ClassMethodStatement, ClassStatement, Statement, InterfaceFieldStatement, InterfaceMethodStatement, InterfaceStatement, EnumStatement, EnumMemberStatement, TryCatchStatement, CatchStatement } from '../parser/Statement';
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, ClassFieldStatement, ClassMethodStatement, ClassStatement, Statement, InterfaceFieldStatement, InterfaceMethodStatement, InterfaceStatement, EnumStatement, EnumMemberStatement, TryCatchStatement, CatchStatement, MethodStatement, FieldStatement } from '../parser/Statement';
import type { LiteralExpression, Expression, BinaryExpression, CallExpression, FunctionExpression, NamespacedVariableNameExpression, DottedGetExpression, XmlAttributeGetExpression, IndexedGetExpression, GroupingExpression, EscapedCharCodeLiteralExpression, ArrayLiteralExpression, AALiteralExpression, UnaryExpression, VariableExpression, SourceLiteralExpression, NewExpression, CallfuncExpression, TemplateStringQuasiExpression, TemplateStringExpression, TaggedTemplateStringExpression, AnnotationExpression, FunctionParameterExpression, AAMemberExpression } from '../parser/Expression';
import type { BrsFile } from '../files/BrsFile';
import type { XmlFile } from '../files/XmlFile';
Expand Down Expand Up @@ -123,11 +123,25 @@ export function isClassStatement(element: Statement | Expression | undefined): e
export function isImportStatement(element: Statement | Expression | undefined): element is ImportStatement {
return element?.constructor?.name === 'ImportStatement';
}
export function isMethodStatement(element: Statement | Expression | undefined): element is MethodStatement {
const name = element?.constructor.name;
return name === 'MethodStatement' || name === 'ClassMethodStatement';
}
/**
* @deprecated use `isMethodStatement`
*/
export function isClassMethodStatement(element: Statement | Expression | undefined): element is ClassMethodStatement {
return element?.constructor.name === 'ClassMethodStatement';
return isMethodStatement(element);
}
export function isFieldStatement(element: Statement | Expression | undefined): element is FieldStatement {
const name = element?.constructor.name;
return name === 'FieldStatement' || name === 'ClassFieldStatement';
}
/**
* @deprecated use `isFieldStatement`
*/
export function isClassFieldStatement(element: Statement | Expression | undefined): element is ClassFieldStatement {
return element?.constructor.name === 'ClassFieldStatement';
return isFieldStatement(element);
}
export function isInterfaceStatement(element: Statement | Expression | undefined): element is InterfaceStatement {
return element?.constructor.name === 'InterfaceStatement';
Expand Down
6 changes: 3 additions & 3 deletions src/astUtils/visitors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -844,10 +844,10 @@ describe('astUtils visitors', () => {
end class
`, [
'ClassStatement',
'ClassFieldStatement',
'ClassFieldStatement',
'FieldStatement',
'FieldStatement',
'LiteralExpression',
'ClassMethodStatement',
'MethodStatement',
'FunctionExpression',
'Block',
'ReturnStatement',
Expand Down
17 changes: 16 additions & 1 deletion src/astUtils/visitors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-bitwise */
import type { CancellationToken } from 'vscode-languageserver';
import type { Statement, 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, ClassMethodStatement, ClassFieldStatement, EnumStatement, EnumMemberStatement, DimStatement, TryCatchStatement, CatchStatement, ThrowStatement, InterfaceStatement, InterfaceFieldStatement, InterfaceMethodStatement } from '../parser/Statement';
import type { Statement, 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, ClassMethodStatement, ClassFieldStatement, EnumStatement, EnumMemberStatement, DimStatement, TryCatchStatement, CatchStatement, ThrowStatement, InterfaceStatement, InterfaceFieldStatement, InterfaceMethodStatement, FieldStatement, MethodStatement } from '../parser/Statement';
import type { AALiteralExpression, AAMemberExpression, AnnotationExpression, ArrayLiteralExpression, BinaryExpression, CallExpression, CallfuncExpression, DottedGetExpression, EscapedCharCodeLiteralExpression, Expression, FunctionExpression, FunctionParameterExpression, GroupingExpression, IndexedGetExpression, LiteralExpression, NamespacedVariableNameExpression, NewExpression, NullCoalescingExpression, RegexLiteralExpression, SourceLiteralExpression, TaggedTemplateStringExpression, TemplateStringExpression, TemplateStringQuasiExpression, TernaryExpression, UnaryExpression, VariableExpression, XmlAttributeGetExpression } from '../parser/Expression';
import { isExpression, isStatement } from './reflection';

Expand Down Expand Up @@ -99,8 +99,16 @@ export function createVisitor(
InterfaceFieldStatement?: (statement: InterfaceFieldStatement, parent?: Statement) => Statement | void;
InterfaceMethodStatement?: (statement: InterfaceMethodStatement, parent?: Statement) => Statement | void;
ClassStatement?: (statement: ClassStatement, parent?: Statement) => Statement | void;
/**
* @deprecated use `MethodStatement`
*/
ClassMethodStatement?: (statement: ClassMethodStatement, parent?: Statement) => Statement | void;
/**
* @deprecated use `FieldStatement`
*/
ClassFieldStatement?: (statement: ClassFieldStatement, parent?: Statement) => Statement | void;
MethodStatement?: (statement: MethodStatement, parent?: Statement) => Statement | void;
FieldStatement?: (statement: FieldStatement, parent?: Statement) => Statement | void;
TryCatchStatement?: (statement: TryCatchStatement, parent?: Statement) => Statement | void;
CatchStatement?: (statement: CatchStatement, parent?: Statement) => Statement | void;
ThrowStatement?: (statement: ThrowStatement, parent?: Statement) => Statement | void;
Expand Down Expand Up @@ -135,6 +143,13 @@ export function createVisitor(
RegexLiteralExpression?: (expression: RegexLiteralExpression, parent?: Statement | Expression) => Expression | void;
}
) {
//remap some deprecated visitor names TODO remove this in v1
if (visitor.ClassFieldStatement) {
visitor.FieldStatement = visitor.ClassFieldStatement;
}
if (visitor.ClassMethodStatement) {
visitor.MethodStatement = visitor.ClassMethodStatement;
}
return <WalkVisitor>((statement: Statement, parent?: Statement): Statement | void => {
return visitor[statement.constructor.name]?.(statement, parent);
});
Expand Down
10 changes: 5 additions & 5 deletions src/files/BrsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Lexer } from '../lexer/Lexer';
import { TokenKind, AllowedLocalIdentifiers, Keywords } from '../lexer/TokenKind';
import { Parser, ParseMode } from '../parser/Parser';
import type { FunctionExpression, VariableExpression, Expression } from '../parser/Expression';
import type { ClassStatement, FunctionStatement, NamespaceStatement, ClassMethodStatement, AssignmentStatement, LibraryStatement, ImportStatement, Statement, ClassFieldStatement } from '../parser/Statement';
import type { ClassStatement, FunctionStatement, NamespaceStatement, AssignmentStatement, LibraryStatement, ImportStatement, Statement, MethodStatement, FieldStatement } from '../parser/Statement';
import type { Program, SignatureInfoObj } from '../Program';
import { DynamicType } from '../types/DynamicType';
import { FunctionType } from '../types/FunctionType';
Expand Down Expand Up @@ -1497,12 +1497,12 @@ export class BrsFile {
public getClassMemberDefinitions(textToSearchFor: string, file: BrsFile): Location[] {
let results: Location[] = [];
//get class fields and members
const statementHandler = (statement: ClassMethodStatement) => {
const statementHandler = (statement: MethodStatement) => {
if (statement.getName(file.parseMode).toLowerCase() === textToSearchFor) {
results.push(Location.create(util.pathToUri(file.srcPath), statement.range));
}
};
const fieldStatementHandler = (statement: ClassFieldStatement) => {
const fieldStatementHandler = (statement: FieldStatement) => {
if (statement.name.text.toLowerCase() === textToSearchFor) {
results.push(Location.create(util.pathToUri(file.srcPath), statement.range));
}
Expand Down Expand Up @@ -1698,7 +1698,7 @@ export class BrsFile {
return { key: key, signature: signature, index: index };
}

private getClassMethod(classStatement: ClassStatement, name: string, walkParents = true): ClassMethodStatement | undefined {
private getClassMethod(classStatement: ClassStatement, name: string, walkParents = true): MethodStatement | undefined {
//TODO - would like to write this with getClassHieararchy; but got stuck on working out the scopes to use... :(
let statement;
const statementHandler = (e) => {
Expand All @@ -1708,7 +1708,7 @@ export class BrsFile {
};
while (classStatement) {
classStatement.walk(createVisitor({
ClassMethodStatement: statementHandler
MethodStatement: statementHandler
}), {
walkMode: WalkMode.visitStatements
});
Expand Down
12 changes: 6 additions & 6 deletions src/parser/Parser.Class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DiagnosticMessages } from '../DiagnosticMessages';
import { TokenKind, AllowedLocalIdentifiers, AllowedProperties } from '../lexer/TokenKind';
import { Lexer } from '../lexer/Lexer';
import { Parser, ParseMode } from './Parser';
import type { FunctionStatement, AssignmentStatement, ClassFieldStatement } from './Statement';
import type { FunctionStatement, AssignmentStatement, FieldStatement } from './Statement';
import { ClassStatement } from './Statement';
import { NewExpression } from './Expression';

Expand Down Expand Up @@ -193,7 +193,7 @@ describe('parser class', () => {
let { statements, diagnostics } = Parser.parse(tokens, { mode: ParseMode.BrighterScript });
expect(diagnostics).to.be.empty;
expect(statements[0]).instanceof(ClassStatement);
let field = (statements[0] as ClassStatement).body[0] as ClassFieldStatement;
let field = (statements[0] as ClassStatement).body[0] as FieldStatement;
expect(field.accessModifier.kind).to.equal(TokenKind.Public);
expect(field.name.text).to.equal('firstName');
expect(field.as.text).to.equal('as');
Expand Down Expand Up @@ -315,10 +315,10 @@ describe('parser class', () => {
let { statements, diagnostics } = Parser.parse(tokens, { mode: ParseMode.BrighterScript });
expect(diagnostics[0]?.message).not.to.exist;
let cls = statements[0] as ClassStatement;
expect((cls.memberMap['name'] as ClassFieldStatement).initialValue).to.exist;
expect((cls.memberMap['age'] as ClassFieldStatement).initialValue).to.exist;
expect((cls.memberMap['isalive'] as ClassFieldStatement).initialValue).to.exist;
expect((cls.memberMap['callback'] as ClassFieldStatement).initialValue).to.exist;
expect((cls.memberMap['name'] as FieldStatement).initialValue).to.exist;
expect((cls.memberMap['age'] as FieldStatement).initialValue).to.exist;
expect((cls.memberMap['isalive'] as FieldStatement).initialValue).to.exist;
expect((cls.memberMap['callback'] as FieldStatement).initialValue).to.exist;
});

it('detects missing function keyword', () => {
Expand Down
53 changes: 27 additions & 26 deletions src/parser/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,35 @@ import type { BlockTerminator } from '../lexer/TokenKind';
import { Lexer } from '../lexer/Lexer';
import {
AllowedLocalIdentifiers,
AssignmentOperators,
DisallowedLocalIdentifiersText,
DisallowedFunctionIdentifiersText,
AllowedProperties,
AssignmentOperators,
BrighterScriptSourceLiterals,
DeclarableTypes, TokenKind
DeclarableTypes,
DisallowedFunctionIdentifiersText,
DisallowedLocalIdentifiersText,
TokenKind
} from '../lexer/TokenKind';
import type {
Statement,
PrintSeparatorSpace,
PrintSeparatorTab,
PrintSeparatorSpace
Statement
} from './Statement';
import {
InterfaceStatement,
InterfaceMethodStatement,
InterfaceFieldStatement,
AssignmentStatement,
Block,
Body,
CatchStatement,
ClassFieldStatement,
ClassMethodStatement,
ClassStatement,
CommentStatement,
DimStatement,
DottedSetStatement,
EndStatement,
EnumStatement,
EnumMemberStatement,
EnumStatement,
ExitForStatement,
ExitWhileStatement,
ExpressionStatement,
FieldStatement,
ForEachStatement,
ForStatement,
FunctionStatement,
Expand All @@ -44,8 +41,12 @@ import {
ImportStatement,
IncrementStatement,
IndexedSetStatement,
InterfaceFieldStatement,
InterfaceMethodStatement,
InterfaceStatement,
LabelStatement,
LibraryStatement,
MethodStatement,
NamespaceStatement,
PrintStatement,
ReturnStatement,
Expand All @@ -61,30 +62,30 @@ import type { Expression } from './Expression';
import {
AALiteralExpression,
AAMemberExpression,
AnnotationExpression,
ArrayLiteralExpression,
BinaryExpression,
CallExpression,
CallfuncExpression,
DottedGetExpression,
EscapedCharCodeLiteralExpression,
FunctionExpression,
FunctionParameterExpression,
GroupingExpression,
IndexedGetExpression,
LiteralExpression,
NamespacedVariableNameExpression,
NewExpression,
NullCoalescingExpression,
RegexLiteralExpression,
UnaryExpression,
VariableExpression,
XmlAttributeGetExpression,
SourceLiteralExpression,
TaggedTemplateStringExpression,
TemplateStringExpression,
EscapedCharCodeLiteralExpression,
TemplateStringQuasiExpression,
TaggedTemplateStringExpression,
SourceLiteralExpression,
AnnotationExpression,
FunctionParameterExpression,
TernaryExpression,
NullCoalescingExpression
UnaryExpression,
VariableExpression,
XmlAttributeGetExpression
} from './Expression';
import type { Diagnostic, Range } from 'vscode-languageserver';
import { Logger } from '../Logger';
Expand Down Expand Up @@ -647,20 +648,20 @@ export class Parser {
});
}

decl = new ClassMethodStatement(
decl = new MethodStatement(
accessModifier,
funcDeclaration.name,
funcDeclaration.func,
overrideKeyword
);

//refer to this statement as parent of the expression
functionStatement.func.functionStatement = decl as ClassMethodStatement;
functionStatement.func.functionStatement = decl as MethodStatement;

//fields
} else if (this.checkAny(TokenKind.Identifier, ...AllowedProperties)) {

decl = this.classFieldDeclaration(accessModifier);
decl = this.fieldDeclaration(accessModifier);

//class fields cannot be overridden
if (overrideKeyword) {
Expand Down Expand Up @@ -711,7 +712,7 @@ export class Parser {
return result;
}

private classFieldDeclaration(accessModifier: Token | null) {
private fieldDeclaration(accessModifier: Token | null) {
let name = this.consume(
DiagnosticMessages.expectedClassFieldIdentifier(),
TokenKind.Identifier,
Expand Down Expand Up @@ -741,7 +742,7 @@ export class Parser {
initialValue = this.expression();
}

return new ClassFieldStatement(
return new FieldStatement(
accessModifier,
name,
asToken,
Expand Down
Loading