BrighterScript
repository·master·Indexed 41 days ago
https://github.com/rokucommunity/brighterscriptA superset of Roku's BrightScript language (version 0.73.5) that adds modern programming features such as classes, namespaces, imports, template strings, and the ternary operator. It transpiles to standard BrightScript for full compatibility with all Roku devices and includes a CLI compiler (bsc) for syntax checking, static analysis, and project packaging.
What's inside BrighterScript
- BrighterScript is a superset of Roku's BrightScript language. It is designed to enhance the Roku channel developer experience by providing new functionality and enhanced syntax support that is not available in standard BrightScript.
Use Annotations in BrighterScript
masterAnnotations are metadata markers that can be used, most commonly by plugins, to change or manipulate code during the compilation lifecycle based on the presence of the annotation.
'mostly useful for plugins that change code based on annotations @logOnException() sub doSomething() '... endNesting Namespaces
masterYou can define hierarchical namespaces in two ways:
- Dotted Identifiers: Using a single declaration with dots (e.g.,
namespace A.B). - Nested Blocks: Declaring a namespace inside another namespace block.
Both methods result in the same underscore-separated transpiled names.
namespace Vertibrates namespace Birds sub Quack() end sub end namespace namespace Reptiles sub Hiss() end sub end namespace end namespace- Dotted Identifiers: Using a single declaration with dots (e.g.,
How null-coalescing scope protection works
masterBrighterScript uses two different transpilation strategies for the
??operator to balance performance and safety:Simple Transpilation: If BrighterScript determines that both the consequent (left side) and the alternate (right side) are side-effect free and will not cause a rendezvous, it uses a high-performance call to
bslib_coalesce.Scope Capturing: If the expressions involve side effects or potential rendezvous, BrighterScript wraps the operation in an immediately-invoked-function-expression (IIFE). This captures local variables and ensures that the consequent is evaluated exactly once, and the alternate is only evaluated if the consequent is
invalid.
// Simple (side-effect free) userId = createdUserId ?? -1 // Scope Capturing (potential side effects/rendezvous) name = userA.name ?? userB.nameBrighterScript language features
masterBrighterScript is a superset of Roku's BrightScript. It transpiles to standard BrightScript, ensuring full compatibility with all Roku devices while providing modern syntax enhancements.
Key Language Features
- Import statements: Declare imports in scripts instead of XML tags. The compiler automatically manages script tags and dependencies in XML components.
- Classes: Supports class inheritance, method overrides, and access modifiers (
public,protected,private) with compile-time enforcement. - Namespaces: Prevents naming collisions by automatically prefixing methods within a namespace block.
- Ternary operator:
username = m.user <> invalid ? m.user.name : "not logged in" - Template strings:
print `Hello ${firstNameVar}` - Null-coalescing operator:
user = m.user ?? getDefaultUser() - Upcoming: Null-conditional operator (
userSettings = m.user?.account?.profile?.settings)
Use BrighterScript Annotations
masterAnnotations allow you to attach metadata to statements, functions, or classes. This metadata is used by plugins during the compilation process to modify how code is transpiled or analyzed.
Important: Annotations are purely for compile-time use. They are completely removed during transpilation and are not available at runtime in the resulting BrightScript code.
@expose class MyComp end class @task @export_fields([content, result]) function init() end functionImport Modules
masterUse the
importkeyword to bring in code from other files using thepkg:/URI scheme.import "pkg:/source/util.bs" sub main() print util_toUpper("hello world") end subHow BrighterScript Enums work at runtime
masterBrighterScript Enums are a compile-time construct used to define sets of named constants. They do not exist at runtime. When the code is transpiled, the enum name and its members are replaced by their literal values directly in the output BrightScript code. This means there is no runtime overhead for using enums, but you cannot inspect the enum structure (like getting a list of all members) during execution.How file exclusion works in the BrighterScript language server
masterThe language server determines which files to process by combining multiple exclusion sources. The final set of processed files is the result of applying all the following rules:
- VS Code built-in exclusions:
files.exclude: Files hidden from the VS Code file explorer.files.watcherExclude: Files ignored by the file watcher.search.exclude: Files ignored during search operations.
- BrighterScript-specific exclusions:
brightscript.languageServer.projectDiscoveryExclude: Files ignored during project discovery.
- Standard exclusions:
- Patterns defined in
.gitignore. - Common directories:
node_modules,.git,out, and.roku-deploy-staging.
- Patterns defined in
- VS Code built-in exclusions:
Define Constants
masterYou can define immutable values using the
constkeyword.const API_URL = "https://api.acme.com/v1/" sub main() print API_URL end subIntegrate BrighterScript with IDEs via Language Server Protocol
masterBrighterScript provides a
LanguageServerclass that implements Microsoft's Language Server Protocol (LSP). This allows developers to integrate BrighterScript support into any IDE that supports LSP.The
vscode-BrightScript-languageextension for Visual Studio Code is a primary example of an implementation using this class.Naming conventions for BrighterScript plugins
masterTo improve discoverability on npm, follow these naming conventions when publishing your plugins:
- Unscoped packages: Use the prefix
bsc-plugin-(e.g.,bsc-plugin-auto-findnode). - Scoped packages: Use the format
@<scope>/bsc-plugin-<plugin-name>(e.g.,@rokucommunity/bsc-plugin-auto-findnode) or@<scope>/bsc-plugin(e.g.,@maestro/bsc-plugin).
- Unscoped packages: Use the prefix