Skip to content
This repository was archived by the owner on May 12, 2025. It is now read-only.

Commit e96b539

Browse files
arodionovAndrii Rodionov
andauthored
Implemented MappedType mapping (#167)
Creates JS.MappedType classes hierarchy --------- Co-authored-by: Andrii Rodionov <andriih@moderne.io>
1 parent 80f9ca6 commit e96b539

File tree

17 files changed

+1306
-10
lines changed

17 files changed

+1306
-10
lines changed

openrewrite/src/javascript/parser.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,67 @@ export class JavaScriptParserVisitor {
14401440
}
14411441

14421442
visitMappedType(node: ts.MappedTypeNode) {
1443-
return this.visitUnknown(node);
1443+
function hasPrefixToken(readonlyToken?: ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken): boolean {
1444+
return !!(readonlyToken && (readonlyToken.kind == ts.SyntaxKind.PlusToken || readonlyToken.kind == ts.SyntaxKind.MinusToken));
1445+
}
1446+
1447+
function hasSuffixToken(questionToken?: ts.QuestionToken | ts.PlusToken | ts.MinusToken): boolean {
1448+
return !!(questionToken && (questionToken.kind == ts.SyntaxKind.PlusToken || questionToken.kind == ts.SyntaxKind.MinusToken));
1449+
}
1450+
1451+
return new JS.MappedType(
1452+
randomId(),
1453+
this.prefix(node),
1454+
Markers.EMPTY,
1455+
hasPrefixToken(node.readonlyToken) ? this.leftPadded(this.prefix(node.readonlyToken!),
1456+
new J.Literal(
1457+
randomId(),
1458+
this.prefix(node.readonlyToken!),
1459+
Markers.EMPTY,
1460+
null,
1461+
node.readonlyToken!.getText(),
1462+
null,
1463+
this.mapPrimitiveType(node.readonlyToken!)
1464+
)) : null,
1465+
node.readonlyToken ? this.leftPadded(this.prefix(this.findChildNode(node, ts.SyntaxKind.ReadonlyKeyword)!), true) : this.leftPadded(Space.EMPTY, false),
1466+
new JS.MappedType.KeysRemapping(
1467+
randomId(),
1468+
this.prefix(this.findChildNode(node, ts.SyntaxKind.OpenBracketToken)!),
1469+
Markers.EMPTY,
1470+
this.rightPadded(
1471+
new JS.MappedType.MappedTypeParameter(
1472+
randomId(),
1473+
this.prefix(node.typeParameter),
1474+
Markers.EMPTY,
1475+
this.visit(node.typeParameter.name),
1476+
this.leftPadded(this.suffix(node.typeParameter.name), this.visit(node.typeParameter.constraint!))
1477+
),
1478+
this.suffix(node.typeParameter)),
1479+
node.nameType ? this.rightPadded(this.visit(node.nameType), this.suffix(node.nameType)) : null,
1480+
),
1481+
hasSuffixToken(node.questionToken) ? this.leftPadded(this.prefix(node.questionToken!),
1482+
new J.Literal(
1483+
randomId(),
1484+
this.prefix(node.questionToken!),
1485+
Markers.EMPTY,
1486+
null,
1487+
node.questionToken!.getText(),
1488+
null,
1489+
this.mapPrimitiveType(node.questionToken!)
1490+
)
1491+
): null,
1492+
node.questionToken ? this.leftPadded(this.prefix(this.findChildNode(node, ts.SyntaxKind.QuestionToken)!), true) : this.leftPadded(Space.EMPTY, false),
1493+
new JContainer(
1494+
this.prefix(this.findChildNode(node, ts.SyntaxKind.ColonToken)!),
1495+
[this.rightPadded(this.visit(node.type!), this.suffix(node.type!)),
1496+
this.findChildNode(node, ts.SyntaxKind.SemicolonToken) ?
1497+
this.rightPadded(this.newJEmpty(Space.EMPTY, Markers.build([new Semicolon(randomId())])), this.prefix(node.getLastToken()!))
1498+
: this.rightPadded(this.newJEmpty(), this.prefix(node.getLastToken()!))
1499+
],
1500+
Markers.EMPTY
1501+
),
1502+
this.mapType(node)
1503+
);
14441504
}
14451505

14461506
visitLiteralType(node: ts.LiteralTypeNode) {

openrewrite/src/javascript/remote/receiver.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
22
import {Checksum, Cursor, FileAttributes, ListUtils, Tree} from '../../core';
33
import {DetailsReceiver, Receiver, ReceiverContext, ReceiverFactory, ValueType} from '@openrewrite/rewrite-remote';
44
import {JavaScriptVisitor} from '..';
5-
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement, ExportDeclaration, ExportAssignment, NamedExports, ExportSpecifier, IndexedAccessType, JsAssignmentOperation} from '../tree';
5+
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, MappedType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement, ExportDeclaration, ExportAssignment, NamedExports, ExportSpecifier, IndexedAccessType, JsAssignmentOperation} from '../tree';
66
import {Expression, J, JContainer, JLeftPadded, JRightPadded, NameTree, Space, Statement, TypeTree, TypedTree} from "../../java";
77
import * as Java from "../../java/tree";
88

