Skip to content

Commit 27ae2a8

Browse files
authored
Enabled strict config (#515)
* Fixed strict issues everywhere except transformer * Strict fixes and interface changes * More fixes, addressed PR comments * Fixed some more undefined errors * fixes for last compile errors (#518) * Fixed tests failing * Ran prettier on build_lualib.ts * Fixed jest ignoring diagnostics * Cleaned up throws * Changed non-null expression to explicit undefined check * Addressed PR feedback * Test appveyor settings * Revert appveyor changes * Fix master's strict violations * revert jest config changes * strict tests * Fixed strict test issues * Fixed prettier, added lint step to pretest * Test util method with undefined typeguard
1 parent 16a61b7 commit 27ae2a8

27 files changed

+1155
-488
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ node_js:
33
- stable
44

55
script:
6-
- npm run lint
76
- npm run build
87
- npm test -- --coverage
98
after_success: npx codecov

appveyor.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
environment:
33
nodejs_version: "8"
44

5+
# Do not build feature branch with open Pull Requests
6+
skip_branch_with_pr: true
7+
58
# Cache dependencies
69
cache:
710
- node_modules
@@ -19,7 +22,6 @@ test_script:
1922
- node --version
2023
- npm --version
2124
# run tests
22-
- npm run lint
2325
- npm run build
2426
- npm test
2527

build_lualib.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@ if (fs.existsSync(bundlePath)) {
2727
fs.unlinkSync(bundlePath);
2828
}
2929

30-
const bundle = luaLib.loadFeatures(Object.keys(LuaLibFeature).map(lib => LuaLibFeature[lib]));
30+
const features = Object.keys(LuaLibFeature).map(
31+
lib => LuaLibFeature[lib as keyof typeof LuaLibFeature],
32+
);
33+
const bundle = luaLib.loadFeatures(features);
3134
fs.writeFileSync(bundlePath, bundle);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"scripts": {
2121
"build": "tsc -p tsconfig.json && npm run build-lualib",
2222
"build-lualib": "ts-node ./build_lualib.ts",
23-
"pretest": "ts-node --transpile-only ./build_lualib.ts",
23+
"pretest": "npm run lint && ts-node --transpile-only ./build_lualib.ts",
2424
"test": "jest",
2525
"lint": "npm run lint:tslint && npm run lint:prettier",
2626
"lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)",

src/CommandLineParser.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export function parseTsConfigString(
228228
}
229229

230230
function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CLIParseResult {
231-
const result = {};
231+
const result: { [key: string]: string | boolean } = {};
232232
for (let i = 0; i < args.length; i++) {
233233
if (args[i].startsWith("--")) {
234234
const argumentName = args[i].substr(2);
@@ -245,15 +245,15 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL
245245
}
246246
} else if (args[i].startsWith("-")) {
247247
const argument = args[i].substr(1);
248-
let argumentName: string;
248+
let argumentName: string | undefined;
249249
for (const key in optionDeclarations) {
250250
if (optionDeclarations[key].aliases && optionDeclarations[key].aliases.indexOf(argument) >= 0) {
251251
argumentName = key;
252252
break;
253253
}
254254
}
255255

256-
if (argumentName) {
256+
if (argumentName !== undefined) {
257257
const argumentResult = getArgumentValue(argumentName, i, args);
258258
if (argumentResult.isValid === true) {
259259
result[argumentName] = argumentResult.result;

src/Compiler.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,9 @@ export function compile(argv: string[]): void {
3333

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

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

7368
const errorDiagnostic: ts.Diagnostic = {
74-
category: undefined,
69+
category: ts.DiagnosticCategory.Error,
7570
code: 6194,
7671
file: undefined,
7772
length: 0,
@@ -82,10 +77,13 @@ export function watchWithOptions(fileNames: string[], options: CompilerOptions):
8277
errorDiagnostic.messageText = "Found Errors. Watching for file changes.";
8378
errorDiagnostic.code = 6193;
8479
}
85-
host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions());
80+
81+
if (host.onWatchStatusChange) {
82+
host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions());
83+
}
8684
};
8785

88-
if (config) {
86+
if (options.project !== undefined) {
8987
ts.createWatchProgram(
9088
host as ts.WatchCompilerHostOfConfigFile<ts.SemanticDiagnosticsBuilderProgram>
9189
);
@@ -118,8 +116,8 @@ export function createStringCompilerProgram(
118116
): ts.Program {
119117
const compilerHost = {
120118
directoryExists: () => true,
121-
fileExists: (fileName): boolean => true,
122-
getCanonicalFileName: fileName => fileName,
119+
fileExists: () => true,
120+
getCanonicalFileName: (fileName: string) => fileName,
123121
getCurrentDirectory: () => "",
124122
getDefaultLibFileName: ts.getDefaultLibFileName,
125123
getDirectories: () => [],
@@ -156,7 +154,7 @@ export function createStringCompilerProgram(
156154

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

183181
const transpiler = new LuaTranspiler(program);
184182

185-
return transpiler.transpileSourceFile(program.getSourceFile(filePath));
183+
const sourceFile = program.getSourceFile(filePath);
184+
if (sourceFile !== undefined) {
185+
return transpiler.transpileSourceFile(sourceFile);
186+
} else {
187+
throw new Error(`Could not find file ${filePath} in created program.`);
188+
}
186189
}

src/Decorator.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export class Decorator {
33
return this.getDecoratorKind(decoratorKindString) !== undefined;
44
}
55

6-
public static getDecoratorKind(decoratorKindString: string): DecoratorKind {
6+
public static getDecoratorKind(decoratorKindString: string): DecoratorKind | undefined {
77
switch (decoratorKindString.toLowerCase()) {
88
case "extension":
99
return DecoratorKind.Extension;
@@ -36,7 +36,12 @@ export class Decorator {
3636
public args: string[];
3737

3838
constructor(name: string, args: string[]) {
39-
this.kind = Decorator.getDecoratorKind(name);
39+
const kind = Decorator.getDecoratorKind(name);
40+
if (kind === undefined) {
41+
throw new Error(`Failed to parse decorator '${name}'`);
42+
}
43+
44+
this.kind = kind;
4045
this.args = args;
4146
}
4247
}

src/LuaAST.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ export interface Node extends TextRange {
109109
}
110110

111111
export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node, parent?: Node): Node {
112+
if (tsOriginal === undefined) {
113+
return {kind, parent};
114+
}
115+
112116
const sourcePosition = getSourcePosition(tsOriginal);
113117
if (sourcePosition) {
114118
return {kind, parent, line: sourcePosition.line, column: sourcePosition.column};
@@ -128,7 +132,11 @@ export function setNodePosition<T extends Node>(node: T, position: TextRange): T
128132
return node;
129133
}
130134

131-
export function setNodeOriginal<T extends Node>(node: T, tsOriginal: ts.Node): T {
135+
export function setNodeOriginal<T extends Node>(node: T | undefined, tsOriginal: ts.Node): T | undefined {
136+
if (node === undefined) {
137+
return undefined;
138+
}
139+
132140
const sourcePosition = getSourcePosition(tsOriginal);
133141
if (sourcePosition) {
134142
setNodePosition(node, sourcePosition);
@@ -172,14 +180,14 @@ export function getOriginalPos(node: Node): TextRange {
172180

173181
export interface Block extends Node {
174182
kind: SyntaxKind.Block;
175-
statements?: Statement[];
183+
statements: Statement[];
176184
}
177185

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

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

193201
export interface DoStatement extends Statement {
194202
kind: SyntaxKind.DoStatement;
195-
statements?: Statement[];
203+
statements: Statement[];
196204
}
197205

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

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

258266
export function createAssignmentStatement(
259267
left: IdentifierOrTableIndexExpression | IdentifierOrTableIndexExpression[],
260-
right: Expression | Expression[],
268+
right?: Expression | Expression[],
261269
tsOriginal?: ts.Node,
262270
parent?: Node
263271
): AssignmentStatement
@@ -273,7 +281,7 @@ export function createAssignmentStatement(
273281
if (Array.isArray(right)) {
274282
statement.right = right;
275283
} else {
276-
statement.right = [right];
284+
statement.right = right ? [right] : [];
277285
}
278286
return statement;
279287
}
@@ -878,18 +886,19 @@ export function isFunctionDefinition(statement: VariableDeclarationStatement | A
878886
: statement is FunctionDefinition
879887
{
880888
return statement.left.length === 1
881-
&& statement.right
889+
&& statement.right !== undefined
882890
&& statement.right.length === 1
883891
&& isFunctionExpression(statement.right[0]);
884892
}
885893

886894
export type InlineFunctionExpression = FunctionExpression & {
887-
body: { statements: [ReturnStatement]; };
895+
body: { statements: [ReturnStatement & { expressions: Expression[] }]; };
888896
};
889897

890898
export function isInlineFunctionExpression(expression: FunctionExpression) : expression is InlineFunctionExpression {
891-
return expression.body.statements
899+
return expression.body.statements !== undefined
892900
&& expression.body.statements.length === 1
893901
&& isReturnStatement(expression.body.statements[0])
902+
&& (expression.body.statements[0] as ReturnStatement).expressions !== undefined
894903
&& (expression.flags & FunctionExpressionFlags.Inline) !== 0;
895904
}

src/LuaLib.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ export class LuaLib {
6767
function load(feature: LuaLibFeature): void {
6868
if (!loadedFeatures.has(feature)) {
6969
loadedFeatures.add(feature);
70-
if (luaLibDependencies[feature]) {
71-
luaLibDependencies[feature].forEach(load);
70+
const dependencies = luaLibDependencies[feature];
71+
if (dependencies) {
72+
dependencies.forEach(load);
7273
}
7374
const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`);
7475
result += fs.readFileSync(featureFile).toString() + "\n";

src/LuaPrinter.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ export class LuaPrinter {
4343
private options: CompilerOptions;
4444
private currentIndent: string;
4545

46-
private sourceFile: string;
46+
private sourceFile = "";
4747

4848
public constructor(options: CompilerOptions) {
4949
this.options = options;
5050
this.currentIndent = "";
5151
}
5252

53-
public print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>, sourceFile?: string): [string, string] {
53+
public print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>, sourceFile = ""): [string, string] {
5454
// Add traceback lualib if sourcemap traceback option is enabled
5555
if (this.options.sourceMapTraceback) {
5656
if (luaLibFeatures === undefined) {
@@ -113,7 +113,7 @@ export class LuaPrinter {
113113
private printImplementation(
114114
block: tstl.Block,
115115
luaLibFeatures?: Set<LuaLibFeature>,
116-
sourceFile?: string): SourceNode {
116+
sourceFile = ""): SourceNode {
117117

118118
let header = "";
119119

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

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

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

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

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

621-
chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")");
622+
const parameterChunks = expression.params !== undefined
623+
? expression.params.map(e => this.printExpression(e))
624+
: [];
625+
626+
chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")");
622627

623628
return this.concatNodes(...chunks);
624629
}
625630

626631
private printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode {
627632
const prefix = this.printExpression(expression.prefixExpression);
628-
const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e)));
633+
634+
const parameterChunks = expression.params !== undefined
635+
? expression.params.map(e => this.printExpression(e))
636+
: [];
637+
629638
const name = this.printIdentifier(expression.name);
630639

631-
return this.concatNodes(prefix, ":", name, "(", ...parameterChunks, ")");
640+
return this.concatNodes(prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")");
632641
}
633642

634643
private printIdentifier(expression: tstl.Identifier): SourceNode {

0 commit comments

Comments
 (0)