X Tutup
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
30 changes: 23 additions & 7 deletions src/Decorator.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
export class Decorator {

public static isValid(decoratorKindString: string): boolean {
return this.getDecoratorKind(decoratorKindString) !== undefined;
}

public static getDecoratorKind(decoratorKindString: string): DecoratorKind {
switch (decoratorKindString.toLowerCase()) {
case "extension": return DecoratorKind.Extension;
case "metaextension": return DecoratorKind.MetaExtension;
case "customconstructor": return DecoratorKind.CustomConstructor;
case "compilemembersonly": return DecoratorKind.CompileMembersOnly;
case "pureabstract": return DecoratorKind.PureAbstract;
case "phantom": return DecoratorKind.Phantom;
case "tuplereturn": return DecoratorKind.TupleReturn;
case "noclassor": return DecoratorKind.NoClassOr;
}

return undefined;
}

public kind: DecoratorKind;
public args: string[];

constructor(raw: string) {
let nameEnd = raw.indexOf(" ");
if (nameEnd === -1) {
nameEnd = raw.length;
}
this.kind = DecoratorKind[raw.substring(1, nameEnd)];
this.args = raw.split(" ").slice(1);
constructor(name: string, args: string[]) {
this.kind = Decorator.getDecoratorKind(name);
this.args = args;
}
}

Expand Down
24 changes: 21 additions & 3 deletions src/TSHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,32 @@ export class TSHelper {
const comments = type.symbol.getDocumentationComment(checker);
const decorators =
comments.filter(comment => comment.kind === "text")
.map(comment => comment.text.trim().split("\n"))
.map(comment => comment.text.split("\n"))
.reduce((a, b) => a.concat(b), [])
.map(line => line.trim())
.filter(comment => comment[0] === "!");

const decMap = new Map<DecoratorKind, Decorator>();

decorators.forEach(decStr => {
const dec = new Decorator(decStr);
decMap.set(dec.kind, dec);
const [decoratorName, ...decoratorArguments] = decStr.split(" ");
if (Decorator.isValid(decoratorName.substr(1))) {
const dec = new Decorator(decoratorName.substr(1), decoratorArguments);
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}.`);
}
});

type.symbol.getJsDocTags().forEach(tag => {
if (Decorator.isValid(tag.name)) {
const dec = new Decorator(tag.name, tag.text ? tag.text.split(" ") : []);
decMap.set(dec.kind, dec);
}
});

return decMap;
}
return new Map<DecoratorKind, Decorator>();
Expand Down
2 changes: 1 addition & 1 deletion src/lualib/StringReplace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare namespace string {
/** !TupleReturn */
/** @tupleReturn */
function gsub(source: string, searchValue: string, replaceValue: string): [string, number];
}

Expand Down
56 changes: 39 additions & 17 deletions test/runner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TestRunner, TestSet } from "alsatian";
import { TapBark } from "tap-bark";
import { TestRunner, TestSet, TestOutcome } from "alsatian";

import * as fs from "fs";
import * as path from "path";
Expand All @@ -21,21 +20,44 @@ fs.copyFileSync(

// setup the output
testRunner.outputStream
// this will use alsatian's default output if you remove this
// you'll get TAP or you can add your favourite TAP reporter in it's place
.pipe(TapBark.create().getPipeable())
// pipe to the console
.pipe(process.stdout);
// pipe to the console
.pipe(process.stdout);

let success = 0;
let ignored = 0;
let run = 0;
testRunner.onTestComplete(test => {
run++;

if (test.outcome === TestOutcome.Pass) {
success++;
} else if (test.outcome === TestOutcome.Skip) {
ignored++;
}
});

// run the test set
testRunner.run(testSet)
// this will be called after all tests have been run
.then(result => {
// Remove lualib bundle again
fs.unlinkSync("lualib_bundle.lua");
})
// this will be called if there was a problem
.catch(error => {
// Remove lualib bundle again
fs.unlinkSync("lualib_bundle.lua");
});
// this will be called after all tests have been run
.then(result => {
// Remove lualib bundle again
fs.unlinkSync("lualib_bundle.lua");

const nonIgnoredTests = run - ignored;
const failedTests = nonIgnoredTests - success;
console.log(`Ignored ${ignored}/${run} tests.`);
console.log(`Failed ${failedTests}/${nonIgnoredTests} tests.`);
console.log(`Passed ${success}/${nonIgnoredTests} tests.`);

if (failedTests > 0) {
process.exit(1);
}
})
// this will be called if there was a problem
.catch(error => {
// Remove lualib bundle again
fs.unlinkSync("lualib_bundle.lua");

console.error(error);
process.exit(1);
});
48 changes: 48 additions & 0 deletions test/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,54 @@ export function transpileAndExecute(tsStr: string): any {
return executeLua(transpileString(tsStr));
}

export function parseTypeScript(typescript: string, target: LuaTarget = LuaTarget.Lua53)
: [ts.SourceFile, ts.TypeChecker] {
const compilerHost = {
directoryExists: () => true,
fileExists: (fileName): boolean => true,
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: () => "",
getDefaultLibFileName: () => "lib.es6.d.ts",
getDirectories: () => [],
getNewLine: () => "\n",

getSourceFile: (filename, languageVersion) => {
if (filename === "file.ts") {
return ts.createSourceFile(filename, typescript, ts.ScriptTarget.Latest, false);
}
if (filename === "lib.es6.d.ts") {
const libPath = path.join(path.dirname(require.resolve("typescript")), "lib.es6.d.ts");
const libSource = fs.readFileSync(libPath).toString();
return ts.createSourceFile(filename, libSource, ts.ScriptTarget.Latest, false);
}
return undefined;
},

readFile: () => "",

useCaseSensitiveFileNames: () => false,
// Don't write output
writeFile: (name, text, writeByteOrderMark) => null,
};

const program = ts.createProgram(["file.ts"], { luaTarget: target }, compilerHost);
return [program.getSourceFile("file.ts"), program.getTypeChecker()];
}

export function findFirstChild(node: ts.Node, predicate: (node: ts.Node) => boolean): ts.Node | undefined {
for (const child of node.getChildren()) {
if (predicate(child)) {
return child;
}

const childChild = findFirstChild(child, predicate);
if (childChild !== undefined) {
return childChild;
}
}
return undefined;
}

const jsonlib = fs.readFileSync("test/src/json.lua") + "\n";

export const minimalTestLib = jsonlib;
2 changes: 1 addition & 1 deletion test/translation/ts/assignments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ declare function getIndex(): number;
declare let xTup: [number, number];
declare let yTup: [number, number];
declare function getTup(): [number, number];
/** !TupleReturn */
/** @tupleReturn */
declare function getTupRet(): [number, number];
x = y;
x = obj.prop;
Expand Down
2 changes: 1 addition & 1 deletion test/translation/ts/classExtension1.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** !Extension */
/** @extension */
class MyClass {
public myFunction() {}
}
4 changes: 2 additions & 2 deletions test/translation/ts/classExtension2.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** !Extension */
/** @extension */
class TestClass {
}

/** !Extension */
/** @extension */
class MyClass extends TestClass {
public myFunction() {}
}
4 changes: 2 additions & 2 deletions test/translation/ts/classExtension3.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/** !Extension RenamedTestClass */
/** @extension RenamedTestClass */
class TestClass {
public myFunction() {}
}

/** !Extension RenamedMyClass */
/** @extension RenamedMyClass */
class MyClass extends TestClass {
public myFunction() {}
}
2 changes: 1 addition & 1 deletion test/translation/ts/classExtension4.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** !Extension */
/** @extension */
class MyClass {
public test: string = "test";
private testP: string = "testP";
Expand Down
2 changes: 1 addition & 1 deletion test/translation/ts/classPureAbstract.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/** !PureAbstract */
/** @pureAbstract */
declare class ClassA {}
class ClassB extends ClassA {}
4 changes: 2 additions & 2 deletions test/translation/ts/enumMembersOnly.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/** !CompileMembersOnly */
/** @compileMembersOnly */
enum TestEnum {
val1 = 0,
val2 = 2,
val3,
val4 = "bye"
val4 = "bye",
}

const a = TestEnum.val1;
2 changes: 1 addition & 1 deletion test/translation/ts/namespacePhantom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** !Phantom */
/** @phantom */
namespace myNamespace {
function nsMember() {}
}
8 changes: 4 additions & 4 deletions test/translation/ts/tupleReturn.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** !TupleReturn */
/** @tupleReturn */
function tupleReturn(): [number, string] {
return [0, "foobar"];
}
Expand All @@ -16,19 +16,19 @@ e = tupleReturn();
f = noTupleReturn();
foo(tupleReturn());
foo(noTupleReturn());
/** !TupleReturn */
/** @tupleReturn */
function tupleReturnFromVar(): [number, string] {
const r: [number, string] = [1, "baz"];
return r;
}
/** !TupleReturn */
/** @tupleReturn */
function tupleReturnForward(): [number, string] {
return tupleReturn();
}
function tupleNoForward(): [number, string] {
return tupleReturn();
}
/** !TupleReturn */
/** @tupleReturn */
function tupleReturnUnpack(): [number, string] {
return tupleNoForward();
}
16 changes: 8 additions & 8 deletions test/unit/assignments.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class AssignmentTests {

@Test("TupleReturn assignment")
public tupleReturnFunction(): void {
const code = `/** !TupleReturn */\n`
const code = `/** @tupleReturn */\n`
+ `declare function abc() { return [1,2,3]; }\n`
+ `let [a,b] = abc();`;

Expand All @@ -86,7 +86,7 @@ export class AssignmentTests {

@Test("TupleReturn Single assignment")
public tupleReturnSingleAssignment(): void {
const code = `/** !TupleReturn */\n`
const code = `/** @tupleReturn */\n`
+ `declare function abc(): [number, string]; }\n`
+ `let a = abc();`
+ `a = abc();`;
Expand All @@ -98,7 +98,7 @@ export class AssignmentTests {
@Test("TupleReturn interface assignment")
public tupleReturnInterface(): void {
const code = `interface def {\n`
+ `/** !TupleReturn */\n`
+ `/** @tupleReturn */\n`
+ `abc();\n`
+ `} declare const jkl : def;\n`
+ `let [a,b] = jkl.abc();`;
Expand All @@ -110,7 +110,7 @@ export class AssignmentTests {
@Test("TupleReturn namespace assignment")
public tupleReturnNameSpace(): void {
const code = `declare namespace def {\n`
+ `/** !TupleReturn */\n`
+ `/** @tupleReturn */\n`
+ `function abc() {}\n`
+ `}\n`
+ `let [a,b] = def.abc();`;
Expand All @@ -122,7 +122,7 @@ export class AssignmentTests {
@Test("TupleReturn method assignment")
public tupleReturnMethod(): void {
const code = `declare class def {\n`
+ `/** !TupleReturn */\n`
+ `/** @tupleReturn */\n`
+ `abc() { return [1,2,3]; }\n`
+ `} const jkl = new def();\n`
+ `let [a,b] = jkl.abc();`;
Expand All @@ -133,7 +133,7 @@ export class AssignmentTests {

@Test("TupleReturn functional")
public tupleReturnFunctional(): void {
const code = `/** !TupleReturn */
const code = `/** @tupleReturn */
function abc(): [number, string] { return [3, "a"]; }
const [a, b] = abc();
return b + a;`;
Expand All @@ -147,7 +147,7 @@ export class AssignmentTests {

@Test("TupleReturn single")
public tupleReturnSingle(): void {
const code = `/** !TupleReturn */
const code = `/** @tupleReturn */
function abc(): [number, string] { return [3, "a"]; }
const res = abc();
return res.length`;
Expand All @@ -161,7 +161,7 @@ export class AssignmentTests {

@Test("TupleReturn in expression")
public tupleReturnInExpression(): void {
const code = `/** !TupleReturn */
const code = `/** @tupleReturn */
function abc(): [number, string] { return [3, "a"]; }
return abc()[1] + abc()[0];`;

Expand Down
4 changes: 2 additions & 2 deletions test/unit/decoratorCustomConstructor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class DecoratorCustomConstructor {
public customCreate(): void {
// Transpile
const lua = util.transpileString(
`/** !CustomConstructor Point2DCreate */
`/** @customConstructor Point2DCreate */
class Point2D {
x: number;
y: number;
Expand All @@ -29,7 +29,7 @@ export class DecoratorCustomConstructor {
public incorrectUsage(): void {
Expect(() => {
util.transpileString(
`/** !CustomConstructor */
`/** @customConstructor */
class Point2D {
x: number;
y: number;
Expand Down
Loading
X Tutup