@@ -209,6 +209,38 @@ class Visitor extends JavaScriptVisitor<ReceiverContext> {
209209
return literalType;
210210
}
211211

212+
public visitMappedType(mappedType: MappedType, ctx: ReceiverContext): J {
213+
mappedType = mappedType.withId(ctx.receiveValue(mappedType.id, ValueType.UUID)!);
214+
mappedType = mappedType.withPrefix(ctx.receiveNode(mappedType.prefix, receiveSpace)!);
215+
mappedType = mappedType.withMarkers(ctx.receiveNode(mappedType.markers, ctx.receiveMarkers)!);
216+
mappedType = mappedType.padding.withPrefixToken(ctx.receiveNode(mappedType.padding.prefixToken, receiveLeftPaddedTree));
217+
mappedType = mappedType.padding.withHasReadonly(ctx.receiveNode(mappedType.padding.hasReadonly, leftPaddedValueReceiver(ValueType.Primitive))!);
218+
mappedType = mappedType.withKeysRemapping(ctx.receiveNode(mappedType.keysRemapping, ctx.receiveTree)!);
219+
mappedType = mappedType.padding.withSuffixToken(ctx.receiveNode(mappedType.padding.suffixToken, receiveLeftPaddedTree));
220+
mappedType = mappedType.padding.withHasQuestionToken(ctx.receiveNode(mappedType.padding.hasQuestionToken, leftPaddedValueReceiver(ValueType.Primitive))!);
221+
mappedType = mappedType.padding.withValueType(ctx.receiveNode(mappedType.padding.valueType, receiveContainer)!);
222+
mappedType = mappedType.withType(ctx.receiveValue(mappedType.type, ValueType.Object));
223+
return mappedType;
224+
}
225+
226+
public visitMappedTypeKeysRemapping(keysRemapping: MappedType.KeysRemapping, ctx: ReceiverContext): J {
227+
keysRemapping = keysRemapping.withId(ctx.receiveValue(keysRemapping.id, ValueType.UUID)!);
228+
keysRemapping = keysRemapping.withPrefix(ctx.receiveNode(keysRemapping.prefix, receiveSpace)!);
229+
keysRemapping = keysRemapping.withMarkers(ctx.receiveNode(keysRemapping.markers, ctx.receiveMarkers)!);
230+
keysRemapping = keysRemapping.padding.withTypeParameter(ctx.receiveNode(keysRemapping.padding.typeParameter, receiveRightPaddedTree)!);
231+
keysRemapping = keysRemapping.padding.withNameType(ctx.receiveNode(keysRemapping.padding.nameType, receiveRightPaddedTree));
232+
return keysRemapping;
233+
}
234+
235+
public visitMappedTypeMappedTypeParameter(mappedTypeParameter: MappedType.MappedTypeParameter, ctx: ReceiverContext): J {
236+
mappedTypeParameter = mappedTypeParameter.withId(ctx.receiveValue(mappedTypeParameter.id, ValueType.UUID)!);
237+
mappedTypeParameter = mappedTypeParameter.withPrefix(ctx.receiveNode(mappedTypeParameter.prefix, receiveSpace)!);
238+
mappedTypeParameter = mappedTypeParameter.withMarkers(ctx.receiveNode(mappedTypeParameter.markers, ctx.receiveMarkers)!);
239+
mappedTypeParameter = mappedTypeParameter.withName(ctx.receiveNode(mappedTypeParameter.name, ctx.receiveTree)!);
240+
mappedTypeParameter = mappedTypeParameter.padding.withIterateType(ctx.receiveNode(mappedTypeParameter.padding.iterateType, receiveLeftPaddedTree)!);
241+
return mappedTypeParameter;
242+
}
243+
212244
public visitObjectBindingDeclarations(objectBindingDeclarations: ObjectBindingDeclarations, ctx: ReceiverContext): J {
213245
objectBindingDeclarations = objectBindingDeclarations.withId(ctx.receiveValue(objectBindingDeclarations.id, ValueType.UUID)!);
214246
objectBindingDeclarations = objectBindingDeclarations.withPrefix(ctx.receiveNode(objectBindingDeclarations.prefix, receiveSpace)!);
@@ -1472,6 +1504,41 @@ class Factory implements ReceiverFactory {
14721504
);
14731505
}
14741506

