Skip to content

Commit

Permalink
[Proposal] Add Namespace Source Literals (#1354)
Browse files Browse the repository at this point in the history
* Add Namespace Source Literals

* Update New Literal IDs with "_NAME" suffix

* casing mismatch in Keywords consts

* Snakecase hash strings must be assigned as strings

---------

Co-authored-by: Addison <addison@torchlight.press>
Co-authored-by: Addison <addison.short@corusent.com>
  • Loading branch information
3 people authored Nov 25, 2024
1 parent f6dedf7 commit bc54435
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 1 deletion.
44 changes: 44 additions & 0 deletions docs/source-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,50 @@ function Human_Versus_Zombie_Eat()
end function
```

## SOURCE_NAMESPACE_NAME

This works the same as SOURCE_FUNCTION_NAME except that it does not include the function name.

The SOURCE_NAMESPACE_NAME can be a useful string for debug logs and logging filters.

```BrighterScript
namespace Human.Versus.Zombie
function Eat()
print SOURCE_NAMESPACE_NAME
end function
end namespace
```

transpiles to:

```BrightScript
function Human_Versus_Zombie_Eat()
print "Human.Versus.Zombie"
end function
```

## SOURCE_NAMESPACE_ROOT_NAME

This works the same as SOURCE_NAMESPACE_NAME except that it only includes the lowest-level namespace.

The SOURCE_NAMESPACE_ROOT_NAME can be a useful string for debug logs and logging filters.

```BrighterScript
namespace Human.Versus.Zombie
function Eat()
print SOURCE_NAMESPACE_ROOT_NAME
end function
end namespace
```

transpiles to:

```BrightScript
function Human_Versus_Zombie_Eat()
print "Human"
end function
```

## SOURCE_LOCATION
A combination of SOURCE_FILE_PATH and SOURCE_LINE_NUM.

Expand Down
2 changes: 2 additions & 0 deletions src/astUtils/creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ const tokenDefaults = {
[TokenKind.Semicolon]: ';',
[TokenKind.SourceFilePathLiteral]: 'SOURCE_FILE_PATH',
[TokenKind.SourceFunctionNameLiteral]: 'SOURCE_FUNCTION_NAME',
[TokenKind.SourceNamespaceRootNameLiteral]: 'SOURCE_NAMESPACE_ROOT_NAME',
[TokenKind.SourceNamespaceNameLiteral]: 'SOURCE_NAMESPACE_NAME',
[TokenKind.SourceLineNumLiteral]: 'SOURCE_LINE_NUM',
[TokenKind.SourceLocationLiteral]: 'SOURCE_LOCATION',
[TokenKind.Star]: '*',
Expand Down
4 changes: 3 additions & 1 deletion src/lexer/Lexer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1332,13 +1332,15 @@ describe('lexer', () => {
});

it('identifies brighterscript source literals', () => {
let { tokens } = Lexer.scan('LINE_NUM SOURCE_FILE_PATH SOURCE_LINE_NUM FUNCTION_NAME SOURCE_FUNCTION_NAME SOURCE_LOCATION PKG_PATH PKG_LOCATION');
let { tokens } = Lexer.scan('LINE_NUM SOURCE_FILE_PATH SOURCE_LINE_NUM FUNCTION_NAME SOURCE_FUNCTION_NAME SOURCE_NAMESPACE_NAME SOURCE_NAMESPACE_ROOT_NAME SOURCE_LOCATION PKG_PATH PKG_LOCATION');
expect(tokens.map(x => x.kind)).to.eql([
TokenKind.LineNumLiteral,
TokenKind.SourceFilePathLiteral,
TokenKind.SourceLineNumLiteral,
TokenKind.FunctionNameLiteral,
TokenKind.SourceFunctionNameLiteral,
TokenKind.SourceNamespaceNameLiteral,
TokenKind.SourceNamespaceRootNameLiteral,
TokenKind.SourceLocationLiteral,
TokenKind.PkgPathLiteral,
TokenKind.PkgLocationLiteral,
Expand Down
10 changes: 10 additions & 0 deletions src/lexer/TokenKind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ export enum TokenKind {
SourceLineNumLiteral = 'SourceLineNumLiteral',
FunctionNameLiteral = 'FunctionNameLiteral',
SourceFunctionNameLiteral = 'SourceFunctionNameLiteral',
SourceNamespaceNameLiteral = 'SourceNamespaceNameLiteral',
SourceNamespaceRootNameLiteral = 'SourceNamespaceRootNameLiteral',
SourceLocationLiteral = 'SourceLocationLiteral',
PkgPathLiteral = 'PkgPathLiteral',
PkgLocationLiteral = 'PkgLocationLiteral',
Expand Down Expand Up @@ -312,6 +314,8 @@ export const Keywords: Record<string, TokenKind> = {
'source_line_num': TokenKind.SourceLineNumLiteral,
'function_name': TokenKind.FunctionNameLiteral,
'source_function_name': TokenKind.SourceFunctionNameLiteral,
'source_namespace_name': TokenKind.SourceNamespaceNameLiteral,
'source_namespace_root_name': TokenKind.SourceNamespaceRootNameLiteral,
'source_location': TokenKind.SourceLocationLiteral,
'pkg_path': TokenKind.PkgPathLiteral,
'pkg_location': TokenKind.PkgLocationLiteral,
Expand Down Expand Up @@ -438,6 +442,8 @@ export const AllowedProperties = [
TokenKind.SourceLineNumLiteral,
TokenKind.FunctionNameLiteral,
TokenKind.SourceFunctionNameLiteral,
TokenKind.SourceNamespaceNameLiteral,
TokenKind.SourceNamespaceRootNameLiteral,
TokenKind.SourceLocationLiteral,
TokenKind.PkgPathLiteral,
TokenKind.PkgLocationLiteral,
Expand Down Expand Up @@ -490,6 +496,8 @@ export const BrighterScriptSourceLiterals = [
TokenKind.SourceLineNumLiteral,
TokenKind.FunctionNameLiteral,
TokenKind.SourceFunctionNameLiteral,
TokenKind.SourceNamespaceNameLiteral,
TokenKind.SourceNamespaceRootNameLiteral,
TokenKind.SourceLocationLiteral,
TokenKind.PkgPathLiteral,
TokenKind.PkgLocationLiteral
Expand Down Expand Up @@ -546,6 +554,8 @@ export const DisallowedLocalIdentifiers = [
TokenKind.SourceLineNumLiteral,
TokenKind.FunctionNameLiteral,
TokenKind.SourceFunctionNameLiteral,
TokenKind.SourceNamespaceNameLiteral,
TokenKind.SourceNamespaceRootNameLiteral,
TokenKind.SourceLocationLiteral,
TokenKind.PkgPathLiteral,
TokenKind.PkgLocationLiteral,
Expand Down
13 changes: 13 additions & 0 deletions src/parser/Expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,19 @@ export class SourceLiteralExpression extends Expression {
case TokenKind.SourceFunctionNameLiteral:
text = `"${this.getFunctionName(state, ParseMode.BrighterScript)}"`;
break;
case TokenKind.SourceNamespaceNameLiteral:
let namespaceParts = this.getFunctionName(state, ParseMode.BrighterScript).split('.');
namespaceParts.pop(); // remove the function name

text = `"${namespaceParts.join('.')}"`;
break;
case TokenKind.SourceNamespaceRootNameLiteral:
let namespaceRootParts = this.getFunctionName(state, ParseMode.BrighterScript).split('.');
namespaceRootParts.pop(); // remove the function name

let rootNamespace = namespaceRootParts.shift() ?? '';
text = `"${rootNamespace}"`;
break;
case TokenKind.SourceLocationLiteral:
const locationUrl = fileUrl(state.srcPath);
//TODO find first parent that has range, or default to -1
Expand Down

0 comments on commit bc54435

Please sign in to comment.