-
Notifications
You must be signed in to change notification settings - Fork 0
/
compile.ts
112 lines (102 loc) · 4.28 KB
/
compile.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import * as ts from 'typescript';
function compile(fileNames: string[], options: ts.CompilerOptions): void {
options.experimentalDecorators = true;
let program = ts.createProgram(fileNames, options);
let emitResult = program.emit(
undefined,
undefined,
undefined,
undefined,
{
before: [
transformer(program)
]
}
);
let exitCode = emitResult.emitSkipped ? 1 : 0;
console.log(`Process exiting with code '${exitCode}'.`);
process.exit(exitCode);
}
compile(process.argv.slice(2), {
noEmitOnError: true,
noImplicitAny: true,
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJS
});
/**
* taken and modified from https://github.com/kimamula/ts-transformer-keys/blob/master/transformer.ts
*
* this code creates nested functions in the way that typescript expects to be able to run your actual
* transformer function. this function executes for all of your nodes when bootstrapped from `customerTransformers` compiler plugin option
*
* @param program
*/
export default function transformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile> {
return (context: ts.TransformationContext) => (file: ts.SourceFile) => visitNodeAndChildren(file, program, context);
}
// I'm pretty sure these function declarations are just to appease the type checker...
function visitNodeAndChildren(node: ts.SourceFile, program: ts.Program, context: ts.TransformationContext): ts.SourceFile;
function visitNodeAndChildren(node: ts.Node, program: ts.Program, context: ts.TransformationContext): ts.Node;
// visits every node given a root node
function visitNodeAndChildren(node: ts.Node, program: ts.Program, context: ts.TransformationContext): ts.Node {
return ts.visitEachChild(visitNode(node, program), childNode => visitNodeAndChildren(childNode, program, context), context);
}
/**
* this function is applied to all visited nodes.
* as part of the transform functionality, any nodes that we `return` will REPLACE
* the current node being processed.
*
* if there are nodes we don't care about changing, return the original node.
* for those that we do care about changing, we have to create a new node and return it.
*
* @param node
* @param program
*/
function visitNode(node: ts.Node, program: ts.Program): ts.Node {
// switch because we plan on adding new conditions here in the future.
switch (node.kind) {
/*
* we have a function block e.g. for function
*
* doSomething() { console.log('something'); }
*
* this would identify the function contents
*
* { console.log('something'); }
*/
case ts.SyntaxKind.Block:
/*
* check to see that our node is one we want to process here.
* requirements
* function block has decorators attached to its definition
* AND at least one of those decorators is the remote server function decorator
*/
let shouldProcess = false;
if(node.parent.decorators) {
for (const decoratorNode of node.parent.decorators) {
if(decoratorNode.getFullText().match(/remote/ && /server/)) {
shouldProcess = true;
}
}
}
if (shouldProcess) {
// we know it's a block, type it as such
let block = (node as ts.Block);
/*
* when we `update` a block, we're really dealing with an immutable thing.
* typescript intakes the block, creates a `new` block, attaches the old block to it
* for historical reference, and then uses your input to define the new functionality in the block.
*
* in our case, we want to make it empty, so the `array` of `Statements` we use to create the block
* is an empty array.
*/
return ts.updateBlock(block, []);
} else {
// we're not interested in mutating this node. return original node.
return node;
}
default:
// we're not interested in mutating this node. return original node.
return node;
}
}