1507+
if (type === "org.openrewrite.javascript.tree.JS$MappedType") {
1508+
return new MappedType(
1509+
ctx.receiveValue(null, ValueType.UUID)!,
1510+
ctx.receiveNode(null, receiveSpace)!,
1511+
ctx.receiveNode(null, ctx.receiveMarkers)!,
1512+
ctx.receiveNode<JLeftPadded<Java.Literal>>(null, receiveLeftPaddedTree),
1513+
ctx.receiveNode<JLeftPadded<boolean>>(null, leftPaddedValueReceiver(ValueType.Primitive))!,
1514+
ctx.receiveNode<MappedType.KeysRemapping>(null, ctx.receiveTree)!,
1515+
ctx.receiveNode<JLeftPadded<Java.Literal>>(null, receiveLeftPaddedTree),
1516+
ctx.receiveNode<JLeftPadded<boolean>>(null, leftPaddedValueReceiver(ValueType.Primitive))!,
1517+
ctx.receiveNode<JContainer<TypeTree>>(null, receiveContainer)!,
1518+
ctx.receiveValue(null, ValueType.Object)
1519+
);
1520+
}
1521+
1522+
if (type === "org.openrewrite.javascript.tree.JS$MappedType$KeysRemapping") {
1523+
return new MappedType.KeysRemapping(
1524+
ctx.receiveValue(null, ValueType.UUID)!,
1525+
ctx.receiveNode(null, receiveSpace)!,
1526+
ctx.receiveNode(null, ctx.receiveMarkers)!,
1527+
ctx.receiveNode<JRightPadded<MappedType.MappedTypeParameter>>(null, receiveRightPaddedTree)!,
1528+
ctx.receiveNode<JRightPadded<Expression>>(null, receiveRightPaddedTree)
1529+
);
1530+
}
1531+
1532+
if (type === "org.openrewrite.javascript.tree.JS$MappedType$MappedTypeParameter") {
1533+
return new MappedType.MappedTypeParameter(
1534+
ctx.receiveValue(null, ValueType.UUID)!,
1535+
ctx.receiveNode(null, receiveSpace)!,
1536+
ctx.receiveNode(null, ctx.receiveMarkers)!,
1537+
ctx.receiveNode<Expression>(null, ctx.receiveTree)!,
1538+
ctx.receiveNode<JLeftPadded<TypeTree>>(null, receiveLeftPaddedTree)!
1539+
);
1540+
}
1541+
14751542
if (type === "org.openrewrite.javascript.tree.JS$ObjectBindingDeclarations") {
14761543
return new ObjectBindingDeclarations(
14771544
ctx.receiveValue(null, ValueType.UUID)!,

openrewrite/src/javascript/remote/sender.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
22
import {Cursor, ListUtils, Tree} from '../../core';
33
import {Sender, SenderContext, ValueType} from '@openrewrite/rewrite-remote';
44
import {JavaScriptVisitor} from '..';
5-
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement, ExportDeclaration, ExportAssignment, NamedExports, ExportSpecifier, IndexedAccessType, JsAssignmentOperation} from '../tree';
5+
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, MappedType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement, ExportDeclaration, ExportAssignment, NamedExports, ExportSpecifier, IndexedAccessType, JsAssignmentOperation} from '../tree';
66
import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../../java";
77
import * as Java from "../../java/tree";
88

@@ -204,6 +204,38 @@ class Visitor extends JavaScriptVisitor<SenderContext> {
204204
return literalType;
205205
}
206206

