Skip to content

Commit fd975e1

Browse files
committed
Moved typescript plugin to "after" transformers to avoid dealing with type information. Fixes #6 #5
1 parent 1fc66bc commit fd975e1

File tree

137 files changed

+499
-494
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+499
-494
lines changed

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
* text=auto
1+
* text=auto eol=lf
22

33
*.css text eol=lf
44
*.js text eol=lf

src/cjsModuleHandler.ts

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as ts from "typescript";
2-
import {isImportDeclaration, StringLiteral} from "typescript";
2+
import {isExpressionStatement} from "typescript";
33
import {POSSIBLE_IMPORTS_TO_ADD} from "./index";
44

55

@@ -15,12 +15,11 @@ export function handleCjsModules(sourceFile: ts.SourceFile, context: ts.Transfor
1515
}
1616

1717
if (specifiersToAdd.length > 0) {
18-
const matchedImportIdx = statements
19-
.findIndex(s => isImportDeclaration(s)
20-
&& (s.moduleSpecifier as StringLiteral).text === 'inferno'
21-
);
18+
const matchedUseStrictStatement = statements.findIndex(
19+
s => isExpressionStatement(s) && (s as any).expression?.text === 'use strict'
20+
);
2221

23-
let infernoIdentifier = factory.createIdentifier(matchedImportIdx === -1 ? "inferno" : "inferno_1")
22+
let infernoIdentifier = factory.createIdentifier("$inferno")
2423

2524
for (const specifier of specifiersToAdd) {
2625
let varStatement = factory.createVariableStatement(undefined, [
@@ -35,33 +34,33 @@ export function handleCjsModules(sourceFile: ts.SourceFile, context: ts.Transfor
3534
)
3635
]);
3736

38-
if (matchedImportIdx === -1) {
37+
if (matchedUseStrictStatement === -1) {
3938
statements.unshift(varStatement)
4039
} else {
41-
statements.splice(matchedImportIdx + 1, 0, varStatement)
40+
statements.splice(matchedUseStrictStatement + 1, 0, varStatement)
4241
}
4342
}
4443

45-
if (matchedImportIdx === -1) {
46-
// Adding import statement does not get re-compiled in typescript core
47-
// So directly add require statement
48-
statements.unshift(
49-
factory.createVariableStatement(
44+
const reqStatement = factory.createVariableStatement(
45+
undefined,
46+
factory.createVariableDeclarationList([
47+
factory.createVariableDeclaration(
48+
"$inferno",
49+
undefined,
5050
undefined,
51-
factory.createVariableDeclarationList([
52-
factory.createVariableDeclaration(
53-
"inferno",
54-
undefined,
55-
undefined,
56-
factory.createCallExpression(
57-
factory.createIdentifier("require"),
58-
[],
59-
[factory.createStringLiteral("inferno")]
60-
)
61-
)
62-
]),
51+
factory.createCallExpression(
52+
factory.createIdentifier("require"),
53+
[],
54+
[factory.createStringLiteral("inferno")]
55+
)
6356
)
64-
);
57+
]),
58+
)
59+
60+
if (matchedUseStrictStatement === -1) {
61+
statements.unshift(reqStatement)
62+
} else {
63+
statements.splice(matchedUseStrictStatement + 1, 0, reqStatement)
6564
}
6665

6766
return factory.updateSourceFile(sourceFile, statements, false);

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default () => {
4848
return (context: TransformationContext): Transformer<SourceFile> => {
4949
const {factory} = context;
5050

51-
return (sourceFile: SourceFile) => {
51+
return ((sourceFile: SourceFile) => {
5252
if (sourceFile.isDeclarationFile) {
5353
return sourceFile
5454
}
@@ -72,7 +72,7 @@ export default () => {
7272
const newSourceFile = visitEachChild(sourceFile, visitor, context)
7373

7474
return updateSourceFile(newSourceFile, context)
75-
}
75+
})
7676

7777
function getImportSpecifier(name: 'createFragment' | 'createVNode' | 'createComponentVNode' | 'createTextVNode' | 'normalizeProps'): Expression {
7878
return context['infernoImportSpecifiers'].get(name).name;

src/utils/createAssignHelper.ts

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,14 @@
1-
import {EmitFlags, EmitHelper, Expression, ScriptTarget, setEmitFlags, TransformationContext} from "typescript";
2-
3-
4-
const assignHelper: EmitHelper = {
5-
name: "typescript:assign",
6-
scoped: false,
7-
priority: 1,
8-
text: `
9-
var __assign = (this && this.__assign) || Object.assign || function(t) {
10-
for (var s, i = 1, n = argumenlength; i < n; i++) {
11-
s = arguments[i];
12-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
13-
t[p] = s[p];
14-
}
15-
return t;
16-
};`
17-
};
1+
import { Expression, TransformationContext} from "typescript";
182

193
export default function createAssignHelper(
204
context: TransformationContext,
215
attributesSegments: Expression[]
226
) {
237
const {factory} = context;
248

25-
if (context.getCompilerOptions().target >= ScriptTarget.ES2015) {
26-
return factory.createCallExpression(
27-
factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "assign"),
28-
undefined,
29-
attributesSegments
30-
);
31-
}
32-
context.requestEmitHelper(assignHelper);
339
return factory.createCallExpression(
34-
getHelperName("__assign"),
35-
/*typeArguments*/ undefined,
10+
factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "assign"),
11+
undefined,
3612
attributesSegments
3713
);
38-
39-
function getHelperName(name: string) {
40-
return setEmitFlags(
41-
factory.createIdentifier(name),
42-
EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode
43-
);
44-
}
4514
}

tests/cases/typeImport_1.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {createVNode} from "inferno"; // If this line is uncommented, no problems
2+
import {InfernoNode} from "inferno";
3+
import {a} from "./test";
4+
5+
type VisualizerProps = {
6+
number: string;
7+
other?: InfernoNode;
8+
}
9+
10+
export function Visualizer({ number, other }: VisualizerProps) {
11+
return (
12+
<div className="visualizer test">
13+
{a}
14+
{number}
15+
{other}
16+
</div>
17+
);
18+
}

tests/cases/typeImport_2.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// import {createVNode} from "inferno"; // If this line is uncommented, no problems
2+
import {InfernoNode} from "inferno";
3+
import {a} from "./test";
4+
5+
type VisualizerProps = {
6+
number: string;
7+
other?: InfernoNode;
8+
}
9+
10+
export function Visualizer({ number, other }: VisualizerProps) {
11+
return (
12+
<div className="visualizer test">
13+
{a}
14+
{number}
15+
{other}
16+
</div>
17+
);
18+
}

tests/index.ts

Lines changed: 83 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,124 @@
11
import {
2-
createCompilerHost, createProgram,
3-
getDefaultCompilerOptions,
4-
JsxEmit,
5-
ModuleKind,
6-
ModuleResolutionKind,
7-
ScriptTarget
2+
createCompilerHost,
3+
createProgram,
4+
getDefaultCompilerOptions,
5+
JsxEmit,
6+
ModuleKind,
7+
ModuleResolutionKind,
8+
NewLineKind,
9+
ScriptTarget
810
} from 'typescript'
9-
import { sync as globSync } from 'glob'
11+
import {sync as globSync} from 'glob'
1012
import transform from '../src'
11-
import { resolve, basename } from 'path'
12-
import { readFileSync, writeFileSync } from 'fs'
13-
// @ts-ignore
14-
import { mkdirpSync } from 'fs-extra'
13+
import {basename, resolve} from 'path'
14+
import {readFileSync, writeFileSync} from 'fs'
15+
import {mkdirpSync} from 'fs-extra'
1516

1617
// Target is ES5 and module is UMD
1718
const config = {
18-
...getDefaultCompilerOptions(),
19-
experimentalDecorators: true,
20-
jsx: JsxEmit.Preserve,
21-
module: ModuleKind.CommonJS,
22-
moduleResolution: ModuleResolutionKind.NodeJs,
23-
noEmitOnError: false,
24-
noUnusedLocals: true,
25-
noUnusedParameters: true,
26-
stripInternal: true,
27-
target: ScriptTarget.ES5,
28-
compilerOptions: {
29-
importsNotUsedAsValues: ['remove'],
30-
}
19+
...getDefaultCompilerOptions(),
20+
experimentalDecorators: true,
21+
jsx: JsxEmit.Preserve,
22+
module: ModuleKind.CommonJS,
23+
moduleResolution: ModuleResolutionKind.NodeJs,
24+
noEmitOnError: false,
25+
noUnusedLocals: true,
26+
noUnusedParameters: true,
27+
stripInternal: true,
28+
target: ScriptTarget.ES5,
29+
newLine: NewLineKind.LineFeed
3130
}
3231

3332
// Target is ES2015 (same as ES6)
3433
const configES6 = {
35-
...getDefaultCompilerOptions(),
36-
experimentalDecorators: true,
37-
jsx: JsxEmit.Preserve,
38-
noEmitOnError: false,
39-
noUnusedLocals: true,
40-
noUnusedParameters: true,
41-
stripInternal: true,
42-
target: ScriptTarget.ES2015,
43-
compilerOptions: {
44-
importsNotUsedAsValues: ['remove'],
45-
}
34+
...getDefaultCompilerOptions(),
35+
experimentalDecorators: true,
36+
jsx: JsxEmit.Preserve,
37+
noEmitOnError: false,
38+
noUnusedLocals: true,
39+
noUnusedParameters: true,
40+
stripInternal: true,
41+
target: ScriptTarget.ES2015,
42+
newLine: NewLineKind.LineFeed
4643
}
4744

4845
function compile(path: string, callback) {
49-
const files = globSync(path)
50-
const compilerHost = createCompilerHost(config)
51-
const program = createProgram(files, config, compilerHost)
46+
const files = globSync(path)
47+
const compilerHost = createCompilerHost(config)
48+
const program = createProgram(files, config, compilerHost)
5249

53-
program.emit(undefined, compare(), undefined, undefined, {
54-
before: [transform()],
55-
})
50+
program.emit(undefined, compare(), undefined, undefined, {
51+
after: [transform()],
52+
})
5653

57-
callback(files, 'ES5')
54+
callback(files, 'ES5')
5855
}
5956

6057
function compileES6(path: string, callback) {
61-
const files = globSync(path)
62-
const compilerHost = createCompilerHost(configES6)
63-
const program = createProgram(files, configES6, compilerHost)
58+
const files = globSync(path)
59+
const compilerHost = createCompilerHost(configES6)
60+
const program = createProgram(files, configES6, compilerHost)
6461

65-
program.emit(undefined, compare('ES6'), undefined, undefined, {
66-
before: [transform()],
67-
})
62+
program.emit(undefined, compare('ES6'), undefined, undefined, {
63+
after: [transform()],
64+
})
6865

69-
callback(files, 'ES6')
66+
callback(files, 'ES6')
7067
}
7168

7269
let failedTestsEs5 = []
7370
let failedTestsEs6 = []
7471
mkdirpSync(resolve(__dirname, 'temp/'))
7572
mkdirpSync(resolve(__dirname, 'tempES6/'))
7673

77-
function compare (target?: string) {
78-
return (filePath: string, output: string) => {
79-
const fileBasename = basename(filePath)
80-
const referenceFilePath = resolve(`${__dirname}`, `references${target ?? ''}/` + fileBasename)
74+
function compare(target?: string) {
75+
return (filePath: string, output: string) => {
76+
const fileBasename = basename(filePath)
77+
const referenceFilePath = resolve(`${__dirname}`, `references${target ?? ''}/` + fileBasename)
8178

82-
const tempFilePath = resolve(__dirname, `temp${target ?? ''}/` + fileBasename)
79+
const tempFilePath = resolve(__dirname, `temp${target ?? ''}/` + fileBasename)
8380

84-
try {
85-
const fileData = readFileSync(referenceFilePath, 'utf8')
86-
if (fileData !== output) {
87-
writeFileSync(tempFilePath, output, 'utf8');
88-
(target === 'ES6' ? failedTestsEs6 : failedTestsEs5).push(fileBasename)
89-
}
90-
} catch (error) {
91-
writeFileSync(tempFilePath, output, 'utf8');
92-
(target === 'ES6' ? failedTestsEs6 : failedTestsEs5).push(fileBasename)
81+
try {
82+
const fileData = readFileSync(referenceFilePath, 'utf8')
83+
if (fileData !== output) {
84+
writeFileSync(tempFilePath, output, 'utf8');
85+
(target === 'ES6' ? failedTestsEs6 : failedTestsEs5).push(fileBasename)
86+
}
87+
} catch (error) {
88+
writeFileSync(tempFilePath, output, 'utf8');
89+
(target === 'ES6' ? failedTestsEs6 : failedTestsEs5).push(fileBasename)
90+
}
9391
}
94-
}
9592
}
9693

9794
function printResult(files: string[], target: string) {
98-
console.info(target ? `\n\n${target ?? ''}` : '')
99-
if ((target === 'ES6' ? failedTestsEs6 : failedTestsEs5).length) {
100-
console.log(
101-
`${files.length - (target === 'ES6' ? failedTestsEs6 : failedTestsEs5).length}/${files.length} cases passed`
102-
)
103-
console.log('Following tests failed:');
104-
(target === 'ES6' ? failedTestsEs6 : failedTestsEs5).map(test => console.log(test))
105-
console.log(`Please look in the test/temp${target === 'ES6' ? target : ''} folder and verify output`)
106-
console.log('When verified use the command: npm run overwrite-references')
107-
// throw 'Failed tests...'
108-
} else {
109-
console.log(`All cases (${files.length}) successfully passed`)
110-
}
95+
console.info(target ? `\n\n${target ?? ''}` : '')
96+
if ((target === 'ES6' ? failedTestsEs6 : failedTestsEs5).length) {
97+
console.log(
98+
`${files.length - (target === 'ES6' ? failedTestsEs6 : failedTestsEs5).length}/${files.length} cases passed`
99+
)
100+
console.log('Following tests failed:');
101+
(target === 'ES6' ? failedTestsEs6 : failedTestsEs5).map(test => console.log(test))
102+
console.log(`Please look in the test/temp${target === 'ES6' ? target : ''} folder and verify output`)
103+
console.log('When verified use the command: npm run overwrite-references')
104+
// throw 'Failed tests...'
105+
} else {
106+
console.log(`All cases (${files.length}) successfully passed`)
107+
}
111108
}
112109

113110
function printFinalResult() {
114-
console.info('\n\nResults:')
115-
if (failedTestsEs5.length || failedTestsEs6.length) {
116-
console.log(`${failedTestsEs5.length} ES5 cases failed`)
117-
console.log(`${failedTestsEs6.length} ES6 cases failed`)
118-
} else {
119-
console.log(`All ES5 and ES6 cases successfully passed`)
120-
}
111+
console.info('\n\nResults:')
112+
if (failedTestsEs5.length || failedTestsEs6.length) {
113+
console.log(`${failedTestsEs5.length} ES5 cases failed`)
114+
console.log(`${failedTestsEs6.length} ES6 cases failed`)
115+
} else {
116+
console.log(`All ES5 and ES6 cases successfully passed`)
117+
}
121118
}
122119

123120
console.time('compile time')
124-
compile('tests/cases/*.tsx', printResult)
125-
compileES6('tests/cases/*.tsx', printResult)
121+
compile('tests/cases/**.tsx', printResult)
122+
compileES6('tests/cases/**.tsx', printResult)
126123
printFinalResult()
127124
console.timeEnd('compile time')

0 commit comments

Comments
 (0)