Skip to content
Draft
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
2 changes: 1 addition & 1 deletion generated/lua_keywords_pretty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ This file is auto-generated by https://github.com/secondlife/lsl-definitions. --
<key>number</key>
<map>
<key>tooltip</key>
<string>Double‑precision floating point number.</string>
<string>Double‑precision (64-bit) floating point number.</string>
</map>
<key>string</key>
<map>
Expand Down
6 changes: 3 additions & 3 deletions generated/syntax/slua.tmLanguage
Original file line number Diff line number Diff line change
Expand Up @@ -488,19 +488,19 @@
<key>name</key>
<string>constant.numeric.hex.luau</string>
<key>match</key>
<string>\b0_*[xX]_*[\da-fA-F_]*(?:[eE][\+\-]?_*\d[\d_]*(?:\.[\d_]*)?)?</string>
<string>\b0_*[xX]_*[\da-fA-F_]*(?:i|[eE][\+\-]?_*\d[\d_]*(?:\.[\d_]*)?)?</string>

@tapple tapple Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The only integer/class change this doesn't exclude is the 4i syntax in the markdown file, as it was added in the template and not in the generator. But, I think that's the most harmless part of the change

</dict>
<dict>
<key>name</key>
<string>constant.numeric.binary.luau</string>
<key>match</key>
<string>\b0_*[bB][01_]+(?:[eE][\+\-]?_*\d[\d_]*(?:\.[\d_]*)?)?</string>
<string>\b0_*[bB][01_]+(?:i|[eE][\+\-]?_*\d[\d_]*(?:\.[\d_]*)?)?</string>
</dict>
<dict>
<key>name</key>
<string>constant.numeric.decimal.luau</string>
<key>match</key>
<string>(?:\d[\d_]*(?:\.[\d_]*)?|\.\d[\d_]*)(?:[eE][\+\-]?_*\d[\d_]*(?:\.[\d_]*)?)?</string>
<string>(?:\d[\d_]*(?:\.[\d_]*)?|\.\d[\d_]*)(?:i|[eE][\+\-]?_*\d[\d_]*(?:\.[\d_]*)?)?</string>
</dict>
</array>
</dict>
Expand Down
6 changes: 3 additions & 3 deletions generated/syntax/slua.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,15 @@
"patterns": [
{
"name": "constant.numeric.hex.luau",
"match": "\\b0_*[xX]_*[\\da-fA-F_]*(?:[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?"
"match": "\\b0_*[xX]_*[\\da-fA-F_]*(?:i|[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?"
},
{
"name": "constant.numeric.binary.luau",
"match": "\\b0_*[bB][01_]+(?:[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?"
"match": "\\b0_*[bB][01_]+(?:i|[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?"
},
{
"name": "constant.numeric.decimal.luau",
"match": "(?:\\d[\\d_]*(?:\\.[\\d_]*)?|\\.\\d[\\d_]*)(?:[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?"
"match": "(?:\\d[\\d_]*(?:\\.[\\d_]*)?|\\.\\d[\\d_]*)(?:i|[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?"
}
]
},
Expand Down
12 changes: 10 additions & 2 deletions lsl_definitions/generators/keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,16 @@ def dump_slua_syntax(
header_comment = b"""<!-- SLua (Server Lua) keywords file for Second Life Viewer.
This file is auto-generated by https://github.com/secondlife/lsl-definitions. -->"""
syntax = {
"controls": slua_definitions.controls.copy(),
"types": slua_definitions.builtin_types.copy(),
"controls": {
k: v
for k, v in slua_definitions.controls.items()
if not v.get("typechecker", {}).get("fflag-disabled", False)
},
"types": {
k: v
for k, v in slua_definitions.builtin_types.items()
if not v.get("typechecker", {}).get("fflag-disabled", False)
},
"constants": {},
"events": {},
"functions": {},
Expand Down
10 changes: 6 additions & 4 deletions lsl_definitions/generators/slua.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ def gen_luau_lsp_defs(definitions: LSLDefinitions, slua_definitions: SLuaDefinit
class_.write_luau_def(defs)
defs.write("\n")
for func in slua_definitions.functions:
if func.private or func.local_only:
if not func.show_in_syntax_files:
continue
if not func.typechecker_flags.fully_defined:
defs.write("-- ")
func.write_luau_global_def(defs)
for module in sorted(slua_definitions.modules, key=lambda x: x.name):
if module.name in {"ll", "llcompat"}:
if module.name in {"ll", "llcompat"} or module.typechecker_flags.fflag_disabled:
continue
if module.name == "string":
defs.write(
Expand Down Expand Up @@ -196,6 +196,8 @@ def selene_class(class_: SLuaClassDeclaration) -> dict:

def selene_module(module: SLuaModule) -> dict:
globals = {}
if module.typechecker_flags.fflag_disabled:
return globals
if module.callable:
globals[module.name] = selene_function(module.callable)
globals.update(
Expand All @@ -211,7 +213,7 @@ def selene_module(module: SLuaModule) -> dict:
f"{module.name}.{func.name}": selene_function(func)
# for func in sorted(self.functions, key=lambda x: x.name)
for func in module.functions
if not func.private and not func.local_only
if func.show_in_syntax_files
}
)
return globals
Expand All @@ -234,7 +236,7 @@ def selene_module(module: SLuaModule) -> dict:
if not const.private:
selene["globals"][const.name] = selene_property(const)
for func in sorted(slua_definitions.functions, key=lambda x: x.name):
if not func.private and not func.local_only:
if func.show_in_syntax_files:
selene["globals"][func.name] = selene_function(func)
for module in sorted(modules.values(), key=lambda x: x.name):
if module.name not in {"ll", "llcompat"}:
Expand Down
6 changes: 4 additions & 2 deletions lsl_definitions/generators/slua_lsp_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def add_constant(self, const: SLuaProperty, module: str | None = None):
self.docs[f"{GLOBALS_PREFIX}{module_prefix}{const.name}"] = entry

def add_module(self, module: SLuaModule) -> None:
if module.typechecker_flags.fflag_disabled:
return
if module.callable:
self.add_function(module.callable)
else:
Expand All @@ -95,7 +97,7 @@ def add_module(self, module: SLuaModule) -> None:
self.add_constant(const, module=module.name)
# for func in sorted(self.functions, key=lambda x: x.name)
for func in module.functions:
if not func.private and not func.local_only:
if func.show_in_syntax_files:
self.add_function(func, module=module.name)


Expand All @@ -120,7 +122,7 @@ def gen_slua_lsp_docs(definitions: LSLDefinitions, slua_definitions: SLuaDefinit
# if not const.private and const.name != "rotation":
# selene["globals"][const.name] = selene_property(const)
for func in slua_definitions.functions:
if not func.private and not func.local_only and not func.slua_removed:
if func.show_in_syntax_files and not func.slua_removed:
builder.add_function(func)
for module in sorted(modules.values(), key=lambda x: x.name):
if module.name not in {"ll", "llcompat"}:
Expand Down
27 changes: 18 additions & 9 deletions lsl_definitions/generators/textmate.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,18 @@ def get_slua_global_constants_for_module(module: SLuaModule) -> str:
return f"{module.name}{constants}"

def get_slua_global_constants(definitions: SLuaDefinitions) -> str:
constants = [get_slua_global_constants_for_module(m) for m in definitions.modules]
constants = [
get_slua_global_constants_for_module(m)
for m in definitions.modules
if not m.typechecker_flags.fflag_disabled
]
constants.sort()
return "|".join(constants)

def get_slua_module_regex(module: SLuaModule) -> str:
if module.name in {"ll", "llcompat"}:
return None
functions = [f.name for f in module.functions if not f.private and not f.local_only]
functions = [f.name for f in module.functions if f.show_in_syntax_files]
functions.sort()
functions = "|".join(functions)
if len(functions) < 1:
Expand All @@ -122,7 +126,11 @@ def get_LL_constants(slua_definitions: SLuaDefinitions) -> str:
return crunch_regex_strings(constants)

def get_slua_modules(definitions: SLuaDefinitions) -> str:
modules = [get_slua_module_regex(m) for m in definitions.modules]
modules = [
get_slua_module_regex(m)
for m in definitions.modules
if not m.typechecker_flags.fflag_disabled
]
modules = [m for m in modules if m is not None]
modules.sort()
return "|".join(modules)
Expand All @@ -131,25 +139,26 @@ def get_LL_module_functions(definitions: SLuaDefinitions) -> str:
functions = [
f.name
for f in definitions.get_module("ll").functions
if not f.private and not f.local_only and not f.slua_removed and f.deprecated is None
if f.show_in_syntax_files and not f.slua_removed and f.deprecated is None
]
return crunch_regex_strings(functions)

def get_LL_module_deprecated_functions(definitions: SLuaDefinitions) -> str:
functions = [
f.name
for f in definitions.get_module("ll").functions
if not f.private
and not f.local_only
and not f.slua_removed
and f.deprecated is not None
if f.show_in_syntax_files and not f.slua_removed and f.deprecated is not None
]
return crunch_regex_strings(functions)

def get_slua_global_types(definitions: SLuaDefinitions) -> str:
# Missing types that are not documented in builtins, classes or aliases
missing_types = ["nil"]
builtin_types = [t for t in definitions.builtin_types.keys()]
builtin_types = [
t
for t in definitions.builtin_types.keys()
if not definitions.builtin_types[t].get("typechecker", {}).get("fflag-disabled", False)
]
base_classes = [b.name for b in definitions.base_classes]
type_aliases = [t.name for t in definitions.type_aliases if t.export]
return "|".join(missing_types + builtin_types + base_classes + type_aliases)
Expand Down
32 changes: 29 additions & 3 deletions lsl_definitions/slua.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class SLuaTypecheckerFlags:
"""
checked: bool = False
"""Raises an error if types are incorrect. Causes !nonstrict to behave like !strict."""
fflag_disabled: bool = False
"""This function is present in Luau, but is temporarily disabled by a feature flag in SLua. Exclude it from syntax files."""

@property
def fully_defined(self) -> bool:
Expand All @@ -139,6 +141,15 @@ def comment_string(self) -> str:
comments.append("magic type")
return " -- " + ", ".join(comments) if comments else ""

@classmethod
def from_dict(cls, d: dict) -> SLuaTypecheckerFlags:
return cls(
builtin=d.get("builtin", False),
magic=d.get("magic", False),
checked=d.get("checked", False),
fflag_disabled=d.get("fflag-disabled", False),
)


@dataclasses.dataclass
class SLuaFunctionBase(abc.ABC):
Expand Down Expand Up @@ -185,6 +196,12 @@ class SLuaFunction(SLuaFunctionBase):
"""Flags specific to the internals of luau-analyze and luau-lsp."""
overloads: list[SLuaFunctionOverload] = dataclasses.field(default_factory=list)

@property
def show_in_syntax_files(self) -> bool:
return (
not self.private and not self.local_only and not self.typechecker_flags.fflag_disabled
)

@property
def annotation_string(self) -> str:
annotation = ""
Expand Down Expand Up @@ -353,9 +370,15 @@ class SLuaModule:
constants: list[SLuaProperty]
functions: list[SLuaFunction]
comment: str = ""
typechecker_flags: SLuaTypecheckerFlags = dataclasses.field(
default_factory=SLuaTypecheckerFlags
)
"""Flags specific to the internals of luau-analyze and luau-lsp."""

def to_keywords_functions_dict(self) -> dict:
functions = {}
if self.typechecker_flags.fflag_disabled:
return functions
if self.callable:
functions[self.name] = self.callable.to_keywords_dict()
else:
Expand All @@ -364,12 +387,14 @@ def to_keywords_functions_dict(self) -> dict:
{
f"{self.name}.{func.name}": func.to_keywords_dict()
for func in sorted(self.functions, key=lambda x: x.name)
if not func.private and not func.local_only
if func.show_in_syntax_files
}
)
return functions

def to_keywords_constants_dict(self) -> dict:
if self.typechecker_flags.fflag_disabled:
return {}
return {
f"{self.name}.{prop.name}": prop.to_keywords_dict()
for prop in sorted(self.constants, key=lambda x: x.name)
Expand Down Expand Up @@ -403,7 +428,7 @@ def write_luau_def(self, f: TextIO) -> None:
for prop in self.constants:
f.write(f" {prop.to_luau_def()},\n")
for func in self.functions:
if func.private or func.local_only:
if not func.show_in_syntax_files:
continue
func.write_luau_table_def(f, indent=1)
f.write("}\n\n")
Expand Down Expand Up @@ -872,6 +897,7 @@ def _validate_module(self, data: dict) -> SLuaModule:
callable=None,
constants=[],
functions=[],
typechecker_flags=SLuaTypecheckerFlags.from_dict(data.get("typechecker", {})),
)
try:
self._validate_identifier(module.name)
Expand Down Expand Up @@ -947,7 +973,7 @@ def _validate_function(
local_only=data.get("local-only", False),
slua_removed=data.get("slua-removed", False),
must_use=data.get("must-use", False),
typechecker_flags=SLuaTypecheckerFlags(**data.get("typechecker", {})),
typechecker_flags=SLuaTypecheckerFlags.from_dict(data.get("typechecker", {})),
)
self._validate_identifier(func.name)
self._validate_scope(func.name, scope)
Expand Down
Loading
Loading