207+
public visitMappedType(mappedType: MappedType, ctx: SenderContext): J {
208+
ctx.sendValue(mappedType, v => v.id, ValueType.UUID);
209+
ctx.sendNode(mappedType, v => v.prefix, Visitor.sendSpace);
210+
ctx.sendNode(mappedType, v => v.markers, ctx.sendMarkers);
211+
ctx.sendNode(mappedType, v => v.padding.prefixToken, Visitor.sendLeftPadded(ValueType.Tree));
212+
ctx.sendNode(mappedType, v => v.padding.hasReadonly, Visitor.sendLeftPadded(ValueType.Primitive));
213+
ctx.sendNode(mappedType, v => v.keysRemapping, ctx.sendTree);
214+
ctx.sendNode(mappedType, v => v.padding.suffixToken, Visitor.sendLeftPadded(ValueType.Tree));
215+
ctx.sendNode(mappedType, v => v.padding.hasQuestionToken, Visitor.sendLeftPadded(ValueType.Primitive));
216+
ctx.sendNode(mappedType, v => v.padding.valueType, Visitor.sendContainer(ValueType.Tree));
217+
ctx.sendTypedValue(mappedType, v => v.type, ValueType.Object);
218+
return mappedType;
219+
}
220+
221+
public visitMappedTypeKeysRemapping(keysRemapping: MappedType.KeysRemapping, ctx: SenderContext): J {
222+
ctx.sendValue(keysRemapping, v => v.id, ValueType.UUID);
223+
ctx.sendNode(keysRemapping, v => v.prefix, Visitor.sendSpace);
224+
ctx.sendNode(keysRemapping, v => v.markers, ctx.sendMarkers);
225+
ctx.sendNode(keysRemapping, v => v.padding.typeParameter, Visitor.sendRightPadded(ValueType.Tree));
226+
ctx.sendNode(keysRemapping, v => v.padding.nameType, Visitor.sendRightPadded(ValueType.Tree));
227+
return keysRemapping;
228+
}
229+
230+
public visitMappedTypeMappedTypeParameter(mappedTypeParameter: MappedType.MappedTypeParameter, ctx: SenderContext): J {
231+
ctx.sendValue(mappedTypeParameter, v => v.id, ValueType.UUID);
232+
ctx.sendNode(mappedTypeParameter, v => v.prefix, Visitor.sendSpace);
233+
ctx.sendNode(mappedTypeParameter, v => v.markers, ctx.sendMarkers);
234+
ctx.sendNode(mappedTypeParameter, v => v.name, ctx.sendTree);
235+
ctx.sendNode(mappedTypeParameter, v => v.padding.iterateType, Visitor.sendLeftPadded(ValueType.Tree));
236+
return mappedTypeParameter;
237+
}
238+
207239
public visitObjectBindingDeclarations(objectBindingDeclarations: ObjectBindingDeclarations, ctx: SenderContext): J {
208240
ctx.sendValue(objectBindingDeclarations, v => v.id, ValueType.UUID);
209241
ctx.sendNode(objectBindingDeclarations, v => v.prefix, Visitor.sendSpace);

openrewrite/src/javascript/tree/support_types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ export namespace JsSpace {
256256
INDEXED_ACCESS_TYPE_INDEX_TYPE_SUFFIX,
257257
INDEXED_ACCESS_TYPE_INDEX_TYPE_ELEMENT_SUFFIX,
258258
JS_ASSIGNMENT_OPERATION_PREFIX,
259+
MAPPED_TYPE_PREFIX,
260+
MAPPED_TYPE_KEYS_REMAPPING_PREFIX,
261+
MAPPED_TYPE_MAPPED_TYPE_PARAMETER_PREFIX,
259262
}
260263
}
261264
export namespace JsLeftPadded {
@@ -293,6 +296,11 @@ export namespace JsLeftPadded {
293296
FUNCTION_DECLARATION_ASTERISK_TOKEN,
294297
FUNCTION_DECLARATION_NAME,
295298
JS_ASSIGNMENT_OPERATION_OPERATOR,
299+
MAPPED_TYPE_PREFIX_TOKEN,
300+
MAPPED_TYPE_SUFFIX_TOKEN,
301+
MAPPED_TYPE_MAPPED_TYPE_PARAMETER_ITERATE_TYPE,
302+
MAPPED_TYPE_HAS_READONLY,
303+
MAPPED_TYPE_HAS_QUESTION_TOKEN,
296304
}
297305
}
298306
export namespace JsRightPadded {
@@ -319,6 +327,8 @@ export namespace JsRightPadded {
319327
IMPORT_TYPE_HAS_TYPEOF,
320328
INDEXED_ACCESS_TYPE_INDEX_TYPE,
321329
INDEXED_ACCESS_TYPE_INDEX_TYPE_ELEMENT,
330+
MAPPED_TYPE_KEYS_REMAPPING_TYPE_PARAMETER,
331+
MAPPED_TYPE_KEYS_REMAPPING_NAME_TYPE,
322332
}
323333
}
324334
export namespace JsContainer {
@@ -339,5 +349,6 @@ export namespace JsContainer {
339349
CONDITIONAL_TYPE_CONDITION,
340350
IMPORT_TYPE_TYPE_ARGUMENTS,
341351
NAMED_EXPORTS_ELEMENTS,
352+
MAPPED_TYPE_VALUE_TYPE,
342353
}
343354
}

0 commit comments

Comments
 (0)