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

Feature: AST annotations #234

Merged
merged 6 commits into from
Oct 27, 2020

Conversation

elsassph
Copy link
Contributor

@elsassph elsassph commented Oct 23, 2020

Annotations are metadata expressions attached to AST statements.

  • any statement can receive multiple annotations,
  • annotations can be on the same line as the statement,
  • annotations can have arguments; arguments can be any valid BrightScript expression,
  • name of the annotation must be a valid identifier; it can't be a keyword (e.g. sub, while...),
  • annotations have a method to obtain JS-friendly types (annotation.getArguments()); basic types, arrays and roAssocArrays are converted.

Limitation:

  • annotations aren't validated if they are mis-named; could be declared by the plugins using them in the future,
  • currently these expressions are not walked, for various reasons.

Example:

@someFlag
sub someFunction()
  '...
end sub

@configuration("param", [1, 2, 3], { prop: "value" })
@andAnotherFlag
function anotherFunction()
  @translate print "this can also have meta"
end function

@replaceWith(45 * 3, sub ()
  print "you could have whole expressions here - why tho?"
end sub)
sub replaceMe()
    '...
end sub

A plugin can explore the AST and look at the annotations:

const annotations = statement.annotations;
if (annotations) {
    annotations.forEach(a => console.log(a.name, a.getArguments()));
    // ex: configuration ["param", [1, 2, 3], { prop: "value" }]
}

Philippe Elsass added 4 commits October 23, 2020 18:02
- any statement can receive multiple annotations
- annotations can have arguments
- annotations have a method to obtain JS-friendly types
@georgejecook
Copy link
Contributor

simply marvellous. I will put this to good use. Thanks @elsassph

@@ -246,6 +252,11 @@ export class Parser {
) {
let dec = this.declaration();
if (dec) {
//attach annotations to statements
if (this.pendingAnnotations.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be this.pendingAnnotations.length > 0?

@@ -2503,11 +2540,11 @@ function createReferences(): References {
export interface References {
assignmentStatements: AssignmentStatement[];
classStatements: ClassStatement[];
namespaceStatements: NamespaceStatement[];
functionStatements: FunctionStatement[];
functionExpressions: FunctionExpression[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're ordering these alphabetically, might as well swap functionStatements and functionExpressions too.

@TwitchBronBron
Copy link
Member

@elsassph this looks great. As soon as you address this comment I'll be ready to merge.

@TwitchBronBron TwitchBronBron merged commit 106b6f2 into rokucommunity:master Oct 27, 2020
@elsassph elsassph deleted the feature/annotations branch February 3, 2021 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants