Skip to content

Commit 720086f

Browse files
authored
Merge pull request #7 from jaredmcateer/upgrade-typescript
feat: upgrade typescript
2 parents 49bc190 + 789dc60 commit 720086f

File tree

26 files changed

+10456
-10221
lines changed

26 files changed

+10456
-10221
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"@types/inquirer": "^7.3.0",
2929
"@types/jest": "^26.0.8",
3030
"@types/node": "^14.0.27",
31-
"@types/prettier": "^2.0.2",
31+
"@types/prettier": "^2.6.1",
3232
"@typescript-eslint/eslint-plugin": "^3.7.1",
3333
"@typescript-eslint/parser": "^3.7.1",
3434
"codecov": "^3.7.2",
@@ -42,7 +42,7 @@
4242
"prettier": "^2.6.2",
4343
"semantic-release": "^17.2.3",
4444
"ts-jest": "^26.1.4",
45-
"typescript": "3.9.7",
45+
"typescript": "^4.6.4",
4646
"vue": "^2.6.11"
4747
},
4848
"scripts": {

src/convert.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export function convertAST(
5555

5656
log("output result code");
5757
const printer = tsModule.createPrinter();
58-
const result = printer.printFile(tsModule.updateSourceFileNode(sourceFile, resultStatements));
58+
const { factory } = tsModule;
59+
const result = printer.printFile(factory.updateSourceFile(sourceFile, resultStatements));
5960

6061
return result;
6162
}

src/file.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function readVueSFCOrTsFile(filePath: string, options: UncouthOptions): F
3030
if (isVueFile(fileFsPath)) {
3131
const scriptContent = parseVueFile(options.vueTemplateCompiler, fileContent).script;
3232
if (scriptContent) {
33-
log(`Readed Vue file: ${fileFsPath}`);
33+
log(`Read Vue file: ${fileFsPath}`);
3434
return {
3535
fsPath: fileFsPath,
3636
kind: FileKind.VUE,
@@ -40,9 +40,9 @@ export function readVueSFCOrTsFile(filePath: string, options: UncouthOptions): F
4040
fileContent,
4141
};
4242
}
43-
throw new Error("The Vue SFC don't have sciprt element.");
43+
throw new Error("The Vue SFC doesn't have script element.");
4444
} else {
45-
log(`Readed TS file: ${fileFsPath}`);
45+
log(`Read TS file: ${fileFsPath}`);
4646
return {
4747
fsPath: fileFsPath,
4848
kind: FileKind.TS,

src/helpers/TsHelper.ts

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
import ts from "typescript";
2+
import { UncouthOptions } from "../options";
3+
import { isString } from "../utils";
4+
5+
export class TsHelper {
6+
public module: typeof ts;
7+
private compatible: boolean;
8+
9+
constructor(options: UncouthOptions) {
10+
this.module = options.typescript;
11+
this.compatible = options.compatible;
12+
}
13+
14+
get factory(): ts.NodeFactory {
15+
return this.module.factory;
16+
}
17+
18+
namedImports(names: string[]): { named: string[]; external: string }[] {
19+
return [
20+
{
21+
named: names,
22+
external: this.compatible ? "@vue/composition-api" : "vue",
23+
},
24+
];
25+
}
26+
27+
createIdentifier(name: string): ts.Identifier {
28+
return this.factory.createIdentifier(name);
29+
}
30+
31+
createPropertyAccess(
32+
expr: ts.Expression | string,
33+
name: string | ts.MemberName
34+
): ts.PropertyAccessExpression {
35+
const eIdentifier = isString(expr) ? this.createIdentifier(expr) : expr;
36+
const nIdentifier = isString(name) ? this.createIdentifier(name) : name;
37+
return this.factory.createPropertyAccessExpression(eIdentifier, nIdentifier);
38+
}
39+
40+
createNonNullPropertyAccess(
41+
expression: ts.Expression | string,
42+
name: string | ts.MemberName
43+
): ts.NonNullExpression {
44+
return this.factory.createNonNullExpression(this.createPropertyAccess(expression, name));
45+
}
46+
47+
addTodoComment<T extends ts.Node>(node: T, comment: string, multiline: boolean): T {
48+
const kind = multiline
49+
? this.module.SyntaxKind.MultiLineCommentTrivia
50+
: this.module.SyntaxKind.SingleLineCommentTrivia;
51+
52+
return this.module.addSyntheticLeadingComment(node, kind, ` TODO: ${comment}`);
53+
}
54+
55+
createObjectPropertyAssignment(
56+
name: string | ts.Identifier,
57+
properties: ts.ObjectLiteralElementLike[]
58+
): ts.PropertyAssignment {
59+
name = isString(name) ? this.factory.createIdentifier(name) : name;
60+
return this.factory.createPropertyAssignment(
61+
name,
62+
this.factory.createObjectLiteralExpression(properties, true)
63+
);
64+
}
65+
66+
createExpressionStatement(expression: ts.Expression): ts.ExpressionStatement;
67+
/**
68+
* Create a call expression and wrap in an expression statement
69+
* @param expression
70+
* @param typeArguments
71+
* @param argumentsArray
72+
*/
73+
createExpressionStatement(
74+
expression: string | ts.Identifier,
75+
typeArguments?: ts.TypeNode[],
76+
argumentsArray?: ts.Expression[]
77+
): ts.ExpressionStatement;
78+
createExpressionStatement(
79+
expression: string | ts.Identifier | ts.Expression,
80+
typeArguments?: ts.TypeNode[],
81+
argumentsArray?: ts.Expression[]
82+
): ts.ExpressionStatement {
83+
if (isString(expression) || ts.isIdentifier(expression)) {
84+
expression = this.createCallExpression(expression, typeArguments, argumentsArray);
85+
}
86+
return this.factory.createExpressionStatement(expression);
87+
}
88+
89+
copySyntheticComments<T extends ts.Node>(node: T, copyNode: ts.Node): T {
90+
const fullText = copyNode.getSourceFile().getFullText();
91+
const leadingComments = this.getLeadingComments(fullText, copyNode.pos);
92+
const trailingComments = this.getTrailingComments(fullText, copyNode.end);
93+
94+
let result = node;
95+
for (const { pos, end, kind, hasTrailingNewLine } of leadingComments) {
96+
const text = this.getCommentText(fullText, { pos, end });
97+
result = this.module.addSyntheticLeadingComment(result, kind, text, hasTrailingNewLine);
98+
}
99+
100+
for (const { pos, end, kind, hasTrailingNewLine } of trailingComments) {
101+
const text = this.getCommentText(fullText, { pos, end });
102+
result = this.module.addSyntheticTrailingComment(result, kind, text, hasTrailingNewLine);
103+
}
104+
105+
return node;
106+
}
107+
108+
createThis(): ts.ThisExpression {
109+
return this.factory.createThis();
110+
}
111+
112+
createCallExpression(
113+
expr: string | ts.Identifier | ts.PropertyAccessExpression,
114+
typeArguments?: ts.TypeNode[],
115+
argumentsArray?: ts.Expression[]
116+
): ts.CallExpression {
117+
const expression = isString(expr) ? this.createIdentifier(expr) : expr;
118+
return this.factory.createCallExpression(expression, typeArguments, argumentsArray);
119+
}
120+
121+
createArrowFunctionFromNode(
122+
node: ts.MethodDeclaration | ts.AccessorDeclaration,
123+
bodyStatements?: ts.Statement[],
124+
multiline?: boolean
125+
): ts.ArrowFunction {
126+
const { modifiers, typeParameters, type, body, parameters } = node;
127+
const rocketToken = this.factory.createToken(this.module.SyntaxKind.EqualsGreaterThanToken);
128+
const fnBody = bodyStatements
129+
? this.factory.createBlock(bodyStatements, multiline)
130+
: body ?? this.factory.createBlock([], multiline);
131+
132+
return this.factory.createArrowFunction(
133+
modifiers,
134+
typeParameters,
135+
parameters,
136+
type,
137+
rocketToken,
138+
fnBody
139+
);
140+
}
141+
142+
createConstStatement(
143+
name: string | ts.BindingName,
144+
expression: ts.Expression
145+
): ts.VariableStatement {
146+
return this.factory.createVariableStatement(
147+
undefined,
148+
this.factory.createVariableDeclarationList(
149+
[this.factory.createVariableDeclaration(name, undefined, undefined, expression)],
150+
this.module.NodeFlags.Const
151+
)
152+
);
153+
}
154+
155+
removeComments<T extends ts.Node>(node: T): T | ts.StringLiteral {
156+
if (this.module.isStringLiteral(node)) {
157+
return this.factory.createStringLiteral(node.text);
158+
}
159+
160+
return node;
161+
}
162+
163+
isPrimitiveType(returnType: ts.Type): boolean {
164+
return (
165+
!!(returnType.flags & this.module.TypeFlags.NumberLike) ||
166+
!!(returnType.flags & this.module.TypeFlags.StringLike) ||
167+
!!(returnType.flags & this.module.TypeFlags.BooleanLike) ||
168+
!!(returnType.flags & this.module.TypeFlags.Null) ||
169+
!!(returnType.flags & this.module.TypeFlags.Undefined)
170+
);
171+
}
172+
173+
makeIife(fn: ts.ArrowFunction): ts.CallExpression {
174+
return this.factory.createCallExpression(
175+
this.factory.createParenthesizedExpression(fn),
176+
undefined,
177+
[]
178+
);
179+
}
180+
181+
createMethod(name: string, parameters: string[], body: ts.Statement[]): ts.MethodDeclaration {
182+
const params = parameters.map((param) =>
183+
this.factory.createParameterDeclaration(
184+
undefined,
185+
undefined,
186+
undefined,
187+
param,
188+
undefined,
189+
undefined,
190+
undefined
191+
)
192+
);
193+
return this.factory.createMethodDeclaration(
194+
undefined,
195+
undefined,
196+
undefined,
197+
name,
198+
undefined,
199+
undefined,
200+
params,
201+
undefined,
202+
this.factory.createBlock(body, true)
203+
);
204+
}
205+
206+
private getLeadingComments(text: string, pos: number): ts.CommentRange[] {
207+
return this.getCommentRange(text, pos, "Leading");
208+
}
209+
210+
private getTrailingComments(text: string, pos: number): ts.CommentRange[] {
211+
return this.getCommentRange(text, pos, "Trailing");
212+
}
213+
214+
private getCommentRange(
215+
text: string,
216+
pos: number,
217+
type: "Leading" | "Trailing"
218+
): ts.CommentRange[] {
219+
const method = `get${type}CommentRanges` as const;
220+
return this.module[method](text, pos) || [];
221+
}
222+
223+
private getCommentText(text: string, { pos, end }: { pos: number; end: number }) {
224+
return text
225+
.slice(pos, end)
226+
.replace(/\/\//g, "")
227+
.replace(/\/\*/g, "")
228+
.replace(/\*\//g, "")
229+
.replace(/ {2}\* ?/g, "* ")
230+
.replace(/ \*\//g, "*/")
231+
.replace(/ {2}$/g, "");
232+
}
233+
}

0 commit comments

Comments
 (0)