Socket
Socket
Sign inDemoInstall

typescript-to-lua

Package Overview
Dependencies
Maintainers
2
Versions
157
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typescript-to-lua - npm Package Compare versions

Comparing version 0.22.1 to 0.23.0

9

CHANGELOG.md
# Changelog
## 0.22.0
- Added the [@vararg](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#vararg) directive.
- Added the [@forRange](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#forRange) directive.
- Custom ts transformers can now be loaded from tsconfig.
- Fixed default tstl header incorrectly showing up above lualib functions.
- Some improvements to typeof expressions.
## 0.21.0

@@ -4,0 +13,0 @@

4

dist/Emit.d.ts
import { CompilerOptions } from "./CompilerOptions";
import { TranspiledFile } from "./Transpile";
import { TranspiledFile, EmitHost } from "./Transpile";
export interface OutputFile {

@@ -7,2 +7,2 @@ name: string;

}
export declare function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: TranspiledFile[]): OutputFile[];
export declare function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: TranspiledFile[], emitHost?: EmitHost): OutputFile[];
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const ts = require("typescript");
const CompilerOptions_1 = require("./CompilerOptions");

@@ -9,3 +9,3 @@ const trimExt = (filePath) => filePath.slice(0, -path.extname(filePath).length);

let lualibContent;
function emitTranspiledFiles(options, transpiledFiles) {
function emitTranspiledFiles(options, transpiledFiles, emitHost = ts.sys) {
let { rootDir, outDir, outFile, luaLibImport } = options;

@@ -46,3 +46,9 @@ const configFileName = options.configFilePath;

if (lualibContent === undefined) {
lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8");
const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"));
if (lualibBundle !== undefined) {
lualibContent = lualibBundle;
}
else {
throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua");
}
}

@@ -49,0 +55,0 @@ let outPath = path.resolve(rootDir, "lualib_bundle.lua");

@@ -275,6 +275,7 @@ import * as ts from "typescript";

text: string;
originalName?: string;
symbolId?: SymbolId;
}
export declare function isIdentifier(node: Node): node is Identifier;
export declare function createIdentifier(text: string | ts.__String, tsOriginal?: ts.Node, symbolId?: SymbolId, parent?: Node): Identifier;
export declare function createIdentifier(text: string | ts.__String, tsOriginal?: ts.Node, symbolId?: SymbolId, originalName?: string, parent?: Node): Identifier;
export declare function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): Identifier;

@@ -281,0 +282,0 @@ export declare function createAnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier;

@@ -413,3 +413,3 @@ "use strict";

function createTableFieldExpression(value, key, tsOriginal, parent) {
const expression = createNode(SyntaxKind.TableExpression, tsOriginal, parent);
const expression = createNode(SyntaxKind.TableFieldExpression, tsOriginal, parent);
setParent(value, expression);

@@ -502,6 +502,7 @@ expression.value = value;

exports.isIdentifier = isIdentifier;
function createIdentifier(text, tsOriginal, symbolId, parent) {
function createIdentifier(text, tsOriginal, symbolId, originalName, parent) {
const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent);
expression.text = text;
expression.symbolId = symbolId;
expression.originalName = originalName;
return expression;

@@ -511,3 +512,3 @@ }

function cloneIdentifier(identifier, tsOriginal) {
return createIdentifier(identifier.text, tsOriginal, identifier.symbolId);
return createIdentifier(identifier.text, tsOriginal, identifier.symbolId, identifier.originalName);
}

@@ -514,0 +515,0 @@ exports.cloneIdentifier = cloneIdentifier;

@@ -0,1 +1,2 @@

import { EmitHost } from "./Transpile";
export declare enum LuaLibFeature {

@@ -58,3 +59,3 @@ ArrayConcat = "ArrayConcat",

export declare class LuaLib {
static loadFeatures(features: Iterable<LuaLibFeature>): string;
static loadFeatures(features: Iterable<LuaLibFeature>, emitHost: EmitHost): string;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");

@@ -76,3 +75,3 @@ var LuaLibFeature;

class LuaLib {
static loadFeatures(features) {
static loadFeatures(features, emitHost) {
let result = "";

@@ -88,3 +87,9 @@ const loadedFeatures = new Set();

const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`);
result += fs.readFileSync(featureFile).toString() + "\n";
const luaLibFeature = emitHost.readFile(featureFile);
if (luaLibFeature !== undefined) {
result += luaLibFeature.toString() + "\n";
}
else {
throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`);
}
}

@@ -91,0 +96,0 @@ }

import { SourceNode } from "source-map";
import { CompilerOptions } from "./CompilerOptions";
import * as tstl from "./LuaAST";
import { CompilerOptions } from "./CompilerOptions";
import { LuaLibFeature } from "./LuaLib";
import { EmitHost } from "./Transpile";
declare type SourceChunk = string | SourceNode;

@@ -9,5 +10,6 @@ export declare class LuaPrinter {

private options;
private emitHost;
private currentIndent;
private sourceFile;
constructor(options: CompilerOptions);
constructor(options: CompilerOptions, emitHost: EmitHost);
print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>, sourceFile?: string): [string, string];

@@ -20,3 +22,3 @@ private printInlineSourceMap;

protected indent(input?: SourceChunk): SourceChunk;
protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode;
protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[], name?: string): SourceNode;
protected concatNodes(...chunks: SourceChunk[]): SourceNode;

@@ -64,4 +66,5 @@ protected printBlock(block: tstl.Block): SourceNode;

protected joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[];
protected printExpressionList(expressions: tstl.Expression[]): SourceChunk[];
private buildSourceMap;
}
export {};

@@ -5,11 +5,12 @@ "use strict";

const source_map_1 = require("source-map");
const CompilerOptions_1 = require("./CompilerOptions");
const tstl = require("./LuaAST");
const CompilerOptions_1 = require("./CompilerOptions");
const LuaKeywords_1 = require("./LuaKeywords");
const LuaLib_1 = require("./LuaLib");
const TSHelper_1 = require("./TSHelper");
const LuaKeywords_1 = require("./LuaKeywords");
const tsHelper = require("./TSHelper");
class LuaPrinter {
constructor(options) {
constructor(options, emitHost) {
this.sourceFile = "";
this.options = options;
this.emitHost = emitHost;
this.currentIndent = "";

@@ -80,3 +81,3 @@ }

header += "-- Lua Library inline imports\n";
header += LuaLib_1.LuaLib.loadFeatures(luaLibFeatures);
header += LuaLib_1.LuaLib.loadFeatures(luaLibFeatures, this.emitHost);
}

@@ -100,7 +101,7 @@ }

}
createSourceNode(node, chunks) {
createSourceNode(node, chunks, name) {
const originalPos = tstl.getOriginalPos(node);
return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined
? new source_map_1.SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks)
: new source_map_1.SourceNode(null, null, this.sourceFile, chunks); // tslint:disable-line:no-null-keyword
? new source_map_1.SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks, name)
: new source_map_1.SourceNode(null, null, this.sourceFile, chunks, name); // tslint:disable-line:no-null-keyword
}

@@ -199,3 +200,3 @@ concatNodes(...chunks) {

}
return this.concatNodes(...chunks);
return this.createSourceNode(statement, chunks);
}

@@ -209,3 +210,3 @@ printVariableAssignmentStatement(statement) {

const name = this.printExpression(statement.left[0]);
if (TSHelper_1.TSHelper.isValidLuaFunctionDeclarationName(name.toString())) {
if (tsHelper.isValidLuaFunctionDeclarationName(name.toString())) {
chunks.push(this.printFunctionDefinition(statement));

@@ -390,3 +391,3 @@ return this.createSourceNode(statement, chunks);

chunks.push(this.createSourceNode(returnStatement, returnNode));
chunks.push(" end");
chunks.push(this.createSourceNode(expression, " end"));
}

@@ -398,3 +399,3 @@ else {

this.popIndent();
chunks.push(this.indent("end"));
chunks.push(this.indent(this.createSourceNode(expression, "end")));
}

@@ -414,3 +415,3 @@ return this.createSourceNode(expression, chunks);

this.popIndent();
chunks.push(this.indent("end"));
chunks.push(this.indent(this.createSourceNode(statement, "end")));
return this.createSourceNode(expression, chunks);

@@ -423,3 +424,3 @@ }

if (tstl.isStringLiteral(expression.key) &&
TSHelper_1.TSHelper.isValidLuaIdentifier(expression.key.value) &&
tsHelper.isValidLuaIdentifier(expression.key.value) &&
!LuaKeywords_1.luaKeywords.has(expression.key.value)) {

@@ -440,14 +441,4 @@ chunks.push(expression.key.value, " = ", value);

chunks.push("{");
if (expression.fields && expression.fields.length > 0) {
if (expression.fields.length === 1) {
// Inline tables with only one entry
chunks.push(this.printTableFieldExpression(expression.fields[0]));
}
else {
chunks.push("\n");
this.pushIndent();
expression.fields.forEach(f => chunks.push(this.indent(), this.printTableFieldExpression(f), ",\n"));
this.popIndent();
chunks.push(this.indent());
}
if (expression.fields) {
chunks.push(...this.printExpressionList(expression.fields));
}

@@ -489,21 +480,22 @@ chunks.push("}");

const chunks = [];
const parameterChunks = expression.params !== undefined ? expression.params.map(e => this.printExpression(e)) : [];
chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")");
chunks.push(this.printExpression(expression.expression), "(");
if (expression.params) {
chunks.push(...this.printExpressionList(expression.params));
}
chunks.push(")");
return this.createSourceNode(expression, chunks);
}
printMethodCallExpression(expression) {
const chunks = [];
const prefix = this.printExpression(expression.prefixExpression);
const parameterChunks = expression.params !== undefined ? expression.params.map(e => this.printExpression(e)) : [];
const name = this.printIdentifier(expression.name);
return this.createSourceNode(expression, [
prefix,
":",
name,
"(",
...this.joinChunks(", ", parameterChunks),
")",
]);
chunks.push(prefix, ":", name, "(");
if (expression.params) {
chunks.push(...this.printExpressionList(expression.params));
}
chunks.push(")");
return this.createSourceNode(expression, chunks);
}
printIdentifier(expression) {
return this.createSourceNode(expression, expression.text);
return this.createSourceNode(expression, expression.text, expression.originalName !== expression.text ? expression.originalName : undefined);
}

@@ -514,3 +506,3 @@ printTableIndexExpression(expression) {

if (tstl.isStringLiteral(expression.index) &&
TSHelper_1.TSHelper.isValidLuaIdentifier(expression.index.value) &&
tsHelper.isValidLuaIdentifier(expression.index.value) &&
!LuaKeywords_1.luaKeywords.has(expression.index.value)) {

@@ -553,2 +545,19 @@ chunks.push(".", this.createSourceNode(expression.index, expression.index.value));

}
printExpressionList(expressions) {
const chunks = [];
if (expressions.every(e => tsHelper.isSimpleExpression(e))) {
chunks.push(...this.joinChunks(", ", expressions.map(e => this.printExpression(e))));
}
else {
chunks.push("\n");
this.pushIndent();
expressions.forEach((p, i) => {
const tail = i < expressions.length - 1 ? ",\n" : "\n";
chunks.push(this.indent(), this.printExpression(p), tail);
});
this.popIndent();
chunks.push(this.indent());
}
return chunks;
}
// The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column

@@ -572,6 +581,9 @@ // will not generate 'empty' mappings in the source map that point to nothing in the original TS.

if (currentMapping.generated.line === generatedLine &&
currentMapping.generated.column === generatedColumn) {
currentMapping.generated.column === generatedColumn &&
currentMapping.name === sourceNode.name) {
return false;
}
return (currentMapping.original.line !== sourceNode.line || currentMapping.original.column !== sourceNode.column);
return (currentMapping.original.line !== sourceNode.line ||
currentMapping.original.column !== sourceNode.column ||
currentMapping.name !== sourceNode.name);
};

@@ -584,2 +596,3 @@ const build = (sourceNode) => {

generated: { line: generatedLine, column: generatedColumn },
name: sourceNode.name,
};

@@ -586,0 +599,0 @@ map.addMapping(currentMapping);

@@ -146,2 +146,3 @@ import * as ts from "typescript";

transformObjectLiteral(expression: ts.ObjectLiteralExpression): ExpressionVisitResult;
transformOmittedExpression(node: ts.OmittedExpression): ExpressionVisitResult;
transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult;

@@ -156,2 +157,3 @@ transformFunctionExpression(node: ts.FunctionLikeDeclaration): ExpressionVisitResult;

transformElementCall(node: ts.CallExpression): ExpressionVisitResult;
transformContextualCallExpression(node: ts.CallExpression | ts.TaggedTemplateExpression, transformedArguments: tstl.Expression[]): ExpressionVisitResult;
protected transformArguments<T extends ts.Expression>(params: ts.NodeArray<ts.Expression> | ts.Expression[], sig?: ts.Signature, context?: T): tstl.Expression[];

@@ -190,2 +192,3 @@ transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult;

transformArrayBindingElement(name: ts.ArrayBindingElement): ExpressionVisitResult;
transformArrayBindingExpression(name: ts.Expression): ExpressionVisitResult;
transformAssertionExpression(expression: ts.AssertionExpression): ExpressionVisitResult;

@@ -200,2 +203,3 @@ transformTypeOfExpression(expression: ts.TypeOfExpression): ExpressionVisitResult;

transformThisKeyword(thisKeyword: ts.ThisExpression): ExpressionVisitResult;
transformTaggedTemplateExpression(expression: ts.TaggedTemplateExpression): ExpressionVisitResult;
transformTemplateExpression(expression: ts.TemplateExpression): ExpressionVisitResult;

@@ -202,0 +206,0 @@ transformPropertyName(propertyName: ts.PropertyName): ExpressionVisitResult;

@@ -23,3 +23,7 @@ import * as ts from "typescript";

printer?: LuaPrinter;
emitHost?: EmitHost;
}
export declare function transpile({ program, sourceFiles: targetSourceFiles, customTransformers, transformer, printer, }: TranspileOptions): TranspileResult;
export interface EmitHost {
readFile(path: string): string | undefined;
}
export declare function transpile({ program, sourceFiles: targetSourceFiles, customTransformers, emitHost, transformer, printer, }: TranspileOptions): TranspileResult;

