Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ node_js:
- stable

script:
- npm run lint
- npm run build
- npm test -- --coverage
after_success: npx codecov
Expand Down
4 changes: 3 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
environment:
nodejs_version: "8"

# Do not build feature branch with open Pull Requests
skip_branch_with_pr: true

# Cache dependencies
cache:
- node_modules
Expand All @@ -19,7 +22,6 @@ test_script:
- node --version
- npm --version
# run tests
- npm run lint
- npm run build
- npm test

Expand Down
5 changes: 4 additions & 1 deletion build_lualib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ if (fs.existsSync(bundlePath)) {
fs.unlinkSync(bundlePath);
}

const bundle = luaLib.loadFeatures(Object.keys(LuaLibFeature).map(lib => LuaLibFeature[lib]));
const features = Object.keys(LuaLibFeature).map(
lib => LuaLibFeature[lib as keyof typeof LuaLibFeature],
);
const bundle = luaLib.loadFeatures(features);
fs.writeFileSync(bundlePath, bundle);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"scripts": {
"build": "tsc -p tsconfig.json && npm run build-lualib",
"build-lualib": "ts-node ./build_lualib.ts",
"pretest": "ts-node --transpile-only ./build_lualib.ts",
"pretest": "npm run lint && ts-node --transpile-only ./build_lualib.ts",
"test": "jest",
"lint": "npm run lint:tslint && npm run lint:prettier",
"lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)",
Expand Down
6 changes: 3 additions & 3 deletions src/CommandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export function parseTsConfigString(
}

function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CLIParseResult {
const result = {};
const result: { [key: string]: string | boolean } = {};
for (let i = 0; i < args.length; i++) {
if (args[i].startsWith("--")) {
const argumentName = args[i].substr(2);
Expand All @@ -245,15 +245,15 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL
}
} else if (args[i].startsWith("-")) {
const argument = args[i].substr(1);
let argumentName: string;
let argumentName: string | undefined;
for (const key in optionDeclarations) {
if (optionDeclarations[key].aliases && optionDeclarations[key].aliases.indexOf(argument) >= 0) {
argumentName = key;
break;
}
}

if (argumentName) {
if (argumentName !== undefined) {
const argumentResult = getArgumentValue(argumentName, i, args);
if (argumentResult.isValid === true) {
result[argumentName] = argumentResult.result;
Expand Down
33 changes: 18 additions & 15 deletions src/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,9 @@ export function compile(argv: string[]): void {

/* istanbul ignore next: tested in test/compiler/watchmode.spec with subproccess */
export function watchWithOptions(fileNames: string[], options: CompilerOptions): void {
let host: ts.WatchCompilerHost<ts.SemanticDiagnosticsBuilderProgram>;
let config = false;
if (options.project) {
config = true;
host = ts.createWatchCompilerHost(options.project, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram);
} else {
host = ts.createWatchCompilerHost(fileNames, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram);
}
const host = options.project !== undefined
? ts.createWatchCompilerHost(options.project, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram)
: ts.createWatchCompilerHost(fileNames, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram);

let fullRecompile = true;
host.afterProgramCreate = program => {
Expand Down Expand Up @@ -71,7 +66,7 @@ export function watchWithOptions(fileNames: string[], options: CompilerOptions):
}

const errorDiagnostic: ts.Diagnostic = {
category: undefined,
category: ts.DiagnosticCategory.Error,
code: 6194,
file: undefined,
length: 0,
Expand All @@ -82,10 +77,13 @@ export function watchWithOptions(fileNames: string[], options: CompilerOptions):
errorDiagnostic.messageText = "Found Errors. Watching for file changes.";
errorDiagnostic.code = 6193;
}
host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions());

if (host.onWatchStatusChange) {
host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions());
}
};

if (config) {
if (options.project !== undefined) {
ts.createWatchProgram(
host as ts.WatchCompilerHostOfConfigFile<ts.SemanticDiagnosticsBuilderProgram>
);
Expand Down Expand Up @@ -118,8 +116,8 @@ export function createStringCompilerProgram(
): ts.Program {
const compilerHost = {
directoryExists: () => true,
fileExists: (fileName): boolean => true,
getCanonicalFileName: fileName => fileName,
fileExists: () => true,
getCanonicalFileName: (fileName: string) => fileName,
getCurrentDirectory: () => "",
getDefaultLibFileName: ts.getDefaultLibFileName,
getDirectories: () => [],
Expand Down Expand Up @@ -156,7 +154,7 @@ export function createStringCompilerProgram(

useCaseSensitiveFileNames: () => false,
// Don't write output
writeFile: (name, text, writeByteOrderMark) => undefined,
writeFile: () => undefined,
};
const filePaths = typeof input === "string" ? [filePath] : Object.keys(input);
return ts.createProgram(filePaths, options, compilerHost);
Expand All @@ -182,5 +180,10 @@ export function transpileString(

const transpiler = new LuaTranspiler(program);

return transpiler.transpileSourceFile(program.getSourceFile(filePath));
const sourceFile = program.getSourceFile(filePath);
if (sourceFile !== undefined) {
return transpiler.transpileSourceFile(sourceFile);
} else {
throw new Error(`Could not find file ${filePath} in created program.`);
}
}
9 changes: 7 additions & 2 deletions src/Decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export class Decorator {
return this.getDecoratorKind(decoratorKindString) !== undefined;
}

public static getDecoratorKind(decoratorKindString: string): DecoratorKind {
public static getDecoratorKind(decoratorKindString: string): DecoratorKind | undefined {
switch (decoratorKindString.toLowerCase()) {
case "extension":
return DecoratorKind.Extension;
Expand Down Expand Up @@ -36,7 +36,12 @@ export class Decorator {
public args: string[];

constructor(name: string, args: string[]) {
this.kind = Decorator.getDecoratorKind(name);
const kind = Decorator.getDecoratorKind(name);
if (kind === undefined) {
throw new Error(`Failed to parse decorator '${name}'`);
}

this.kind = kind;
this.args = args;
}
}
Expand Down
29 changes: 19 additions & 10 deletions src/LuaAST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ export interface Node extends TextRange {
}

export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node, parent?: Node): Node {
if (tsOriginal === undefined) {
return {kind, parent};
}

const sourcePosition = getSourcePosition(tsOriginal);
if (sourcePosition) {
return {kind, parent, line: sourcePosition.line, column: sourcePosition.column};
Expand All @@ -128,7 +132,11 @@ export function setNodePosition<T extends Node>(node: T, position: TextRange): T
return node;
}

export function setNodeOriginal<T extends Node>(node: T, tsOriginal: ts.Node): T {
export function setNodeOriginal<T extends Node>(node: T | undefined, tsOriginal: ts.Node): T | undefined {
if (node === undefined) {
return undefined;
}

const sourcePosition = getSourcePosition(tsOriginal);
if (sourcePosition) {
setNodePosition(node, sourcePosition);
Expand Down Expand Up @@ -172,14 +180,14 @@ export function getOriginalPos(node: Node): TextRange {

export interface Block extends Node {
kind: SyntaxKind.Block;
statements?: Statement[];
statements: Statement[];
}

export function isBlock(node: Node): node is Block {
return node.kind === SyntaxKind.Block;
}

export function createBlock(statements?: Statement[], tsOriginal?: ts.Node, parent?: Node): Block {
export function createBlock(statements: Statement[], tsOriginal?: ts.Node, parent?: Node): Block {
const block = createNode(SyntaxKind.Block, tsOriginal, parent) as Block;
setParent(statements, block);
block.statements = statements;
Expand All @@ -192,14 +200,14 @@ export interface Statement extends Node {

export interface DoStatement extends Statement {
kind: SyntaxKind.DoStatement;
statements?: Statement[];
statements: Statement[];
}

export function isDoStatement(node: Node): node is DoStatement {
return node.kind === SyntaxKind.DoStatement;
}

export function createDoStatement(statements?: Statement[], tsOriginal?: ts.Node, parent?: Node): DoStatement {
export function createDoStatement(statements: Statement[], tsOriginal?: ts.Node, parent?: Node): DoStatement {
const statement = createNode(SyntaxKind.DoStatement, tsOriginal, parent) as DoStatement;
setParent(statements, statement);
statement.statements = statements;
Expand Down Expand Up @@ -257,7 +265,7 @@ export function isAssignmentStatement(node: Node): node is AssignmentStatement {

export function createAssignmentStatement(
left: IdentifierOrTableIndexExpression | IdentifierOrTableIndexExpression[],
right: Expression | Expression[],
right?: Expression | Expression[],
tsOriginal?: ts.Node,
parent?: Node
): AssignmentStatement
Expand All @@ -273,7 +281,7 @@ export function createAssignmentStatement(
if (Array.isArray(right)) {
statement.right = right;
} else {
statement.right = [right];
statement.right = right ? [right] : [];
}
return statement;
}
Expand Down Expand Up @@ -878,18 +886,19 @@ export function isFunctionDefinition(statement: VariableDeclarationStatement | A
: statement is FunctionDefinition
{
return statement.left.length === 1
&& statement.right
&& statement.right !== undefined
&& statement.right.length === 1
&& isFunctionExpression(statement.right[0]);
}

export type InlineFunctionExpression = FunctionExpression & {
body: { statements: [ReturnStatement]; };
body: { statements: [ReturnStatement & { expressions: Expression[] }]; };
};

export function isInlineFunctionExpression(expression: FunctionExpression) : expression is InlineFunctionExpression {
return expression.body.statements
return expression.body.statements !== undefined
&& expression.body.statements.length === 1
&& isReturnStatement(expression.body.statements[0])
&& (expression.body.statements[0] as ReturnStatement).expressions !== undefined
&& (expression.flags & FunctionExpressionFlags.Inline) !== 0;
}
5 changes: 3 additions & 2 deletions src/LuaLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ export class LuaLib {
function load(feature: LuaLibFeature): void {
if (!loadedFeatures.has(feature)) {
loadedFeatures.add(feature);
if (luaLibDependencies[feature]) {
luaLibDependencies[feature].forEach(load);
const dependencies = luaLibDependencies[feature];
if (dependencies) {
dependencies.forEach(load);
}
const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`);
result += fs.readFileSync(featureFile).toString() + "\n";
Expand Down
29 changes: 19 additions & 10 deletions src/LuaPrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ export class LuaPrinter {
private options: CompilerOptions;
private currentIndent: string;

private sourceFile: string;
private sourceFile = "";

public constructor(options: CompilerOptions) {
this.options = options;
this.currentIndent = "";
}

public print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>, sourceFile?: string): [string, string] {
public print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>, sourceFile = ""): [string, string] {
// Add traceback lualib if sourcemap traceback option is enabled
if (this.options.sourceMapTraceback) {
if (luaLibFeatures === undefined) {
Expand Down Expand Up @@ -113,7 +113,7 @@ export class LuaPrinter {
private printImplementation(
block: tstl.Block,
luaLibFeatures?: Set<LuaLibFeature>,
sourceFile?: string): SourceNode {
sourceFile = ""): SourceNode {

let header = "";

Expand Down Expand Up @@ -162,13 +162,15 @@ export class LuaPrinter {
private createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode {
const originalPos = tstl.getOriginalPos(node);

return originalPos !== undefined
return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined
? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks)
: new SourceNode(undefined, undefined, this.sourceFile, chunks);
// tslint:disable-next-line:no-null-keyword
: new SourceNode(null, null, this.sourceFile, chunks);
}

private concatNodes(...chunks: SourceChunk[]): SourceNode {
return new SourceNode(undefined, undefined, this.sourceFile, chunks);
// tslint:disable-next-line:no-null-keyword
return new SourceNode(null, null, this.sourceFile, chunks);
}

private printBlock(block: tstl.Block): SourceNode {
Expand Down Expand Up @@ -616,19 +618,26 @@ export class LuaPrinter {

private printCallExpression(expression: tstl.CallExpression): SourceNode {
const chunks = [];
const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e)));

chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")");
const parameterChunks = expression.params !== undefined
? expression.params.map(e => this.printExpression(e))
: [];

chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")");

return this.concatNodes(...chunks);
}

private printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode {
const prefix = this.printExpression(expression.prefixExpression);
const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e)));

const parameterChunks = expression.params !== undefined
? expression.params.map(e => this.printExpression(e))
: [];

const name = this.printIdentifier(expression.name);

return this.concatNodes(prefix, ":", name, "(", ...parameterChunks, ")");
return this.concatNodes(prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")");
}

private printIdentifier(expression: tstl.Identifier): SourceNode {
Expand Down
Loading