@tilua/parser 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -298,6 +298,18 @@ call needed it — and the receiver is passed as the call's first argument. An
298
298
  answer of `undefined` leaves an ordinary Luau method call, which is what
299
299
  `text:upper()` wants, since a string already answers to it.
300
300
 
301
+ A call can also carry more than was written. Every hook is told `at`, where
302
+ the call was written (`{ file, line, column }`), and `arguments`: each one's
303
+ type, that type as text, the code it was written as, and, for a name, the
304
+ code of what it names. An answer's `prepend` lists Luau expressions to pass
305
+ ahead of the written arguments. `globalCall` answers for a call to a global,
306
+ such as `print(x)`, and `globalValue` for a global read as a value, such as
307
+ `local p = print`. A local with the same name belongs to the author, and no
308
+ hook is asked about it. A runtime can read `__LINES__`, the bundle's line map
309
+ (`nil` outside a bundle), to turn a line Luau reports back into a place in the
310
+ project. `console:log`, `print` and `error` in `@tilua-types/lua` are built on
311
+ these hooks.
312
+
301
313
  The compiler lowers the language and nothing else: `filter` appears nowhere in
302
314
  it.
303
315
 
@@ -406,6 +418,14 @@ method's type is `(this: Dog, ...) => R`, so `rex:speak()` supplies it the way
406
418
  `function T:m()` supplies `self`. `new Dog(x)` *is* `Dog.new(x)` — the same
407
419
  function, callable by hand and passable as a value.
408
420
 
421
+ **`public` and `private`** go before a member — `private balance = 0`,
422
+ `private static function check()`, `public get size()`. Leaving it out means
423
+ public. A private member can be reached only inside the body of the class that
424
+ declared it, including functions nested in its methods; a subclass is outside,
425
+ as in TypeScript. It is a type check and nothing more: the member is an
426
+ ordinary key at runtime. `public` and `private` stay ordinary names elsewhere,
427
+ so `private: boolean` is still a field.
428
+
409
429
  A declaration names two things. As a **type**, `Dog` is the type of its
410
430
  instances, nominal the same way a `declare class` is: a table with the same
411
431
  members is not one, and only `Dog` and what extends it are assignable to it.
package/dist/index.cjs CHANGED
@@ -1830,6 +1830,19 @@ var Parser = class {
1830
1830
  }
1831
1831
  parseClassMember() {
1832
1832
  const start = this.current();
1833
+ let accessibility;
1834
+ if ((this.checkIdentifierValue("public") || this.checkIdentifierValue("private")) && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=") && !this.punctuatorAt(1, "(")) {
1835
+ accessibility = this.advance().value;
1836
+ }
1837
+ const member = this.parseClassMemberAfterAccessibility(start);
1838
+ if (!accessibility || !member) return member;
1839
+ if (member.type === "ClassConstructor") {
1840
+ this.problem(`A constructor cannot be '${accessibility}'`);
1841
+ return member;
1842
+ }
1843
+ return { ...member, accessibility };
1844
+ }
1845
+ parseClassMemberAfterAccessibility(start) {
1833
1846
  const isStatic = this.checkIdentifierValue("static") && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=");
1834
1847
  if (isStatic) this.advance();
1835
1848
  if (this.checkKeyword("function")) {
@@ -5896,13 +5909,18 @@ var TypeAnalyzer = class {
5896
5909
  classIdentityCount = 0;
5897
5910
  /** The class whose members are being read, so `super` knows its base. */
5898
5911
  currentClass;
5912
+ /** Every class whose body the checker is inside, innermost last — what
5913
+ * decides whether a `private` member may be reached. */
5914
+ enclosingClasses = [];
5899
5915
  withClass(stmt, fn2) {
5900
5916
  const previous = this.currentClass;
5901
5917
  this.currentClass = stmt;
5918
+ this.enclosingClasses.push(stmt);
5902
5919
  try {
5903
5920
  return fn2();
5904
5921
  } finally {
5905
5922
  this.currentClass = previous;
5923
+ this.enclosingClasses.pop();
5906
5924
  }
5907
5925
  }
5908
5926
  /** What the class is known by. A declaration is known by its name, the way
@@ -6120,8 +6138,11 @@ var TypeAnalyzer = class {
6120
6138
  return shape;
6121
6139
  }
6122
6140
  fillShape(stmt, shape) {
6141
+ const className = this.className(stmt);
6123
6142
  const put = (isStatic, name, property) => {
6124
- (isStatic ? shape.statics : shape.instance).set(name, property);
6143
+ const member = stmt.members.find((m) => m.type !== "ClassConstructor" && m.isStatic === isStatic && m.name.name === name && m.accessibility === "private");
6144
+ const marked = member ? { ...property, private: { owner: stmt, className } } : property;
6145
+ (isStatic ? shape.statics : shape.instance).set(name, marked);
6125
6146
  };
6126
6147
  for (const member of stmt.members) {
6127
6148
  if (member.type !== "ClassField") continue;
@@ -8578,6 +8599,28 @@ var TypeAnalyzer = class {
8578
8599
  message: names.length === 1 ? `'${names[0]}' does not exist on a string` : `'${briefType(key)}' does not name a member of a string`
8579
8600
  });
8580
8601
  }
8602
+ /** A `private` member read from outside the class that declared it —
8603
+ * a subclass counts as outside, as in TypeScript. */
8604
+ checkPrivateMember(node, object, name) {
8605
+ if (!this.emitDiagnostics) return;
8606
+ const raw = this.expand(object);
8607
+ for (const part of raw.kind === "union" ? raw.types : [raw]) {
8608
+ const t = this.deferredAccess(this.expand(part));
8609
+ if (t.kind !== "object") continue;
8610
+ const access = t.properties.get(name)?.private;
8611
+ if (!access || this.insideClass(access.owner)) continue;
8612
+ this.diagnostics.push({
8613
+ node,
8614
+ message: `Property '${name}' is private and only accessible within class '${access.className}'`
8615
+ });
8616
+ return;
8617
+ }
8618
+ }
8619
+ /** Is the code being checked written inside `owner`'s body — its own
8620
+ * methods, or a class or function nested in them? */
8621
+ insideClass(owner) {
8622
+ return this.enclosingClasses.includes(owner);
8623
+ }
8581
8624
  propertyType(raw, name) {
8582
8625
  const t = this.deferredAccess(this.expand(raw));
8583
8626
  if (t.kind === "object") {
@@ -8795,6 +8838,7 @@ var TypeAnalyzer = class {
8795
8838
  }
8796
8839
  case "MemberExpression": {
8797
8840
  const { type: obj, shortCircuits } = this.chainObject(expr, expr.object, env);
8841
+ this.checkPrivateMember(expr.property, obj, expr.property.name);
8798
8842
  const key = this.refKeyOf(expr);
8799
8843
  const narrowed = key === void 0 ? void 0 : env.get(key);
8800
8844
  this.checkStringMember(expr, obj, literal(expr.property.name));
@@ -8930,6 +8974,7 @@ var TypeAnalyzer = class {
8930
8974
  });
8931
8975
  }
8932
8976
  inferMethodCall(expr, objType, env) {
8977
+ this.checkPrivateMember(expr.method, objType, expr.method.name);
8933
8978
  const method = this.propertyType(objType, expr.method.name);
8934
8979
  const united = this.unionSignatures(method);
8935
8980
  const fns = united ?? this.overloadsOf(method);
package/dist/index.d.cts CHANGED
@@ -377,11 +377,16 @@ type ClassMember = ClassField | ClassMethod | ClassAccessor | ClassConstructor;
377
377
  /** The two ways a class is written. Everything after parsing treats them
378
378
  * alike: only the name and the type parameters differ. */
379
379
  type ClassLike = ClassDeclaration | ClassExpression;
380
+ /** `public` / `private` written before a member. Only the type checker reads
381
+ * it: a private member is still an ordinary key at runtime. */
382
+ type ClassAccessibility = "public" | "private";
380
383
  /** `x: number` / `x = 1` / `static count = 0`. An instance field is assigned
381
384
  * when the instance is built, before the constructor body runs; a `static`
382
385
  * one is assigned on the class table, once. */
383
386
  interface ClassField extends BaseNode {
384
387
  type: "ClassField";
388
+ /** Left out, the member is public. */
389
+ accessibility?: ClassAccessibility;
385
390
  name: Identifier;
386
391
  isStatic: boolean;
387
392
  typeAnnotation?: TypeNode;
@@ -391,6 +396,8 @@ interface ClassField extends BaseNode {
391
396
  * A `static` one is a plain function on the class table, with no `this`. */
392
397
  interface ClassMethod extends BaseNode {
393
398
  type: "ClassMethod";
399
+ /** Left out, the member is public. */
400
+ accessibility?: ClassAccessibility;
394
401
  name: Identifier;
395
402
  isStatic: boolean;
396
403
  func: FunctionBody;
@@ -401,6 +408,8 @@ interface ClassMethod extends BaseNode {
401
408
  * property, run as a function. */
402
409
  interface ClassAccessor extends BaseNode {
403
410
  type: "ClassAccessor";
411
+ /** Left out, the member is public. */
412
+ accessibility?: ClassAccessibility;
404
413
  kind: "get" | "set";
405
414
  name: Identifier;
406
415
  isStatic: boolean;
@@ -1117,6 +1126,13 @@ interface ObjectProperty {
1117
1126
  type: Type;
1118
1127
  optional: boolean;
1119
1128
  readonly?: boolean;
1129
+ /** A class member written `private`: reachable only from inside the class
1130
+ * that declared it. `owner` is that class's node, compared by identity;
1131
+ * `className` is how a diagnostic names it. Checked, never lowered. */
1132
+ private?: {
1133
+ owner: object;
1134
+ className: string;
1135
+ };
1120
1136
  }
1121
1137
  interface ObjectType {
1122
1138
  kind: "object";
@@ -1609,9 +1625,20 @@ declare function resolveTypeLibraries(config: TiluaConfig, host?: ProjectHost):
1609
1625
 
1610
1626
  interface LoweringPlugin {
1611
1627
  /** Luau the plugin needs in the output, by a key it chooses. Each is a
1612
- * file's worth of source with `__NAME__` standing for the local the
1613
- * compiler gives it, and each is emitted once, at the top of the output,
1614
- * only if `use` asked for it:
1628
+ * file's worth of source, emitted once, at the top of the output, only if
1629
+ * `use` asked for it. Two names in it are filled in by the compiler:
1630
+ *
1631
+ * - `__NAME__`, the local the compiler gives this runtime;
1632
+ * - `__LINES__`, an expression holding the bundle's line map —
1633
+ * `{ [bundleLine] = { "src/a.tilua", sourceLine } }` — or `nil` when
1634
+ * the output is not a bundle. It is what turns a line Luau reports at
1635
+ * runtime back into a place in the project;
1636
+ * - `__FAIL__`, the bundle's error reporter, or `nil` outside a bundle:
1637
+ * a function that takes an error and returns it with the bundle's
1638
+ * positions replaced by the project's, followed by a traceback of
1639
+ * those. It is an `xpcall` handler — the one the entry runs under —
1640
+ * so a runtime that runs a callback on a thread of its own can report
1641
+ * that callback's errors the same way.
1615
1642
  *
1616
1643
  * local __NAME__ = {}
1617
1644
  * function __NAME__.filter(t, test) ... end
@@ -1621,24 +1648,84 @@ interface LoweringPlugin {
1621
1648
  * method call, which is what a value that answers to the method itself
1622
1649
  * wants — `text:upper()` reaches Lua's own. */
1623
1650
  methodCall?(call: MethodCall): MethodLowering | undefined;
1651
+ /** What a call to a global — `print(...)`, `error(...)` — becomes. Asked
1652
+ * only when the name really is the global: a local the author called
1653
+ * `print` is theirs. `undefined` leaves the call as it was written. */
1654
+ globalCall?(call: GlobalCall): CallLowering | undefined;
1655
+ /** What a global read as a value — `task.spawn(print, x)`, `local p =
1656
+ * print` — becomes: a Luau expression, usually built from `use(...)`.
1657
+ * There is no call site to describe here, so this is where a plugin
1658
+ * that rewrites calls keeps the rest of the program consistent with it. */
1659
+ globalValue?(value: GlobalValue): string | undefined;
1660
+ }
1661
+ /** Where a call was written. */
1662
+ interface CallSite {
1663
+ /** The file, relative to the project root with `/` separators, or
1664
+ * `undefined` when a single source was compiled with no name. */
1665
+ readonly file: string | undefined;
1666
+ /** 1-based. */
1667
+ readonly line: number;
1668
+ /** 1-based. */
1669
+ readonly column: number;
1670
+ }
1671
+ /** What the compiler knows about one argument that the runtime will not. */
1672
+ interface ArgumentInfo {
1673
+ /** Its type, as the analyzer worked it out. */
1674
+ readonly type: Type | undefined;
1675
+ /** That type as the editor would show it — `(x: number) => number` —
1676
+ * so a library can print it without depending on this package. */
1677
+ readonly typeText: string | undefined;
1678
+ /** The code it was written as, at the call. */
1679
+ readonly source: string;
1680
+ /** For a name, the code of what it names — the value of `const f = ...`,
1681
+ * or the whole `function f() { ... }` — when this file declares it. */
1682
+ readonly declaration?: string;
1683
+ /** Written `...xs`. */
1684
+ readonly spread: boolean;
1685
+ }
1686
+ interface CallContext {
1687
+ /** Where the call was written. */
1688
+ readonly at: CallSite;
1689
+ /** Each written argument, in order. */
1690
+ readonly arguments: readonly ArgumentInfo[];
1691
+ /** The local name the output gives one of `runtime`'s entries, emitting
1692
+ * it if this is the first call that needed it. */
1693
+ use(runtime: string): string;
1624
1694
  }
1625
- interface MethodCall {
1695
+ interface MethodCall extends CallContext {
1626
1696
  /** The name written after `:`. */
1627
1697
  readonly method: string;
1628
1698
  /** The receiver's type, as the analyzer worked it out. `undefined` when
1629
1699
  * nothing typed it, where a plugin should decline rather than guess. */
1630
1700
  readonly receiver: Type | undefined;
1701
+ /** The receiver's name when it is a global — `console` in
1702
+ * `console:log(x)` — and `undefined` for anything else, a local of the
1703
+ * same name included. */
1704
+ readonly receiverGlobal: string | undefined;
1631
1705
  /** How many arguments were written. */
1632
1706
  readonly argumentCount: number;
1633
- /** The local name the output gives one of `runtime`'s entries, emitting
1634
- * it if this is the first call that needed it. */
1707
+ }
1708
+ interface GlobalCall extends CallContext {
1709
+ /** The global called. */
1710
+ readonly name: string;
1711
+ }
1712
+ interface GlobalValue {
1713
+ /** The global read. */
1714
+ readonly name: string;
1715
+ readonly at: CallSite;
1635
1716
  use(runtime: string): string;
1636
1717
  }
1637
- interface MethodLowering {
1718
+ interface CallLowering {
1638
1719
  /** What to call instead: a name, or a `table.member` path — usually built
1639
1720
  * from `use(...)`. */
1640
1721
  readonly callee: string;
1641
- /** Pass the receiver as the first argument. Default: yes. */
1722
+ /** Luau expressions passed ahead of the written arguments — the call
1723
+ * site, say, or a table of what the compiler knew about them. */
1724
+ readonly prepend?: readonly string[];
1725
+ }
1726
+ interface MethodLowering extends CallLowering {
1727
+ /** Pass the receiver as the first argument, after `prepend`. Default:
1728
+ * yes. */
1642
1729
  readonly passReceiver?: boolean;
1643
1730
  }
1644
1731
 
@@ -1688,4 +1775,4 @@ declare const tilua: {
1688
1775
  readonly analyzeTypes: typeof analyzeTypes;
1689
1776
  };
1690
1777
 
1691
- export { type AnalyzeTypesOptions, type AnyType, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallStatement, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypeOrigin, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
1778
+ export { type AnalyzeTypesOptions, type AnyType, type ArgumentInfo, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallLowering, type CallSite, type CallStatement, type ClassAccessibility, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type GlobalCall, type GlobalValue, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypeOrigin, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
package/dist/index.d.ts CHANGED
@@ -377,11 +377,16 @@ type ClassMember = ClassField | ClassMethod | ClassAccessor | ClassConstructor;
377
377
  /** The two ways a class is written. Everything after parsing treats them
378
378
  * alike: only the name and the type parameters differ. */
379
379
  type ClassLike = ClassDeclaration | ClassExpression;
380
+ /** `public` / `private` written before a member. Only the type checker reads
381
+ * it: a private member is still an ordinary key at runtime. */
382
+ type ClassAccessibility = "public" | "private";
380
383
  /** `x: number` / `x = 1` / `static count = 0`. An instance field is assigned
381
384
  * when the instance is built, before the constructor body runs; a `static`
382
385
  * one is assigned on the class table, once. */
383
386
  interface ClassField extends BaseNode {
384
387
  type: "ClassField";
388
+ /** Left out, the member is public. */
389
+ accessibility?: ClassAccessibility;
385
390
  name: Identifier;
386
391
  isStatic: boolean;
387
392
  typeAnnotation?: TypeNode;
@@ -391,6 +396,8 @@ interface ClassField extends BaseNode {
391
396
  * A `static` one is a plain function on the class table, with no `this`. */
392
397
  interface ClassMethod extends BaseNode {
393
398
  type: "ClassMethod";
399
+ /** Left out, the member is public. */
400
+ accessibility?: ClassAccessibility;
394
401
  name: Identifier;
395
402
  isStatic: boolean;
396
403
  func: FunctionBody;
@@ -401,6 +408,8 @@ interface ClassMethod extends BaseNode {
401
408
  * property, run as a function. */
402
409
  interface ClassAccessor extends BaseNode {
403
410
  type: "ClassAccessor";
411
+ /** Left out, the member is public. */
412
+ accessibility?: ClassAccessibility;
404
413
  kind: "get" | "set";
405
414
  name: Identifier;
406
415
  isStatic: boolean;
@@ -1117,6 +1126,13 @@ interface ObjectProperty {
1117
1126
  type: Type;
1118
1127
  optional: boolean;
1119
1128
  readonly?: boolean;
1129
+ /** A class member written `private`: reachable only from inside the class
1130
+ * that declared it. `owner` is that class's node, compared by identity;
1131
+ * `className` is how a diagnostic names it. Checked, never lowered. */
1132
+ private?: {
1133
+ owner: object;
1134
+ className: string;
1135
+ };
1120
1136
  }
1121
1137
  interface ObjectType {
1122
1138
  kind: "object";
@@ -1609,9 +1625,20 @@ declare function resolveTypeLibraries(config: TiluaConfig, host?: ProjectHost):
1609
1625
 
1610
1626
  interface LoweringPlugin {
1611
1627
  /** Luau the plugin needs in the output, by a key it chooses. Each is a
1612
- * file's worth of source with `__NAME__` standing for the local the
1613
- * compiler gives it, and each is emitted once, at the top of the output,
1614
- * only if `use` asked for it:
1628
+ * file's worth of source, emitted once, at the top of the output, only if
1629
+ * `use` asked for it. Two names in it are filled in by the compiler:
1630
+ *
1631
+ * - `__NAME__`, the local the compiler gives this runtime;
1632
+ * - `__LINES__`, an expression holding the bundle's line map —
1633
+ * `{ [bundleLine] = { "src/a.tilua", sourceLine } }` — or `nil` when
1634
+ * the output is not a bundle. It is what turns a line Luau reports at
1635
+ * runtime back into a place in the project;
1636
+ * - `__FAIL__`, the bundle's error reporter, or `nil` outside a bundle:
1637
+ * a function that takes an error and returns it with the bundle's
1638
+ * positions replaced by the project's, followed by a traceback of
1639
+ * those. It is an `xpcall` handler — the one the entry runs under —
1640
+ * so a runtime that runs a callback on a thread of its own can report
1641
+ * that callback's errors the same way.
1615
1642
  *
1616
1643
  * local __NAME__ = {}
1617
1644
  * function __NAME__.filter(t, test) ... end
@@ -1621,24 +1648,84 @@ interface LoweringPlugin {
1621
1648
  * method call, which is what a value that answers to the method itself
1622
1649
  * wants — `text:upper()` reaches Lua's own. */
1623
1650
  methodCall?(call: MethodCall): MethodLowering | undefined;
1651
+ /** What a call to a global — `print(...)`, `error(...)` — becomes. Asked
1652
+ * only when the name really is the global: a local the author called
1653
+ * `print` is theirs. `undefined` leaves the call as it was written. */
1654
+ globalCall?(call: GlobalCall): CallLowering | undefined;
1655
+ /** What a global read as a value — `task.spawn(print, x)`, `local p =
1656
+ * print` — becomes: a Luau expression, usually built from `use(...)`.
1657
+ * There is no call site to describe here, so this is where a plugin
1658
+ * that rewrites calls keeps the rest of the program consistent with it. */
1659
+ globalValue?(value: GlobalValue): string | undefined;
1660
+ }
1661
+ /** Where a call was written. */
1662
+ interface CallSite {
1663
+ /** The file, relative to the project root with `/` separators, or
1664
+ * `undefined` when a single source was compiled with no name. */
1665
+ readonly file: string | undefined;
1666
+ /** 1-based. */
1667
+ readonly line: number;
1668
+ /** 1-based. */
1669
+ readonly column: number;
1670
+ }
1671
+ /** What the compiler knows about one argument that the runtime will not. */
1672
+ interface ArgumentInfo {
1673
+ /** Its type, as the analyzer worked it out. */
1674
+ readonly type: Type | undefined;
1675
+ /** That type as the editor would show it — `(x: number) => number` —
1676
+ * so a library can print it without depending on this package. */
1677
+ readonly typeText: string | undefined;
1678
+ /** The code it was written as, at the call. */
1679
+ readonly source: string;
1680
+ /** For a name, the code of what it names — the value of `const f = ...`,
1681
+ * or the whole `function f() { ... }` — when this file declares it. */
1682
+ readonly declaration?: string;
1683
+ /** Written `...xs`. */
1684
+ readonly spread: boolean;
1685
+ }
1686
+ interface CallContext {
1687
+ /** Where the call was written. */
1688
+ readonly at: CallSite;
1689
+ /** Each written argument, in order. */
1690
+ readonly arguments: readonly ArgumentInfo[];
1691
+ /** The local name the output gives one of `runtime`'s entries, emitting
1692
+ * it if this is the first call that needed it. */
1693
+ use(runtime: string): string;
1624
1694
  }
1625
- interface MethodCall {
1695
+ interface MethodCall extends CallContext {
1626
1696
  /** The name written after `:`. */
1627
1697
  readonly method: string;
1628
1698
  /** The receiver's type, as the analyzer worked it out. `undefined` when
1629
1699
  * nothing typed it, where a plugin should decline rather than guess. */
1630
1700
  readonly receiver: Type | undefined;
1701
+ /** The receiver's name when it is a global — `console` in
1702
+ * `console:log(x)` — and `undefined` for anything else, a local of the
1703
+ * same name included. */
1704
+ readonly receiverGlobal: string | undefined;
1631
1705
  /** How many arguments were written. */
1632
1706
  readonly argumentCount: number;
1633
- /** The local name the output gives one of `runtime`'s entries, emitting
1634
- * it if this is the first call that needed it. */
1707
+ }
1708
+ interface GlobalCall extends CallContext {
1709
+ /** The global called. */
1710
+ readonly name: string;
1711
+ }
1712
+ interface GlobalValue {
1713
+ /** The global read. */
1714
+ readonly name: string;
1715
+ readonly at: CallSite;
1635
1716
  use(runtime: string): string;
1636
1717
  }
1637
- interface MethodLowering {
1718
+ interface CallLowering {
1638
1719
  /** What to call instead: a name, or a `table.member` path — usually built
1639
1720
  * from `use(...)`. */
1640
1721
  readonly callee: string;
1641
- /** Pass the receiver as the first argument. Default: yes. */
1722
+ /** Luau expressions passed ahead of the written arguments — the call
1723
+ * site, say, or a table of what the compiler knew about them. */
1724
+ readonly prepend?: readonly string[];
1725
+ }
1726
+ interface MethodLowering extends CallLowering {
1727
+ /** Pass the receiver as the first argument, after `prepend`. Default:
1728
+ * yes. */
1642
1729
  readonly passReceiver?: boolean;
1643
1730
  }
1644
1731
 
@@ -1688,4 +1775,4 @@ declare const tilua: {
1688
1775
  readonly analyzeTypes: typeof analyzeTypes;
1689
1776
  };
1690
1777
 
1691
- export { type AnalyzeTypesOptions, type AnyType, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallStatement, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypeOrigin, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
1778
+ export { type AnalyzeTypesOptions, type AnyType, type ArgumentInfo, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallLowering, type CallSite, type CallStatement, type ClassAccessibility, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type GlobalCall, type GlobalValue, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypeOrigin, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
package/dist/index.js CHANGED
@@ -1727,6 +1727,19 @@ var Parser = class {
1727
1727
  }
1728
1728
  parseClassMember() {
1729
1729
  const start = this.current();
1730
+ let accessibility;
1731
+ if ((this.checkIdentifierValue("public") || this.checkIdentifierValue("private")) && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=") && !this.punctuatorAt(1, "(")) {
1732
+ accessibility = this.advance().value;
1733
+ }
1734
+ const member = this.parseClassMemberAfterAccessibility(start);
1735
+ if (!accessibility || !member) return member;
1736
+ if (member.type === "ClassConstructor") {
1737
+ this.problem(`A constructor cannot be '${accessibility}'`);
1738
+ return member;
1739
+ }
1740
+ return { ...member, accessibility };
1741
+ }
1742
+ parseClassMemberAfterAccessibility(start) {
1730
1743
  const isStatic = this.checkIdentifierValue("static") && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=");
1731
1744
  if (isStatic) this.advance();
1732
1745
  if (this.checkKeyword("function")) {
@@ -5793,13 +5806,18 @@ var TypeAnalyzer = class {
5793
5806
  classIdentityCount = 0;
5794
5807
  /** The class whose members are being read, so `super` knows its base. */
5795
5808
  currentClass;
5809
+ /** Every class whose body the checker is inside, innermost last — what
5810
+ * decides whether a `private` member may be reached. */
5811
+ enclosingClasses = [];
5796
5812
  withClass(stmt, fn2) {
5797
5813
  const previous = this.currentClass;
5798
5814
  this.currentClass = stmt;
5815
+ this.enclosingClasses.push(stmt);
5799
5816
  try {
5800
5817
  return fn2();
5801
5818
  } finally {
5802
5819
  this.currentClass = previous;
5820
+ this.enclosingClasses.pop();
5803
5821
  }
5804
5822
  }
5805
5823
  /** What the class is known by. A declaration is known by its name, the way
@@ -6017,8 +6035,11 @@ var TypeAnalyzer = class {
6017
6035
  return shape;
6018
6036
  }
6019
6037
  fillShape(stmt, shape) {
6038
+ const className = this.className(stmt);
6020
6039
  const put = (isStatic, name, property) => {
6021
- (isStatic ? shape.statics : shape.instance).set(name, property);
6040
+ const member = stmt.members.find((m) => m.type !== "ClassConstructor" && m.isStatic === isStatic && m.name.name === name && m.accessibility === "private");
6041
+ const marked = member ? { ...property, private: { owner: stmt, className } } : property;
6042
+ (isStatic ? shape.statics : shape.instance).set(name, marked);
6022
6043
  };
6023
6044
  for (const member of stmt.members) {
6024
6045
  if (member.type !== "ClassField") continue;
@@ -8475,6 +8496,28 @@ var TypeAnalyzer = class {
8475
8496
  message: names.length === 1 ? `'${names[0]}' does not exist on a string` : `'${briefType(key)}' does not name a member of a string`
8476
8497
  });
8477
8498
  }
8499
+ /** A `private` member read from outside the class that declared it —
8500
+ * a subclass counts as outside, as in TypeScript. */
8501
+ checkPrivateMember(node, object, name) {
8502
+ if (!this.emitDiagnostics) return;
8503
+ const raw = this.expand(object);
8504
+ for (const part of raw.kind === "union" ? raw.types : [raw]) {
8505
+ const t = this.deferredAccess(this.expand(part));
8506
+ if (t.kind !== "object") continue;
8507
+ const access = t.properties.get(name)?.private;
8508
+ if (!access || this.insideClass(access.owner)) continue;
8509
+ this.diagnostics.push({
8510
+ node,
8511
+ message: `Property '${name}' is private and only accessible within class '${access.className}'`
8512
+ });
8513
+ return;
8514
+ }
8515
+ }
8516
+ /** Is the code being checked written inside `owner`'s body — its own
8517
+ * methods, or a class or function nested in them? */
8518
+ insideClass(owner) {
8519
+ return this.enclosingClasses.includes(owner);
8520
+ }
8478
8521
  propertyType(raw, name) {
8479
8522
  const t = this.deferredAccess(this.expand(raw));
8480
8523
  if (t.kind === "object") {
@@ -8692,6 +8735,7 @@ var TypeAnalyzer = class {
8692
8735
  }
8693
8736
  case "MemberExpression": {
8694
8737
  const { type: obj, shortCircuits } = this.chainObject(expr, expr.object, env);
8738
+ this.checkPrivateMember(expr.property, obj, expr.property.name);
8695
8739
  const key = this.refKeyOf(expr);
8696
8740
  const narrowed = key === void 0 ? void 0 : env.get(key);
8697
8741
  this.checkStringMember(expr, obj, literal(expr.property.name));
@@ -8827,6 +8871,7 @@ var TypeAnalyzer = class {
8827
8871
  });
8828
8872
  }
8829
8873
  inferMethodCall(expr, objType, env) {
8874
+ this.checkPrivateMember(expr.method, objType, expr.method.name);
8830
8875
  const method = this.propertyType(objType, expr.method.name);
8831
8876
  const united = this.unionSignatures(method);
8832
8877
  const fns = united ?? this.overloadsOf(method);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tilua/parser",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "tilua parser for roblox",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",