@@ -9,3 +9,3 @@ "use strict";

const TSTransformers_1 = require("./TSTransformers");
function transpile({ program, sourceFiles: targetSourceFiles, customTransformers = {}, transformer = new LuaTransformer_1.LuaTransformer(program), printer = new LuaPrinter_1.LuaPrinter(program.getCompilerOptions()), }) {
function transpile({ program, sourceFiles: targetSourceFiles, customTransformers = {}, emitHost = ts.sys, transformer = new LuaTransformer_1.LuaTransformer(program), printer = new LuaPrinter_1.LuaPrinter(program.getCompilerOptions(), emitHost), }) {
const options = program.getCompilerOptions();

@@ -12,0 +12,0 @@ const diagnostics = [];

import * as ts from "typescript";
import { Decorator, DecoratorKind } from "./Decorator";
import * as tstl from "./LuaAST";
export declare enum ContextType {

@@ -9,65 +10,66 @@ None = 0,

}
export declare class TSHelper {
static getExtendedTypeNode(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.ExpressionWithTypeArguments | undefined;
static getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined;
static isFileModule(sourceFile: ts.SourceFile): boolean;
static isStatementExported(statement: ts.Statement): boolean;
static getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined;
static isDeclaration(node: ts.Node): node is ts.Declaration;
static isInDestructingAssignment(node: ts.Node): boolean;
static forTypeOrAnySupertype(type: ts.Type, checker: ts.TypeChecker, predicate: (type: ts.Type) => boolean): boolean;
static isAmbient(node: ts.Declaration): boolean;
static isStatic(node: ts.Node): boolean;
static isStringType(type: ts.Type): boolean;
static isNumberType(type: ts.Type): boolean;
static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean;
static isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean;
static isFunctionTypeAtLocation(node: ts.Node, checker: ts.TypeChecker): boolean;
static isArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean;
static isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean;
static isRestParameter(node: ts.Node, checker: ts.TypeChecker): boolean;
static isVarArgType(node: ts.Node, checker: ts.TypeChecker): boolean;
static isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean;
static isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean;
static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean;
static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined;
static collectCustomDecorators(source: ts.Symbol | ts.Signature, checker: ts.TypeChecker, decMap: Map<DecoratorKind, Decorator>): void;
static getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map<DecoratorKind, Decorator>;
static getCustomFileDirectives(file: ts.SourceFile): Map<DecoratorKind, Decorator>;
static getCustomSignatureDirectives(signature: ts.Signature, checker: ts.TypeChecker): Map<DecoratorKind, Decorator>;
static findFirstNodeAbove<T extends ts.Node>(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined;
static isBinaryAssignmentToken(token: ts.SyntaxKind): [true, ts.BinaryOperator] | [false, undefined];
static isExpressionWithEvaluationEffect(node: ts.Expression): boolean;
static isAccessExpressionWithEvaluationEffects(node: ts.Expression, checker: ts.TypeChecker, program: ts.Program): [true, ts.Expression, ts.Expression] | [false, undefined, undefined];
static isDefaultArrayCallMethodName(methodName: string): boolean;
static getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration | undefined;
static findInClassOrAncestor(classDeclaration: ts.ClassLikeDeclarationBase, callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, checker: ts.TypeChecker): ts.ClassLikeDeclarationBase | undefined;
static hasSetAccessorInClassOrAncestor(classDeclaration: ts.ClassLikeDeclarationBase, isStatic: boolean, checker: ts.TypeChecker): boolean;
static hasGetAccessorInClassOrAncestor(classDeclaration: ts.ClassLikeDeclarationBase, isStatic: boolean, checker: ts.TypeChecker): boolean;
static getPropertyName(propertyName: ts.PropertyName): string | number | undefined;
static isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean;
static isGetAccessorOverride(element: ts.ClassElement, classDeclaration: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): element is ts.GetAccessorDeclaration;
static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type;
static getAllCallSignatures(type: ts.Type): ReadonlyArray<ts.Signature>;
static getSignatureDeclarations(signatures: readonly ts.Signature[], checker: ts.TypeChecker): ts.SignatureDeclaration[];
static hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeChecker): boolean;
static getDeclarationContextType(signatureDeclaration: ts.SignatureDeclaration, checker: ts.TypeChecker): ContextType;
static reduceContextTypes(contexts: ContextType[]): ContextType;
static getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType;
static escapeString(text: string): string;
static isValidLuaIdentifier(str: string): boolean;
static fixInvalidLuaIdentifier(name: string): string;
static isValidLuaFunctionDeclarationName(str: string): boolean;
static isFalsible(type: ts.Type, strictNullChecks: boolean): boolean;
static getFirstDeclaration(symbol: ts.Symbol, sourceFile?: ts.SourceFile): ts.Declaration | undefined;
static isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean;
static isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean;
static isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean;
static isEnumMember(enumDeclaration: ts.EnumDeclaration, value: ts.Expression): [true, ts.PropertyName] | [false, undefined];
static moduleHasEmittedBody(statement: ts.ModuleDeclaration): statement is ts.ModuleDeclaration & {
body: ts.ModuleBlock | ts.ModuleDeclaration;
};
static isArrayLengthAssignment(expression: ts.BinaryExpression, checker: ts.TypeChecker, program: ts.Program): expression is ts.BinaryExpression & {
left: ts.PropertyAccessExpression | ts.ElementAccessExpression;
};
}
export declare function getExtendedTypeNode(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.ExpressionWithTypeArguments | undefined;
export declare function getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined;
export declare function isFileModule(sourceFile: ts.SourceFile): boolean;
export declare function isStatementExported(statement: ts.Statement): boolean;
export declare function getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined;
export declare function isDeclaration(node: ts.Node): node is ts.Declaration;
export declare function isInDestructingAssignment(node: ts.Node): boolean;
export declare function forTypeOrAnySupertype(type: ts.Type, checker: ts.TypeChecker, predicate: (type: ts.Type) => boolean): boolean;
export declare function isAmbientNode(node: ts.Declaration): boolean;
export declare function isStaticNode(node: ts.Node): boolean;
export declare function isStringType(type: ts.Type): boolean;
export declare function isNumberType(type: ts.Type): boolean;
export declare function isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean;
export declare function isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean;
export declare function isFunctionTypeAtLocation(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function isArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean;
export declare function isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function isRestParameter(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function isVarArgType(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean;
export declare function getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined;
export declare function collectCustomDecorators(source: ts.Symbol | ts.Signature, checker: ts.TypeChecker, decMap: Map<DecoratorKind, Decorator>): void;
export declare function getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map<DecoratorKind, Decorator>;
export declare function getCustomFileDirectives(file: ts.SourceFile): Map<DecoratorKind, Decorator>;
export declare function getCustomSignatureDirectives(signature: ts.Signature, checker: ts.TypeChecker): Map<DecoratorKind, Decorator>;
export declare function findFirstNodeAbove<T extends ts.Node>(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined;
export declare function isBinaryAssignmentToken(token: ts.SyntaxKind): [true, ts.BinaryOperator] | [false, undefined];
export declare function isExpressionWithEvaluationEffect(node: ts.Expression): boolean;
export declare function isAccessExpressionWithEvaluationEffects(node: ts.Expression, checker: ts.TypeChecker, program: ts.Program): [true, ts.Expression, ts.Expression] | [false, undefined, undefined];
export declare function isDefaultArrayCallMethodName(methodName: string): boolean;
export declare function getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration | undefined;
export declare function findInClassOrAncestor(classDeclaration: ts.ClassLikeDeclarationBase, callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, checker: ts.TypeChecker): ts.ClassLikeDeclarationBase | undefined;
export declare function hasSetAccessorInClassOrAncestor(classDeclaration: ts.ClassLikeDeclarationBase, isStatic: boolean, checker: ts.TypeChecker): boolean;
export declare function hasGetAccessorInClassOrAncestor(classDeclaration: ts.ClassLikeDeclarationBase, isStatic: boolean, checker: ts.TypeChecker): boolean;
export declare function getPropertyName(propertyName: ts.PropertyName): string | number | undefined;
export declare function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean;
export declare function isGetAccessorOverride(element: ts.ClassElement, classDeclaration: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): element is ts.GetAccessorDeclaration;
export declare function inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type;
export declare function getAllCallSignatures(type: ts.Type): ReadonlyArray<ts.Signature>;
export declare function getSignatureDeclarations(signatures: readonly ts.Signature[], checker: ts.TypeChecker): ts.SignatureDeclaration[];
export declare function hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeChecker): boolean;
export declare function getDeclarationContextType(signatureDeclaration: ts.SignatureDeclaration, checker: ts.TypeChecker): ContextType;
export declare function reduceContextTypes(contexts: ContextType[]): ContextType;
export declare function getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType;
export declare function escapeString(text: string): string;
export declare function isValidLuaIdentifier(str: string): boolean;
export declare function fixInvalidLuaIdentifier(name: string): string;
export declare function isValidLuaFunctionDeclarationName(str: string): boolean;
export declare function isFalsible(type: ts.Type, strictNullChecks: boolean): boolean;
export declare function getFirstDeclaration(symbol: ts.Symbol, sourceFile?: ts.SourceFile): ts.Declaration | undefined;
export declare function getRawLiteral(node: ts.LiteralLikeNode): string;
export declare function isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean;
export declare function isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean;
export declare function isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean;
export declare function isEnumMember(enumDeclaration: ts.EnumDeclaration, value: ts.Expression): [true, ts.PropertyName] | [false, undefined];
export declare function isWithinLiteralAssignmentStatement(node: ts.Node): boolean;
export declare function moduleHasEmittedBody(statement: ts.ModuleDeclaration): statement is ts.ModuleDeclaration & {
body: ts.ModuleBlock | ts.ModuleDeclaration;
};
export declare function isArrayLengthAssignment(expression: ts.BinaryExpression, checker: ts.TypeChecker, program: ts.Program): expression is ts.BinaryExpression & {
left: ts.PropertyAccessExpression | ts.ElementAccessExpression;
};
export declare function isSimpleExpression(expression: tstl.Expression): boolean;

@@ -5,2 +5,3 @@ "use strict";

const Decorator_1 = require("./Decorator");
const tstl = require("./LuaAST");
var ContextType;

@@ -33,460 +34,491 @@ (function (ContextType) {

]);
class TSHelper {
static getExtendedTypeNode(node, checker) {
if (node && node.heritageClauses) {
for (const clause of node.heritageClauses) {
if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
const superType = checker.getTypeAtLocation(clause.types[0]);
const decorators = TSHelper.getCustomDecorators(superType, checker);
if (!decorators.has(Decorator_1.DecoratorKind.PureAbstract)) {
return clause.types[0];
}
function getExtendedTypeNode(node, checker) {
if (node && node.heritageClauses) {
for (const clause of node.heritageClauses) {
if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
const superType = checker.getTypeAtLocation(clause.types[0]);
const decorators = getCustomDecorators(superType, checker);
if (!decorators.has(Decorator_1.DecoratorKind.PureAbstract)) {
return clause.types[0];
}
}
}
return undefined;
}
static getExtendedType(node, checker) {
const extendedTypeNode = TSHelper.getExtendedTypeNode(node, checker);
return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode);
return undefined;
}
exports.getExtendedTypeNode = getExtendedTypeNode;
function getExtendedType(node, checker) {
const extendedTypeNode = getExtendedTypeNode(node, checker);
return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode);
}
exports.getExtendedType = getExtendedType;
function isFileModule(sourceFile) {
return sourceFile.statements.some(isStatementExported);
}
exports.isFileModule = isFileModule;
function isStatementExported(statement) {
if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) {
return true;
}
static isFileModule(sourceFile) {
return sourceFile.statements.some(TSHelper.isStatementExported);
if (ts.isVariableStatement(statement)) {
return statement.declarationList.declarations.some(declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0);
}
static isStatementExported(statement) {
if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) {
return true;
}
if (ts.isVariableStatement(statement)) {
return statement.declarationList.declarations.some(declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0);
}
return (TSHelper.isDeclaration(statement) &&
(ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0);
return isDeclaration(statement) && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0;
}
exports.isStatementExported = isStatementExported;
function getExportedSymbolDeclaration(symbol) {
const declarations = symbol.getDeclarations();
if (declarations) {
return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0);
}
static getExportedSymbolDeclaration(symbol) {
const declarations = symbol.getDeclarations();
if (declarations) {
return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0);
}
return undefined;
return undefined;
}
exports.getExportedSymbolDeclaration = getExportedSymbolDeclaration;
function isDeclaration(node) {
return (ts.isEnumDeclaration(node) ||
ts.isClassDeclaration(node) ||
ts.isExportDeclaration(node) ||
ts.isImportDeclaration(node) ||
ts.isMethodDeclaration(node) ||
ts.isModuleDeclaration(node) ||
ts.isFunctionDeclaration(node) ||
ts.isVariableDeclaration(node) ||
ts.isInterfaceDeclaration(node) ||
ts.isTypeAliasDeclaration(node) ||
ts.isNamespaceExportDeclaration(node));
}
exports.isDeclaration = isDeclaration;
function isInDestructingAssignment(node) {
return (node.parent &&
((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) ||
(ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))));
}
exports.isInDestructingAssignment = isInDestructingAssignment;
// iterate over a type and its bases until the callback returns true.
function forTypeOrAnySupertype(type, checker, predicate) {
if (predicate(type)) {
return true;
}
static isDeclaration(node) {
return (ts.isEnumDeclaration(node) ||
ts.isClassDeclaration(node) ||
ts.isExportDeclaration(node) ||
ts.isImportDeclaration(node) ||
ts.isMethodDeclaration(node) ||
ts.isModuleDeclaration(node) ||
ts.isFunctionDeclaration(node) ||
ts.isVariableDeclaration(node) ||
ts.isInterfaceDeclaration(node) ||
ts.isTypeAliasDeclaration(node) ||
ts.isNamespaceExportDeclaration(node));
if (!type.isClassOrInterface() && type.symbol) {
type = checker.getDeclaredTypeOfSymbol(type.symbol);
}
static isInDestructingAssignment(node) {
return (node.parent &&
((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) ||
(ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))));
}
// iterate over a type and its bases until the callback returns true.
static forTypeOrAnySupertype(type, checker, predicate) {
if (predicate(type)) {
return true;
}
if (!type.isClassOrInterface() && type.symbol) {
type = checker.getDeclaredTypeOfSymbol(type.symbol);
}
const superTypes = type.getBaseTypes();
if (superTypes) {
for (const superType of superTypes) {
if (TSHelper.forTypeOrAnySupertype(superType, checker, predicate)) {
return true;
}
const superTypes = type.getBaseTypes();
if (superTypes) {
for (const superType of superTypes) {
if (forTypeOrAnySupertype(superType, checker, predicate)) {
return true;
}
}
return false;
}
static isAmbient(node) {
return !((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) === 0);
return false;
}
exports.forTypeOrAnySupertype = forTypeOrAnySupertype;
function isAmbientNode(node) {
return !((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) === 0);
}
exports.isAmbientNode = isAmbientNode;
function isStaticNode(node) {
return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword);
}
exports.isStaticNode = isStaticNode;
function isStringType(type) {
return ((type.flags & ts.TypeFlags.String) !== 0 ||
(type.flags & ts.TypeFlags.StringLike) !== 0 ||
(type.flags & ts.TypeFlags.StringLiteral) !== 0);
}
exports.isStringType = isStringType;
function isNumberType(type) {
return ((type.flags & ts.TypeFlags.Number) !== 0 ||
(type.flags & ts.TypeFlags.NumberLike) !== 0 ||
(type.flags & ts.TypeFlags.NumberLiteral) !== 0);
}
exports.isNumberType = isNumberType;
function isExplicitArrayType(type, checker, program) {
if (type.isUnionOrIntersection()) {
return type.types.some(t => isExplicitArrayType(t, checker, program));
}
static isStatic(node) {
return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword);
if (isStandardLibraryType(type, "ReadonlyArray", program)) {
return true;
}
static isStringType(type) {
return ((type.flags & ts.TypeFlags.String) !== 0 ||
(type.flags & ts.TypeFlags.StringLike) !== 0 ||
(type.flags & ts.TypeFlags.StringLiteral) !== 0);
const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple;
const typeNode = checker.typeToTypeNode(type, undefined, flags);
return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode));
}
exports.isExplicitArrayType = isExplicitArrayType;
function isFunctionType(type, checker) {
const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias);
return typeNode !== undefined && ts.isFunctionTypeNode(typeNode);
}
exports.isFunctionType = isFunctionType;
function isFunctionTypeAtLocation(node, checker) {
const type = checker.getTypeAtLocation(node);
return isFunctionType(type, checker);
}
exports.isFunctionTypeAtLocation = isFunctionTypeAtLocation;
function isArrayType(type, checker, program) {
return forTypeOrAnySupertype(type, checker, t => isExplicitArrayType(t, checker, program));
}
exports.isArrayType = isArrayType;
function isLuaIteratorType(node, checker) {
const type = checker.getTypeAtLocation(node);
return getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.LuaIterator);
}
exports.isLuaIteratorType = isLuaIteratorType;
function isRestParameter(node, checker) {
const symbol = checker.getSymbolAtLocation(node);
if (!symbol) {
return false;
}
static isNumberType(type) {
return ((type.flags & ts.TypeFlags.Number) !== 0 ||
(type.flags & ts.TypeFlags.NumberLike) !== 0 ||
(type.flags & ts.TypeFlags.NumberLiteral) !== 0);
const declarations = symbol.getDeclarations();
if (!declarations) {
return false;
}
static isExplicitArrayType(type, checker, program) {
if (type.isUnionOrIntersection()) {
return type.types.some(t => TSHelper.isExplicitArrayType(t, checker, program));
return declarations.some(d => ts.isParameter(d) && d.dotDotDotToken !== undefined);
}
exports.isRestParameter = isRestParameter;
function isVarArgType(node, checker) {
const type = checker.getTypeAtLocation(node);
return type !== undefined && getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.Vararg);
}
exports.isVarArgType = isVarArgType;
function isForRangeType(node, checker) {
const type = checker.getTypeAtLocation(node);
return getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.ForRange);
}
exports.isForRangeType = isForRangeType;
function isTupleReturnCall(node, checker) {
if (ts.isCallExpression(node)) {
const signature = checker.getResolvedSignature(node);
if (signature) {
if (getCustomSignatureDirectives(signature, checker).has(Decorator_1.DecoratorKind.TupleReturn)) {
return true;
}
// Only check function type for directive if it is declared as an interface or type alias
const declaration = signature.getDeclaration();
const isInterfaceOrAlias = declaration &&
declaration.parent &&
((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) ||
ts.isTypeAliasDeclaration(declaration.parent));
if (!isInterfaceOrAlias) {
return false;
}
}
if (TSHelper.isStandardLibraryType(type, "ReadonlyArray", program)) {
return true;
}
const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple;
const typeNode = checker.typeToTypeNode(type, undefined, flags);
return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode));
const type = checker.getTypeAtLocation(node.expression);
return getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.TupleReturn);
}
static isFunctionType(type, checker) {
const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias);
return typeNode !== undefined && ts.isFunctionTypeNode(typeNode);
else {
return false;
}
static isFunctionTypeAtLocation(node, checker) {
const type = checker.getTypeAtLocation(node);
return TSHelper.isFunctionType(type, checker);
}
static isArrayType(type, checker, program) {
return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.isExplicitArrayType(t, checker, program));
}
static isLuaIteratorType(node, checker) {
const type = checker.getTypeAtLocation(node);
return TSHelper.getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.LuaIterator);
}
static isRestParameter(node, checker) {
const symbol = checker.getSymbolAtLocation(node);
if (!symbol) {
return false;
}
exports.isTupleReturnCall = isTupleReturnCall;
function isInTupleReturnFunction(node, checker) {
const declaration = findFirstNodeAbove(node, ts.isFunctionLike);
if (declaration) {
let functionType;
if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) {
functionType = inferAssignedType(declaration, checker);
}
const declarations = symbol.getDeclarations();
if (!declarations) {
return false;
else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) {
// Manually lookup type for object literal properties declared with method syntax
const interfaceType = inferAssignedType(declaration.parent, checker);
const propertySymbol = interfaceType.getProperty(declaration.name.getText());
if (propertySymbol) {
functionType = checker.getTypeOfSymbolAtLocation(propertySymbol, declaration);
}
}
return declarations.some(d => ts.isParameter(d) && d.dotDotDotToken !== undefined);
if (functionType === undefined) {
functionType = checker.getTypeAtLocation(declaration);
}
// Check all overloads for directive
const signatures = functionType.getCallSignatures();
if (signatures &&
signatures.some(s => getCustomSignatureDirectives(s, checker).has(Decorator_1.DecoratorKind.TupleReturn))) {
return true;
}
const decorators = getCustomDecorators(functionType, checker);
return decorators.has(Decorator_1.DecoratorKind.TupleReturn);
}
static isVarArgType(node, checker) {
const type = checker.getTypeAtLocation(node);
return type !== undefined && TSHelper.getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.Vararg);
else {
return false;
}
static isForRangeType(node, checker) {
const type = checker.getTypeAtLocation(node);
return TSHelper.getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.ForRange);
}
exports.isInTupleReturnFunction = isInTupleReturnFunction;
function getContainingFunctionReturnType(node, checker) {
const declaration = findFirstNodeAbove(node, ts.isFunctionLike);
if (declaration) {
const signature = checker.getSignatureFromDeclaration(declaration);
return signature === undefined ? undefined : checker.getReturnTypeOfSignature(signature);
}
static isTupleReturnCall(node, checker) {
if (ts.isCallExpression(node)) {
const signature = checker.getResolvedSignature(node);
if (signature) {
if (TSHelper.getCustomSignatureDirectives(signature, checker).has(Decorator_1.DecoratorKind.TupleReturn)) {
return true;
}
// Only check function type for directive if it is declared as an interface or type alias
const declaration = signature.getDeclaration();
const isInterfaceOrAlias = declaration &&
declaration.parent &&
((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) ||
ts.isTypeAliasDeclaration(declaration.parent));
if (!isInterfaceOrAlias) {
return false;
}
}
const type = checker.getTypeAtLocation(node.expression);
return TSHelper.getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.TupleReturn);
return undefined;
}
exports.getContainingFunctionReturnType = getContainingFunctionReturnType;
function collectCustomDecorators(source, checker, decMap) {
const comments = source.getDocumentationComment(checker);
const decorators = comments
.filter(comment => comment.kind === "text")
.map(comment => comment.text.split("\n"))
.reduce((a, b) => a.concat(b), [])
.map(line => line.trim())
.filter(comment => comment[0] === "!");
decorators.forEach(decStr => {
const [decoratorName, ...decoratorArguments] = decStr.split(" ");
if (Decorator_1.Decorator.isValid(decoratorName.substr(1))) {
const dec = new Decorator_1.Decorator(decoratorName.substr(1), decoratorArguments);
decMap.set(dec.kind, dec);
console.warn(`[Deprecated] Decorators with ! are being deprecated, ` + `use @${decStr.substr(1)} instead`);
}
else {
return false;
console.warn(`Encountered unknown decorator ${decStr}.`);
}
}
static isInTupleReturnFunction(node, checker) {
const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike);
if (declaration) {
let functionType;
if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) {
functionType = TSHelper.inferAssignedType(declaration, checker);
}
else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) {
// Manually lookup type for object literal properties declared with method syntax
const interfaceType = TSHelper.inferAssignedType(declaration.parent, checker);
const propertySymbol = interfaceType.getProperty(declaration.name.getText());
if (propertySymbol) {
functionType = checker.getTypeOfSymbolAtLocation(propertySymbol, declaration);
}
}
if (functionType === undefined) {
functionType = checker.getTypeAtLocation(declaration);
}
// Check all overloads for directive
const signatures = functionType.getCallSignatures();
if (signatures &&
signatures.some(s => TSHelper.getCustomSignatureDirectives(s, checker).has(Decorator_1.DecoratorKind.TupleReturn))) {
return true;
}
const decorators = TSHelper.getCustomDecorators(functionType, checker);
return decorators.has(Decorator_1.DecoratorKind.TupleReturn);
});
source.getJsDocTags().forEach(tag => {
if (Decorator_1.Decorator.isValid(tag.name)) {
const dec = new Decorator_1.Decorator(tag.name, tag.text ? tag.text.split(" ") : []);
decMap.set(dec.kind, dec);
}
else {
return false;
}
});
}
exports.collectCustomDecorators = collectCustomDecorators;
function getCustomDecorators(type, checker) {
const decMap = new Map();
if (type.symbol) {
collectCustomDecorators(type.symbol, checker, decMap);
}
static getContainingFunctionReturnType(node, checker) {
const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike);
if (declaration) {
const signature = checker.getSignatureFromDeclaration(declaration);
return signature === undefined ? undefined : checker.getReturnTypeOfSignature(signature);
}
return undefined;
if (type.aliasSymbol) {
collectCustomDecorators(type.aliasSymbol, checker, decMap);
}
static collectCustomDecorators(source, checker, decMap) {
const comments = source.getDocumentationComment(checker);
const decorators = comments
.filter(comment => comment.kind === "text")
.map(comment => comment.text.split("\n"))
.reduce((a, b) => a.concat(b), [])
.map(line => line.trim())
.filter(comment => comment[0] === "!");
decorators.forEach(decStr => {
const [decoratorName, ...decoratorArguments] = decStr.split(" ");
if (Decorator_1.Decorator.isValid(decoratorName.substr(1))) {
const dec = new Decorator_1.Decorator(decoratorName.substr(1), decoratorArguments);
return decMap;
}
exports.getCustomDecorators = getCustomDecorators;
function getCustomFileDirectives(file) {
const decMap = new Map();
if (file.statements.length > 0) {
const tags = ts.getJSDocTags(file.statements[0]);
for (const tag of tags) {
const tagName = tag.tagName.escapedText;
if (Decorator_1.Decorator.isValid(tagName)) {
const dec = new Decorator_1.Decorator(tagName, tag.comment ? tag.comment.split(" ") : []);
decMap.set(dec.kind, dec);
console.warn(`[Deprecated] Decorators with ! are being deprecated, ` + `use @${decStr.substr(1)} instead`);
}
else {
console.warn(`Encountered unknown decorator ${decStr}.`);
}
});
source.getJsDocTags().forEach(tag => {
if (Decorator_1.Decorator.isValid(tag.name)) {
const dec = new Decorator_1.Decorator(tag.name, tag.text ? tag.text.split(" ") : []);
decMap.set(dec.kind, dec);
}
});
}
static getCustomDecorators(type, checker) {
const decMap = new Map();
if (type.symbol) {
TSHelper.collectCustomDecorators(type.symbol, checker, decMap);
}
if (type.aliasSymbol) {
TSHelper.collectCustomDecorators(type.aliasSymbol, checker, decMap);
}
return decMap;
}
static getCustomFileDirectives(file) {
const decMap = new Map();
if (file.statements.length > 0) {
const tags = ts.getJSDocTags(file.statements[0]);
for (const tag of tags) {
const tagName = tag.tagName.escapedText;
if (Decorator_1.Decorator.isValid(tagName)) {
const dec = new Decorator_1.Decorator(tagName, tag.comment ? tag.comment.split(" ") : []);
decMap.set(dec.kind, dec);
}
}
return decMap;
}
exports.getCustomFileDirectives = getCustomFileDirectives;
function getCustomSignatureDirectives(signature, checker) {
const directivesMap = new Map();
collectCustomDecorators(signature, checker, directivesMap);
// Function properties on interfaces have the JSDoc tags on the parent PropertySignature
const declaration = signature.getDeclaration();
if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) {
const symbol = checker.getSymbolAtLocation(declaration.parent.name);
if (symbol) {
collectCustomDecorators(symbol, checker, directivesMap);
}
return decMap;
}
static getCustomSignatureDirectives(signature, checker) {
const directivesMap = new Map();
TSHelper.collectCustomDecorators(signature, checker, directivesMap);
// Function properties on interfaces have the JSDoc tags on the parent PropertySignature
const declaration = signature.getDeclaration();
if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) {
const symbol = checker.getSymbolAtLocation(declaration.parent.name);
if (symbol) {
TSHelper.collectCustomDecorators(symbol, checker, directivesMap);
}
return directivesMap;
}
exports.getCustomSignatureDirectives = getCustomSignatureDirectives;
// Search up until finding a node satisfying the callback
function findFirstNodeAbove(node, callback) {
let current = node;
while (current.parent) {
if (callback(current.parent)) {
return current.parent;
}
return directivesMap;
}
// Search up until finding a node satisfying the callback
static findFirstNodeAbove(node, callback) {
let current = node;
while (current.parent) {
if (callback(current.parent)) {
return current.parent;
}
else {
current = current.parent;
}
else {
current = current.parent;
}
return undefined;
}
static isBinaryAssignmentToken(token) {
switch (token) {
case ts.SyntaxKind.BarEqualsToken:
return [true, ts.SyntaxKind.BarToken];
case ts.SyntaxKind.PlusEqualsToken:
return [true, ts.SyntaxKind.PlusToken];
case ts.SyntaxKind.CaretEqualsToken:
return [true, ts.SyntaxKind.CaretToken];
case ts.SyntaxKind.MinusEqualsToken:
return [true, ts.SyntaxKind.MinusToken];
case ts.SyntaxKind.SlashEqualsToken:
return [true, ts.SyntaxKind.SlashToken];
case ts.SyntaxKind.PercentEqualsToken:
return [true, ts.SyntaxKind.PercentToken];
case ts.SyntaxKind.AsteriskEqualsToken:
return [true, ts.SyntaxKind.AsteriskToken];
case ts.SyntaxKind.AmpersandEqualsToken:
return [true, ts.SyntaxKind.AmpersandToken];
case ts.SyntaxKind.AsteriskAsteriskEqualsToken:
return [true, ts.SyntaxKind.AsteriskAsteriskToken];
case ts.SyntaxKind.LessThanLessThanEqualsToken:
return [true, ts.SyntaxKind.LessThanLessThanToken];
case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:
return [true, ts.SyntaxKind.GreaterThanGreaterThanToken];
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
return [true, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken];
}
return [false, undefined];
return undefined;
}
exports.findFirstNodeAbove = findFirstNodeAbove;
function isBinaryAssignmentToken(token) {
switch (token) {
case ts.SyntaxKind.BarEqualsToken:
return [true, ts.SyntaxKind.BarToken];
case ts.SyntaxKind.PlusEqualsToken:
return [true, ts.SyntaxKind.PlusToken];
case ts.SyntaxKind.CaretEqualsToken:
return [true, ts.SyntaxKind.CaretToken];
case ts.SyntaxKind.MinusEqualsToken:
return [true, ts.SyntaxKind.MinusToken];
case ts.SyntaxKind.SlashEqualsToken:
return [true, ts.SyntaxKind.SlashToken];
case ts.SyntaxKind.PercentEqualsToken:
return [true, ts.SyntaxKind.PercentToken];
case ts.SyntaxKind.AsteriskEqualsToken:
return [true, ts.SyntaxKind.AsteriskToken];
case ts.SyntaxKind.AmpersandEqualsToken:
return [true, ts.SyntaxKind.AmpersandToken];
case ts.SyntaxKind.AsteriskAsteriskEqualsToken:
return [true, ts.SyntaxKind.AsteriskAsteriskToken];
case ts.SyntaxKind.LessThanLessThanEqualsToken:
return [true, ts.SyntaxKind.LessThanLessThanToken];
case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:
return [true, ts.SyntaxKind.GreaterThanGreaterThanToken];
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
return [true, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken];
}
// Returns true for expressions that may have effects when evaluated
static isExpressionWithEvaluationEffect(node) {
return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword);
}
// If expression is property/element access with possible effects from being evaluated, returns true along with the
// separated object and index expressions.
static isAccessExpressionWithEvaluationEffects(node, checker, program) {
if (ts.isElementAccessExpression(node) &&
(TSHelper.isExpressionWithEvaluationEffect(node.expression) ||
TSHelper.isExpressionWithEvaluationEffect(node.argumentExpression))) {
const type = checker.getTypeAtLocation(node.expression);
if (TSHelper.isArrayType(type, checker, program)) {
// Offset arrays by one
const oneLit = ts.createNumericLiteral("1");
const exp = ts.createParen(node.argumentExpression);
const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit);
return [true, node.expression, addExp];
}
else {
return [true, node.expression, node.argumentExpression];
}
return [false, undefined];
}
exports.isBinaryAssignmentToken = isBinaryAssignmentToken;
// Returns true for expressions that may have effects when evaluated
function isExpressionWithEvaluationEffect(node) {
return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword);
}
exports.isExpressionWithEvaluationEffect = isExpressionWithEvaluationEffect;
// If expression is property/element access with possible effects from being evaluated, returns true along with the
// separated object and index expressions.
function isAccessExpressionWithEvaluationEffects(node, checker, program) {
if (ts.isElementAccessExpression(node) &&
(isExpressionWithEvaluationEffect(node.expression) || isExpressionWithEvaluationEffect(node.argumentExpression))) {
const type = checker.getTypeAtLocation(node.expression);
if (isArrayType(type, checker, program)) {
// Offset arrays by one
const oneLit = ts.createNumericLiteral("1");
const exp = ts.createParen(node.argumentExpression);
const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit);
return [true, node.expression, addExp];
}
else if (ts.isPropertyAccessExpression(node) && TSHelper.isExpressionWithEvaluationEffect(node.expression)) {
return [true, node.expression, ts.createStringLiteral(node.name.text)];
else {
return [true, node.expression, node.argumentExpression];
}
return [false, undefined, undefined];
}
static isDefaultArrayCallMethodName(methodName) {
return defaultArrayCallMethodNames.has(methodName);
else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) {
return [true, node.expression, ts.createStringLiteral(node.name.text)];
}
static getExplicitThisParameter(signatureDeclaration) {
return signatureDeclaration.parameters.find(param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword);
return [false, undefined, undefined];
}
exports.isAccessExpressionWithEvaluationEffects = isAccessExpressionWithEvaluationEffects;
function isDefaultArrayCallMethodName(methodName) {
return defaultArrayCallMethodNames.has(methodName);
}
exports.isDefaultArrayCallMethodName = isDefaultArrayCallMethodName;
function getExplicitThisParameter(signatureDeclaration) {
return signatureDeclaration.parameters.find(param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword);
}
exports.getExplicitThisParameter = getExplicitThisParameter;
function findInClassOrAncestor(classDeclaration, callback, checker) {
if (callback(classDeclaration)) {
return classDeclaration;
}
static findInClassOrAncestor(classDeclaration, callback, checker) {
if (callback(classDeclaration)) {
return classDeclaration;
}
const extendsType = TSHelper.getExtendedType(classDeclaration, checker);
if (!extendsType) {
return undefined;
}
const symbol = extendsType.getSymbol();
if (symbol === undefined) {
return undefined;
}
const symbolDeclarations = symbol.getDeclarations();
if (symbolDeclarations === undefined) {
return undefined;
}
const declaration = symbolDeclarations.find(ts.isClassLike);
if (!declaration) {
return undefined;
}
return TSHelper.findInClassOrAncestor(declaration, callback, checker);
const extendsType = getExtendedType(classDeclaration, checker);
if (!extendsType) {
return undefined;
}
static hasSetAccessorInClassOrAncestor(classDeclaration, isStatic, checker) {
return (TSHelper.findInClassOrAncestor(classDeclaration, c => c.members.some(m => ts.isSetAccessor(m) && TSHelper.isStatic(m) === isStatic), checker) !== undefined);
const symbol = extendsType.getSymbol();
if (symbol === undefined) {
return undefined;
}
static hasGetAccessorInClassOrAncestor(classDeclaration, isStatic, checker) {
return (TSHelper.findInClassOrAncestor(classDeclaration, c => c.members.some(m => ts.isGetAccessor(m) && TSHelper.isStatic(m) === isStatic), checker) !== undefined);
const symbolDeclarations = symbol.getDeclarations();
if (symbolDeclarations === undefined) {
return undefined;
}
static getPropertyName(propertyName) {
if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) {
return propertyName.text;
}
else {
return undefined; // TODO: how to handle computed property names?
}
const declaration = symbolDeclarations.find(ts.isClassLike);
if (!declaration) {
return undefined;
}
static isSamePropertyName(a, b) {
const aName = TSHelper.getPropertyName(a);
const bName = TSHelper.getPropertyName(b);
return aName !== undefined && aName === bName;
return findInClassOrAncestor(declaration, callback, checker);
}
exports.findInClassOrAncestor = findInClassOrAncestor;
function hasSetAccessorInClassOrAncestor(classDeclaration, isStatic, checker) {
return (findInClassOrAncestor(classDeclaration, c => c.members.some(m => ts.isSetAccessor(m) && isStaticNode(m) === isStatic), checker) !== undefined);
}
exports.hasSetAccessorInClassOrAncestor = hasSetAccessorInClassOrAncestor;
function hasGetAccessorInClassOrAncestor(classDeclaration, isStatic, checker) {
return (findInClassOrAncestor(classDeclaration, c => c.members.some(m => ts.isGetAccessor(m) && isStaticNode(m) === isStatic), checker) !== undefined);
}
exports.hasGetAccessorInClassOrAncestor = hasGetAccessorInClassOrAncestor;
function getPropertyName(propertyName) {
if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) {
return propertyName.text;
}
static isGetAccessorOverride(element, classDeclaration, checker) {
if (!ts.isGetAccessor(element) || TSHelper.isStatic(element)) {
return false;
}
const hasInitializedField = (e) => ts.isPropertyDeclaration(e) &&
e.initializer !== undefined &&
TSHelper.isSamePropertyName(e.name, element.name);
return (TSHelper.findInClassOrAncestor(classDeclaration, c => c.members.some(hasInitializedField), checker) !==
undefined);
else {
return undefined; // TODO: how to handle computed property names?
}
static inferAssignedType(expression, checker) {
return checker.getContextualType(expression) || checker.getTypeAtLocation(expression);
}
exports.getPropertyName = getPropertyName;
function isSamePropertyName(a, b) {
const aName = getPropertyName(a);
const bName = getPropertyName(b);
return aName !== undefined && aName === bName;
}
exports.isSamePropertyName = isSamePropertyName;
function isGetAccessorOverride(element, classDeclaration, checker) {
if (!ts.isGetAccessor(element) || isStaticNode(element)) {
return false;
}
static getAllCallSignatures(type) {
if (type.isUnion()) {
return type.types.map(t => TSHelper.getAllCallSignatures(t)).reduce((a, b) => a.concat(b));
}
return type.getCallSignatures();
const hasInitializedField = (e) => ts.isPropertyDeclaration(e) && e.initializer !== undefined && isSamePropertyName(e.name, element.name);
return findInClassOrAncestor(classDeclaration, c => c.members.some(hasInitializedField), checker) !== undefined;
}
exports.isGetAccessorOverride = isGetAccessorOverride;
function inferAssignedType(expression, checker) {
return checker.getContextualType(expression) || checker.getTypeAtLocation(expression);
}
exports.inferAssignedType = inferAssignedType;
function getAllCallSignatures(type) {
if (type.isUnion()) {
return type.types.map(t => getAllCallSignatures(t)).reduce((a, b) => a.concat(b));
}
static getSignatureDeclarations(signatures, checker) {
const signatureDeclarations = [];
for (const signature of signatures) {
const signatureDeclaration = signature.getDeclaration();
if ((ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) &&
!TSHelper.getExplicitThisParameter(signatureDeclaration)) {
// Infer type of function expressions/arrow functions
const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker);
if (inferredType) {
const inferredSignatures = TSHelper.getAllCallSignatures(inferredType);
if (inferredSignatures.length > 0) {
signatureDeclarations.push(...inferredSignatures.map(s => s.getDeclaration()));
continue;
}
return type.getCallSignatures();
}
exports.getAllCallSignatures = getAllCallSignatures;
function getSignatureDeclarations(signatures, checker) {
const signatureDeclarations = [];
for (const signature of signatures) {
const signatureDeclaration = signature.getDeclaration();
if ((ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) &&
!getExplicitThisParameter(signatureDeclaration)) {
// Infer type of function expressions/arrow functions
const inferredType = inferAssignedType(signatureDeclaration, checker);
if (inferredType) {
const inferredSignatures = getAllCallSignatures(inferredType);
if (inferredSignatures.length > 0) {
signatureDeclarations.push(...inferredSignatures.map(s => s.getDeclaration()));
continue;
}
}
signatureDeclarations.push(signatureDeclaration);
}
return signatureDeclarations;
signatureDeclarations.push(signatureDeclaration);
}
static hasNoSelfAncestor(declaration, checker) {
const scopeDeclaration = TSHelper.findFirstNodeAbove(declaration, (n) => ts.isSourceFile(n) || ts.isModuleDeclaration(n));
if (!scopeDeclaration) {
return false;
}
if (ts.isSourceFile(scopeDeclaration)) {
return TSHelper.getCustomFileDirectives(scopeDeclaration).has(Decorator_1.DecoratorKind.NoSelfInFile);
}
const scopeType = checker.getTypeAtLocation(scopeDeclaration);
if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(Decorator_1.DecoratorKind.NoSelf)) {
return true;
}
return TSHelper.hasNoSelfAncestor(scopeDeclaration, checker);
return signatureDeclarations;
}
exports.getSignatureDeclarations = getSignatureDeclarations;
function hasNoSelfAncestor(declaration, checker) {
const scopeDeclaration = findFirstNodeAbove(declaration, (n) => ts.isSourceFile(n) || ts.isModuleDeclaration(n));
if (!scopeDeclaration) {
return false;
}
static getDeclarationContextType(signatureDeclaration, checker) {
const thisParameter = TSHelper.getExplicitThisParameter(signatureDeclaration);
if (thisParameter) {
// Explicit 'this'
return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword
? ContextType.Void
: ContextType.NonVoid;
}
if (ts.isMethodSignature(signatureDeclaration) ||
ts.isMethodDeclaration(signatureDeclaration) ||
ts.isConstructSignatureDeclaration(signatureDeclaration) ||
ts.isConstructorDeclaration(signatureDeclaration) ||
(signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) ||
(signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent))) {
// Class/interface methods only respect @noSelf on their parent
const scopeDeclaration = TSHelper.findFirstNodeAbove(signatureDeclaration, (n) => ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n));
if (scopeDeclaration === undefined) {
return ContextType.NonVoid;
}
const scopeType = checker.getTypeAtLocation(scopeDeclaration);
if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(Decorator_1.DecoratorKind.NoSelf)) {
return ContextType.Void;
}
if (ts.isSourceFile(scopeDeclaration)) {
return getCustomFileDirectives(scopeDeclaration).has(Decorator_1.DecoratorKind.NoSelfInFile);
}
const scopeType = checker.getTypeAtLocation(scopeDeclaration);
if (scopeType && getCustomDecorators(scopeType, checker).has(Decorator_1.DecoratorKind.NoSelf)) {
return true;
}
return hasNoSelfAncestor(scopeDeclaration, checker);
}
exports.hasNoSelfAncestor = hasNoSelfAncestor;
function getDeclarationContextType(signatureDeclaration, checker) {
const thisParameter = getExplicitThisParameter(signatureDeclaration);
if (thisParameter) {
// Explicit 'this'
return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword
? ContextType.Void
: ContextType.NonVoid;
}
if (ts.isMethodSignature(signatureDeclaration) ||
ts.isMethodDeclaration(signatureDeclaration) ||
ts.isConstructSignatureDeclaration(signatureDeclaration) ||
ts.isConstructorDeclaration(signatureDeclaration) ||
(signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) ||
(signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent))) {
// Class/interface methods only respect @noSelf on their parent
const scopeDeclaration = findFirstNodeAbove(signatureDeclaration, (n) => ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n));
if (scopeDeclaration === undefined) {
return ContextType.NonVoid;
}
// Walk up to find @noSelf or @noSelfOnFile
if (TSHelper.hasNoSelfAncestor(signatureDeclaration, checker)) {
const scopeType = checker.getTypeAtLocation(scopeDeclaration);
if (scopeType && getCustomDecorators(scopeType, checker).has(Decorator_1.DecoratorKind.NoSelf)) {
return ContextType.Void;

@@ -496,143 +528,166 @@ }

}
static reduceContextTypes(contexts) {
const reducer = (a, b) => {
if (a === ContextType.None) {
return b;
}
else if (b === ContextType.None) {
return a;
}
else if (a !== b) {
return ContextType.Mixed;
}
else {
return a;
}
};
return contexts.reduce(reducer, ContextType.None);
// Walk up to find @noSelf or @noSelfOnFile
if (hasNoSelfAncestor(signatureDeclaration, checker)) {
return ContextType.Void;
}
static getFunctionContextType(type, checker) {
if (type.isTypeParameter()) {
type = type.getConstraint() || type;
return ContextType.NonVoid;
}
exports.getDeclarationContextType = getDeclarationContextType;
function reduceContextTypes(contexts) {
const reducer = (a, b) => {
if (a === ContextType.None) {
return b;
}
if (type.isUnion()) {
return TSHelper.reduceContextTypes(type.types.map(t => TSHelper.getFunctionContextType(t, checker)));
else if (b === ContextType.None) {
return a;
}
const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call);
if (signatures.length === 0) {
return ContextType.None;
else if (a !== b) {
return ContextType.Mixed;
}
const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker);
return TSHelper.reduceContextTypes(signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker)));
else {
return a;
}
};
return contexts.reduce(reducer, ContextType.None);
}
exports.reduceContextTypes = reduceContextTypes;
function getFunctionContextType(type, checker) {
if (type.isTypeParameter()) {
type = type.getConstraint() || type;
}
static escapeString(text) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
const escapeSequences = [
[/[\\]/g, "\\\\"],
[/[\']/g, "\\'"],
[/[\"]/g, '\\"'],
[/[\n]/g, "\\n"],
[/[\r]/g, "\\r"],
[/[\v]/g, "\\v"],
[/[\t]/g, "\\t"],
[/[\b]/g, "\\b"],
[/[\f]/g, "\\f"],
[/[\0]/g, "\\0"],
];
if (text.length > 0) {
for (const [regex, replacement] of escapeSequences) {
text = text.replace(regex, replacement);
}
if (type.isUnion()) {
return reduceContextTypes(type.types.map(t => getFunctionContextType(t, checker)));
}
const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call);
if (signatures.length === 0) {
return ContextType.None;
}
const signatureDeclarations = getSignatureDeclarations(signatures, checker);
return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(s, checker)));
}
exports.getFunctionContextType = getFunctionContextType;
function escapeString(text) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
const escapeSequences = [
[/[\\]/g, "\\\\"],
[/[\']/g, "\\'"],
[/[\"]/g, '\\"'],
[/[\n]/g, "\\n"],
[/[\r]/g, "\\r"],
[/[\v]/g, "\\v"],
[/[\t]/g, "\\t"],
[/[\b]/g, "\\b"],
[/[\f]/g, "\\f"],
[/[\0]/g, "\\0"],
];
if (text.length > 0) {
for (const [regex, replacement] of escapeSequences) {
text = text.replace(regex, replacement);
}
return text;
}
static isValidLuaIdentifier(str) {
const match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/);
return match !== undefined && match !== null && match[0] === str;
return text;
}
exports.escapeString = escapeString;
function isValidLuaIdentifier(str) {
const match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/);
return match !== undefined && match !== null && match[0] === str;
}
exports.isValidLuaIdentifier = isValidLuaIdentifier;
function fixInvalidLuaIdentifier(name) {
return name.replace(/[^a-zA-Z0-9_]/g, c => `_${c
.charCodeAt(0)
.toString(16)
.toUpperCase()}`);
}
exports.fixInvalidLuaIdentifier = fixInvalidLuaIdentifier;
// Checks that a name is valid for use in lua function declaration syntax:
// 'foo.bar' => passes ('function foo.bar()' is valid)
// 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal)
function isValidLuaFunctionDeclarationName(str) {
const match = str.match(/[a-zA-Z0-9_\.]+/);
return match !== undefined && match !== null && match[0] === str;
}
exports.isValidLuaFunctionDeclarationName = isValidLuaFunctionDeclarationName;
function isFalsible(type, strictNullChecks) {
const falsibleFlags = ts.TypeFlags.Boolean |
ts.TypeFlags.BooleanLiteral |
ts.TypeFlags.Undefined |
ts.TypeFlags.Null |
ts.TypeFlags.Never |
ts.TypeFlags.Void |
ts.TypeFlags.Any;
if (type.flags & falsibleFlags) {
return true;
}
static fixInvalidLuaIdentifier(name) {
return name.replace(/[^a-zA-Z0-9_]/g, c => `_${c
.charCodeAt(0)
.toString(16)
.toUpperCase()}`);
else if (!strictNullChecks && !type.isLiteral()) {
return true;
}
// Checks that a name is valid for use in lua function declaration syntax:
// 'foo.bar' => passes ('function foo.bar()' is valid)
// 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal)
static isValidLuaFunctionDeclarationName(str) {
const match = str.match(/[a-zA-Z0-9_\.]+/);
return match !== undefined && match !== null && match[0] === str;
}
static isFalsible(type, strictNullChecks) {
const falsibleFlags = ts.TypeFlags.Boolean |
ts.TypeFlags.BooleanLiteral |
ts.TypeFlags.Undefined |
ts.TypeFlags.Null |
ts.TypeFlags.Never |
ts.TypeFlags.Void |
ts.TypeFlags.Any;
if (type.flags & falsibleFlags) {
return true;
}
else if (!strictNullChecks && !type.isLiteral()) {
return true;
}
else if (type.isUnion()) {
for (const subType of type.types) {
if (TSHelper.isFalsible(subType, strictNullChecks)) {
return true;
}
else if (type.isUnion()) {
for (const subType of type.types) {
if (isFalsible(subType, strictNullChecks)) {
return true;
}
}
}
return false;
}
exports.isFalsible = isFalsible;
function getFirstDeclaration(symbol, sourceFile) {
let declarations = symbol.getDeclarations();
if (!declarations) {
return undefined;
}
if (sourceFile) {
declarations = declarations.filter(d => findFirstNodeAbove(d, ts.isSourceFile) === sourceFile);
}
return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined;
}
exports.getFirstDeclaration = getFirstDeclaration;
function getRawLiteral(node) {
let text = node.getText();
const isLast = node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === ts.SyntaxKind.TemplateTail;
text = text.substring(1, text.length - (isLast ? 1 : 2));
text = text.replace(/\r\n?/g, "\n").replace(/\\/g, "\\\\");
return text;
}
exports.getRawLiteral = getRawLiteral;
function isFirstDeclaration(node, checker) {
const symbol = checker.getSymbolAtLocation(node.name);
if (!symbol) {
return false;
}
static getFirstDeclaration(symbol, sourceFile) {
let declarations = symbol.getDeclarations();
if (!declarations) {
return undefined;
}
if (sourceFile) {
declarations = declarations.filter(d => this.findFirstNodeAbove(d, ts.isSourceFile) === sourceFile);
}
return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined;
const firstDeclaration = getFirstDeclaration(symbol);
return firstDeclaration === node;
}
exports.isFirstDeclaration = isFirstDeclaration;
function isStandardLibraryDeclaration(declaration, program) {
const source = declaration.getSourceFile();
if (!source) {
return false;
}
static isFirstDeclaration(node, checker) {
const symbol = checker.getSymbolAtLocation(node.name);
if (!symbol) {
return false;
}
const firstDeclaration = this.getFirstDeclaration(symbol);
return firstDeclaration === node;
return program.isSourceFileDefaultLibrary(source);
}
exports.isStandardLibraryDeclaration = isStandardLibraryDeclaration;
function isStandardLibraryType(type, name, program) {
const symbol = type.getSymbol();
if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === "__type")) {
return false;
}
static isStandardLibraryDeclaration(declaration, program) {
const source = declaration.getSourceFile();
if (!source) {
return false;
}
return program.isSourceFileDefaultLibrary(source);
const declaration = symbol.valueDeclaration;
if (!declaration) {
return true;
}
static isStandardLibraryType(type, name, program) {
const symbol = type.getSymbol();
if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === "__type")) {
return false;
}
const declaration = symbol.valueDeclaration;
if (!declaration) {
return true;
} // assume to be lib function if no valueDeclaration exists
return this.isStandardLibraryDeclaration(declaration, program);
}
static isEnumMember(enumDeclaration, value) {
if (ts.isIdentifier(value)) {
const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text);
if (enumMember !== undefined) {
if (enumMember.initializer && ts.isIdentifier(enumMember.initializer)) {
return this.isEnumMember(enumDeclaration, enumMember.initializer);
}
else {
return [true, enumMember.name];
}
// assume to be lib function if no valueDeclaration exists
return isStandardLibraryDeclaration(declaration, program);
}
exports.isStandardLibraryType = isStandardLibraryType;
function isEnumMember(enumDeclaration, value) {
if (ts.isIdentifier(value)) {
const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text);
if (enumMember !== undefined) {
if (enumMember.initializer && ts.isIdentifier(enumMember.initializer)) {
return isEnumMember(enumDeclaration, enumMember.initializer);
}
else {
return [false, undefined];
return [true, enumMember.name];
}

@@ -644,32 +699,80 @@ }

}
static moduleHasEmittedBody(statement) {
if (statement.body) {
if (ts.isModuleBlock(statement.body)) {
// Ignore if body has no emitted statements
return (statement.body.statements.findIndex(s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s)) !== -1);
}
else if (ts.isModuleDeclaration(statement.body)) {
return true;
}
}
else {
return [false, undefined];
}
}
exports.isEnumMember = isEnumMember;
function isWithinLiteralAssignmentStatement(node) {
if (!node.parent) {
return false;
}
static isArrayLengthAssignment(expression, checker, program) {
if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
return false;
if (ts.isArrayLiteralExpression(node.parent) || ts.isObjectLiteralExpression(node.parent)) {
return isWithinLiteralAssignmentStatement(node.parent);
}
else if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
return true;
}
else {
return false;
}
}
exports.isWithinLiteralAssignmentStatement = isWithinLiteralAssignmentStatement;
function moduleHasEmittedBody(statement) {
if (statement.body) {
if (ts.isModuleBlock(statement.body)) {
// Ignore if body has no emitted statements
return (statement.body.statements.findIndex(s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s)) !== -1);
}
if (!ts.isPropertyAccessExpression(expression.left) && !ts.isElementAccessExpression(expression.left)) {
return false;
else if (ts.isModuleDeclaration(statement.body)) {
return true;
}
const type = checker.getTypeAtLocation(expression.left.expression);
if (!TSHelper.isArrayType(type, checker, program)) {
}
return false;
}
exports.moduleHasEmittedBody = moduleHasEmittedBody;
function isArrayLengthAssignment(expression, checker, program) {
if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
return false;
}
if (!ts.isPropertyAccessExpression(expression.left) && !ts.isElementAccessExpression(expression.left)) {
return false;
}
const type = checker.getTypeAtLocation(expression.left.expression);
if (!isArrayType(type, checker, program)) {
return false;
}
const name = ts.isPropertyAccessExpression(expression.left)
? expression.left.name.escapedText
: ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text;
return name === "length";
}
exports.isArrayLengthAssignment = isArrayLengthAssignment;
// Returns true if expression contains no function calls
function isSimpleExpression(expression) {
switch (expression.kind) {
case tstl.SyntaxKind.CallExpression:
case tstl.SyntaxKind.MethodCallExpression:
case tstl.SyntaxKind.FunctionExpression:
return false;
}
const name = ts.isPropertyAccessExpression(expression.left)
? expression.left.name.escapedText
: ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text;
return name === "length";
case tstl.SyntaxKind.TableExpression:
const tableExpression = expression;
return !tableExpression.fields || tableExpression.fields.every(e => isSimpleExpression(e));
case tstl.SyntaxKind.TableFieldExpression:
const fieldExpression = expression;
return ((!fieldExpression.key || isSimpleExpression(fieldExpression.key)) &&
isSimpleExpression(fieldExpression.value));
case tstl.SyntaxKind.TableIndexExpression:
const indexExpression = expression;
return isSimpleExpression(indexExpression.table) && isSimpleExpression(indexExpression.index);
case tstl.SyntaxKind.UnaryExpression:
return isSimpleExpression(expression.operand);
case tstl.SyntaxKind.BinaryExpression:
const binaryExpression = expression;
return isSimpleExpression(binaryExpression.left) && isSimpleExpression(binaryExpression.right);
case tstl.SyntaxKind.ParenthesizedExpression:
return isSimpleExpression(expression.innerExpression);
}
return true;
}
exports.TSHelper = TSHelper;
exports.isSimpleExpression = isSimpleExpression;
//# sourceMappingURL=TSHelper.js.map
import * as ts from "typescript";
import { LuaTarget } from "./CompilerOptions";
import { TranspileError } from "./TranspileError";
import { LuaTarget } from "./CompilerOptions";
export declare class TSTLErrors {
static CouldNotCast: (castName: string) => Error;
static DefaultImportsNotSupported: (node: ts.Node) => TranspileError;
static ForbiddenEllipsisDestruction: (node: ts.Node) => TranspileError;
static ForbiddenForIn: (node: ts.Node) => TranspileError;
static ForbiddenLuaTableSetExpression: (node: ts.Node) => TranspileError;
static ForbiddenLuaTableNonDeclaration: (node: ts.Node) => TranspileError;
static InvalidExtendsLuaTable: (node: ts.Node) => TranspileError;
static InvalidInstanceOfLuaTable: (node: ts.Node) => TranspileError;
static ForbiddenLuaTableUseException: (description: string, node: ts.Node) => TranspileError;
static HeterogeneousEnum: (node: ts.Node) => TranspileError;
static InvalidDecoratorArgumentNumber: (name: string, got: number, expected: number, node: ts.Node) => TranspileError;
static InvalidDecoratorContext: (node: ts.Node) => TranspileError;
static InvalidExtensionMetaExtension: (node: ts.Node) => TranspileError;
static InvalidNewExpressionOnExtension: (node: ts.Node) => TranspileError;
static InvalidExportDeclaration: (declaration: ts.ExportDeclaration) => TranspileError;
static InvalidExtendsExtension: (node: ts.Node) => TranspileError;
static InvalidExportsExtension: (node: ts.Node) => TranspileError;
static InvalidInstanceOfExtension: (node: ts.Node) => TranspileError;
static InvalidJsonFileContent: (node: ts.Node) => TranspileError;
static InvalidPropertyCall: (node: ts.Node) => TranspileError;
static InvalidElementCall: (node: ts.Node) => TranspileError;
static InvalidThrowExpression: (node: ts.Node) => TranspileError;
static ForbiddenStaticClassPropertyName: (node: ts.Node, name: string) => TranspileError;
static MissingClassName: (node: ts.Node) => TranspileError;
static MissingForOfVariables: (node: ts.Node) => TranspileError;
static MissingFunctionName: (declaration: ts.FunctionLikeDeclaration) => TranspileError;
static MissingMetaExtension: (node: ts.Node) => TranspileError;
static MissingSourceFile: () => Error;
static UndefinedFunctionDefinition: (functionSymbolId: number) => Error;
static UndefinedScope: () => Error;
static UndefinedTypeNode: (node: ts.Node) => TranspileError;
static UnknownSuperType: (node: ts.Node) => TranspileError;
static UnsupportedDefaultExport: (node: ts.Node) => TranspileError;
static UnsupportedImportType: (node: ts.Node) => TranspileError;
static UnsupportedKind: (description: string, kind: ts.SyntaxKind, node: ts.Node) => TranspileError;
static UnsupportedProperty: (parentName: string, property: string, node: ts.Node) => TranspileError;
static UnsupportedForTarget: (functionality: string, version: LuaTarget, node: ts.Node) => TranspileError;
static UnsupportedFunctionWithoutBody: (node: ts.FunctionLikeDeclaration) => TranspileError;
static UnsupportedNoSelfFunctionConversion: (node: ts.Node, name?: string | undefined) => TranspileError;
static UnsupportedSelfFunctionConversion: (node: ts.Node, name?: string | undefined) => TranspileError;
static UnsupportedOverloadAssignment: (node: ts.Node, name?: string | undefined) => TranspileError;
static UnsupportedNonDestructuringLuaIterator: (node: ts.Node) => TranspileError;
static UnresolvableRequirePath: (node: ts.Node, reason: string, path?: string | undefined) => TranspileError;
static ReferencedBeforeDeclaration: (node: ts.Identifier) => TranspileError;
static UnsupportedObjectDestructuringInForOf: (node: ts.Node) => TranspileError;
static InvalidAmbientIdentifierName: (node: ts.Identifier) => TranspileError;
static InvalidForRangeCall: (node: ts.Node, message: string) => TranspileError;
}
export declare const CouldNotCast: (castName: string) => Error;
export declare const DefaultImportsNotSupported: (node: ts.Node) => TranspileError;
export declare const ForbiddenEllipsisDestruction: (node: ts.Node) => TranspileError;
export declare const ForbiddenForIn: (node: ts.Node) => TranspileError;
export declare const ForbiddenLuaTableSetExpression: (node: ts.Node) => TranspileError;
export declare const ForbiddenLuaTableNonDeclaration: (node: ts.Node) => TranspileError;
export declare const InvalidExtendsLuaTable: (node: ts.Node) => TranspileError;
export declare const InvalidInstanceOfLuaTable: (node: ts.Node) => TranspileError;
export declare const ForbiddenLuaTableUseException: (description: string, node: ts.Node) => TranspileError;
export declare const HeterogeneousEnum: (node: ts.Node) => TranspileError;
export declare const InvalidDecoratorArgumentNumber: (name: string, got: number, expected: number, node: ts.Node) => TranspileError;
export declare const InvalidDecoratorContext: (node: ts.Node) => TranspileError;
export declare const InvalidExtensionMetaExtension: (node: ts.Node) => TranspileError;
export declare const InvalidNewExpressionOnExtension: (node: ts.Node) => TranspileError;
export declare const InvalidExportDeclaration: (declaration: ts.ExportDeclaration) => TranspileError;
export declare const InvalidExtendsExtension: (node: ts.Node) => TranspileError;
export declare const InvalidExportsExtension: (node: ts.Node) => TranspileError;
export declare const InvalidInstanceOfExtension: (node: ts.Node) => TranspileError;
export declare const InvalidJsonFileContent: (node: ts.Node) => TranspileError;
export declare const InvalidPropertyCall: (node: ts.Node) => TranspileError;
export declare const InvalidElementCall: (node: ts.Node) => TranspileError;
export declare const InvalidThrowExpression: (node: ts.Node) => TranspileError;
export declare const ForbiddenStaticClassPropertyName: (node: ts.Node, name: string) => TranspileError;
export declare const MissingClassName: (node: ts.Node) => TranspileError;
export declare const MissingForOfVariables: (node: ts.Node) => TranspileError;
export declare const MissingFunctionName: (declaration: ts.FunctionLikeDeclaration) => TranspileError;
export declare const MissingMetaExtension: (node: ts.Node) => TranspileError;
export declare const MissingSourceFile: () => Error;
export declare const UndefinedFunctionDefinition: (functionSymbolId: number) => Error;
export declare const UndefinedScope: () => Error;
export declare const UndefinedTypeNode: (node: ts.Node) => TranspileError;
export declare const UnknownSuperType: (node: ts.Node) => TranspileError;
export declare const UnsupportedDefaultExport: (node: ts.Node) => TranspileError;
export declare const UnsupportedImportType: (node: ts.Node) => TranspileError;
export declare const UnsupportedKind: (description: string, kind: ts.SyntaxKind, node: ts.Node) => TranspileError;
export declare const UnsupportedProperty: (parentName: string, property: string, node: ts.Node) => TranspileError;
export declare const UnsupportedForTarget: (functionality: string, version: LuaTarget, node: ts.Node) => TranspileError;
export declare const UnsupportedFunctionWithoutBody: (node: ts.FunctionLikeDeclaration) => TranspileError;
export declare const UnsupportedNoSelfFunctionConversion: (node: ts.Node, name?: string | undefined) => TranspileError;
export declare const UnsupportedSelfFunctionConversion: (node: ts.Node, name?: string | undefined) => TranspileError;
export declare const UnsupportedOverloadAssignment: (node: ts.Node, name?: string | undefined) => TranspileError;
export declare const UnsupportedNonDestructuringLuaIterator: (node: ts.Node) => TranspileError;
export declare const UnresolvableRequirePath: (node: ts.Node, reason: string, path?: string | undefined) => TranspileError;
export declare const ReferencedBeforeDeclaration: (node: ts.Identifier) => TranspileError;
export declare const UnsupportedObjectDestructuringInForOf: (node: ts.Node) => TranspileError;
export declare const InvalidAmbientIdentifierName: (node: ts.Identifier) => TranspileError;
export declare const InvalidForRangeCall: (node: ts.Node, message: string) => TranspileError;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ts = require("typescript");
const CompilerOptions_1 = require("./CompilerOptions");
const TranspileError_1 = require("./TranspileError");
const CompilerOptions_1 = require("./CompilerOptions");
const getLuaTargetName = (version) => (version === CompilerOptions_1.LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`);
class TSTLErrors {
}
TSTLErrors.CouldNotCast = (castName) => new Error(`Failed to cast all elements to expected type using ${castName}.`);
TSTLErrors.DefaultImportsNotSupported = (node) => new TranspileError_1.TranspileError(`Default Imports are not supported, please use named imports instead!`, node);
TSTLErrors.ForbiddenEllipsisDestruction = (node) => new TranspileError_1.TranspileError(`Ellipsis destruction is not allowed.`, node);
TSTLErrors.ForbiddenForIn = (node) => new TranspileError_1.TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node);
TSTLErrors.ForbiddenLuaTableSetExpression = (node) => new TranspileError_1.TranspileError(`A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, node);
TSTLErrors.ForbiddenLuaTableNonDeclaration = (node) => new TranspileError_1.TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node);
TSTLErrors.InvalidExtendsLuaTable = (node) => new TranspileError_1.TranspileError(`Cannot extend classes with the decorator '@luaTable'.`, node);
TSTLErrors.InvalidInstanceOfLuaTable = (node) => new TranspileError_1.TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node);
TSTLErrors.ForbiddenLuaTableUseException = (description, node) => new TranspileError_1.TranspileError(`Invalid @luaTable usage: ${description}`, node);
TSTLErrors.HeterogeneousEnum = (node) => new TranspileError_1.TranspileError(`Invalid heterogeneous enum. Enums should either specify no member values, ` +
exports.CouldNotCast = (castName) => new Error(`Failed to cast all elements to expected type using ${castName}.`);
exports.DefaultImportsNotSupported = (node) => new TranspileError_1.TranspileError(`Default Imports are not supported, please use named imports instead!`, node);
exports.ForbiddenEllipsisDestruction = (node) => new TranspileError_1.TranspileError(`Ellipsis destruction is not allowed.`, node);
exports.ForbiddenForIn = (node) => new TranspileError_1.TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node);
exports.ForbiddenLuaTableSetExpression = (node) => new TranspileError_1.TranspileError(`A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, node);
exports.ForbiddenLuaTableNonDeclaration = (node) => new TranspileError_1.TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node);
exports.InvalidExtendsLuaTable = (node) => new TranspileError_1.TranspileError(`Cannot extend classes with the decorator '@luaTable'.`, node);
exports.InvalidInstanceOfLuaTable = (node) => new TranspileError_1.TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node);
exports.ForbiddenLuaTableUseException = (description, node) => new TranspileError_1.TranspileError(`Invalid @luaTable usage: ${description}`, node);
exports.HeterogeneousEnum = (node) => new TranspileError_1.TranspileError(`Invalid heterogeneous enum. Enums should either specify no member values, ` +
`or specify values (of the same type) for all members.`, node);
TSTLErrors.InvalidDecoratorArgumentNumber = (name, got, expected, node) => new TranspileError_1.TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node);
TSTLErrors.InvalidDecoratorContext = (node) => new TranspileError_1.TranspileError(`Decorator function cannot have 'this: void'.`, node);
TSTLErrors.InvalidExtensionMetaExtension = (node) => new TranspileError_1.TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node);
TSTLErrors.InvalidNewExpressionOnExtension = (node) => new TranspileError_1.TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node);
TSTLErrors.InvalidExportDeclaration = (declaration) => new TranspileError_1.TranspileError("Encountered invalid export declaration without exports and without module.", declaration);
TSTLErrors.InvalidExtendsExtension = (node) => new TranspileError_1.TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node);
TSTLErrors.InvalidExportsExtension = (node) => new TranspileError_1.TranspileError(`Cannot export classes with decorator '@extension' or '@metaExtension'.`, node);
TSTLErrors.InvalidInstanceOfExtension = (node) => new TranspileError_1.TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node);
TSTLErrors.InvalidJsonFileContent = (node) => new TranspileError_1.TranspileError("Invalid JSON file content", node);
TSTLErrors.InvalidPropertyCall = (node) => new TranspileError_1.TranspileError(`Tried to transpile a non-property call as property call.`, node);
TSTLErrors.InvalidElementCall = (node) => new TranspileError_1.TranspileError(`Tried to transpile a non-element call as an element call.`, node);
TSTLErrors.InvalidThrowExpression = (node) => new TranspileError_1.TranspileError(`Invalid throw expression, only strings can be thrown.`, node);
TSTLErrors.ForbiddenStaticClassPropertyName = (node, name) => new TranspileError_1.TranspileError(`Cannot use "${name}" as a static class property or method name.`, node);
TSTLErrors.MissingClassName = (node) => new TranspileError_1.TranspileError(`Class declarations must have a name.`, node);
TSTLErrors.MissingForOfVariables = (node) => new TranspileError_1.TranspileError("Transpiled ForOf variable declaration list contains no declarations.", node);
TSTLErrors.MissingFunctionName = (declaration) => new TranspileError_1.TranspileError("Unsupported function declaration without name.", declaration);
TSTLErrors.MissingMetaExtension = (node) => new TranspileError_1.TranspileError(`@metaExtension requires the extension of the metatable class.`, node);
TSTLErrors.MissingSourceFile = () => new Error("Expected transformer.sourceFile to be set, but it isn't.");
TSTLErrors.UndefinedFunctionDefinition = (functionSymbolId) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`);
TSTLErrors.UndefinedScope = () => new Error("Expected to pop a scope, but found undefined.");
TSTLErrors.UndefinedTypeNode = (node) => new TranspileError_1.TranspileError("Failed to resolve required type node.", node);
TSTLErrors.UnknownSuperType = (node) => new TranspileError_1.TranspileError("Unable to resolve type of super expression.", node);
TSTLErrors.UnsupportedDefaultExport = (node) => new TranspileError_1.TranspileError(`Default exports are not supported.`, node);
TSTLErrors.UnsupportedImportType = (node) => new TranspileError_1.TranspileError(`Unsupported import type.`, node);
TSTLErrors.UnsupportedKind = (description, kind, node) => new TranspileError_1.TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node);
TSTLErrors.UnsupportedProperty = (parentName, property, node) => new TranspileError_1.TranspileError(`Unsupported property on ${parentName}: ${property}`, node);
TSTLErrors.UnsupportedForTarget = (functionality, version, node) => new TranspileError_1.TranspileError(`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`, node);
TSTLErrors.UnsupportedFunctionWithoutBody = (node) => new TranspileError_1.TranspileError("Functions with undefined bodies are not supported.", node);
TSTLErrors.UnsupportedNoSelfFunctionConversion = (node, name) => {
exports.InvalidDecoratorArgumentNumber = (name, got, expected, node) => new TranspileError_1.TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node);
exports.InvalidDecoratorContext = (node) => new TranspileError_1.TranspileError(`Decorator function cannot have 'this: void'.`, node);
exports.InvalidExtensionMetaExtension = (node) => new TranspileError_1.TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node);
exports.InvalidNewExpressionOnExtension = (node) => new TranspileError_1.TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node);
exports.InvalidExportDeclaration = (declaration) => new TranspileError_1.TranspileError("Encountered invalid export declaration without exports and without module.", declaration);
exports.InvalidExtendsExtension = (node) => new TranspileError_1.TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node);
exports.InvalidExportsExtension = (node) => new TranspileError_1.TranspileError(`Cannot export classes with decorator '@extension' or '@metaExtension'.`, node);
exports.InvalidInstanceOfExtension = (node) => new TranspileError_1.TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node);
exports.InvalidJsonFileContent = (node) => new TranspileError_1.TranspileError("Invalid JSON file content", node);
exports.InvalidPropertyCall = (node) => new TranspileError_1.TranspileError(`Tried to transpile a non-property call as property call.`, node);
exports.InvalidElementCall = (node) => new TranspileError_1.TranspileError(`Tried to transpile a non-element call as an element call.`, node);
exports.InvalidThrowExpression = (node) => new TranspileError_1.TranspileError(`Invalid throw expression, only strings can be thrown.`, node);
exports.ForbiddenStaticClassPropertyName = (node, name) => new TranspileError_1.TranspileError(`Cannot use "${name}" as a static class property or method name.`, node);
exports.MissingClassName = (node) => new TranspileError_1.TranspileError(`Class declarations must have a name.`, node);
exports.MissingForOfVariables = (node) => new TranspileError_1.TranspileError("Transpiled ForOf variable declaration list contains no declarations.", node);
exports.MissingFunctionName = (declaration) => new TranspileError_1.TranspileError("Unsupported function declaration without name.", declaration);
exports.MissingMetaExtension = (node) => new TranspileError_1.TranspileError(`@metaExtension requires the extension of the metatable class.`, node);
exports.MissingSourceFile = () => new Error("Expected transformer.sourceFile to be set, but it isn't.");
exports.UndefinedFunctionDefinition = (functionSymbolId) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`);
exports.UndefinedScope = () => new Error("Expected to pop a scope, but found undefined.");
exports.UndefinedTypeNode = (node) => new TranspileError_1.TranspileError("Failed to resolve required type node.", node);
exports.UnknownSuperType = (node) => new TranspileError_1.TranspileError("Unable to resolve type of super expression.", node);
exports.UnsupportedDefaultExport = (node) => new TranspileError_1.TranspileError(`Default exports are not supported.`, node);
exports.UnsupportedImportType = (node) => new TranspileError_1.TranspileError(`Unsupported import type.`, node);
exports.UnsupportedKind = (description, kind, node) => new TranspileError_1.TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node);
exports.UnsupportedProperty = (parentName, property, node) => new TranspileError_1.TranspileError(`Unsupported property on ${parentName}: ${property}`, node);
exports.UnsupportedForTarget = (functionality, version, node) => new TranspileError_1.TranspileError(`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`, node);
exports.UnsupportedFunctionWithoutBody = (node) => new TranspileError_1.TranspileError("Functions with undefined bodies are not supported.", node);
exports.UnsupportedNoSelfFunctionConversion = (node, name) => {
if (name) {

@@ -58,3 +56,3 @@ return new TranspileError_1.TranspileError(`Unable to convert function with a 'this' parameter to function "${name}" with no 'this'. ` +

};
TSTLErrors.UnsupportedSelfFunctionConversion = (node, name) => {
exports.UnsupportedSelfFunctionConversion = (node, name) => {
if (name) {

@@ -69,3 +67,3 @@ return new TranspileError_1.TranspileError(`Unable to convert function with no 'this' parameter to function "${name}" with 'this'. ` +

};
TSTLErrors.UnsupportedOverloadAssignment = (node, name) => {
exports.UnsupportedOverloadAssignment = (node, name) => {
if (name) {

@@ -80,3 +78,3 @@ return new TranspileError_1.TranspileError(`Unsupported assignment of function with different overloaded types for 'this' to "${name}". ` +

};
TSTLErrors.UnsupportedNonDestructuringLuaIterator = (node) => {
exports.UnsupportedNonDestructuringLuaIterator = (node) => {
return new TranspileError_1.TranspileError("Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " +

@@ -86,19 +84,18 @@ "You must use a destructuring statement to catch results from a lua iterator with " +

};
TSTLErrors.UnresolvableRequirePath = (node, reason, path) => {
exports.UnresolvableRequirePath = (node, reason, path) => {
return new TranspileError_1.TranspileError(`${reason}. ` + `TypeScript path: ${path}.`, node);
};
TSTLErrors.ReferencedBeforeDeclaration = (node) => {
exports.ReferencedBeforeDeclaration = (node) => {
return new TranspileError_1.TranspileError(`Identifier "${node.text}" was referenced before it was declared. The declaration ` +
"must be moved before the identifier's use, or hoisting must be enabled.", node);
};
TSTLErrors.UnsupportedObjectDestructuringInForOf = (node) => {
exports.UnsupportedObjectDestructuringInForOf = (node) => {
return new TranspileError_1.TranspileError(`Unsupported object destructuring in for...of statement.`, node);
};
TSTLErrors.InvalidAmbientIdentifierName = (node) => {
exports.InvalidAmbientIdentifierName = (node) => {
return new TranspileError_1.TranspileError(`Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, node);
};
TSTLErrors.InvalidForRangeCall = (node, message) => {
exports.InvalidForRangeCall = (node, message) => {
return new TranspileError_1.TranspileError(`Invalid @forRange call: ${message}`, node);
};
exports.TSTLErrors = TSTLErrors;
//# sourceMappingURL=TSTLErrors.js.map
{
"name": "typescript-to-lua",
"version": "0.22.1",
"version": "0.23.0",
"description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",

@@ -5,0 +5,0 @@ "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc