Skip to content

Commit

Permalink
Reimplemented for-in/of loop
Browse files Browse the repository at this point in the history
Implemented custom JSForOfLoop and JSForInLoop for loops
  • Loading branch information
Andrii Rodionov committed Nov 20, 2024
1 parent 0f8c089 commit e2ef997
Show file tree
Hide file tree
Showing 14 changed files with 868 additions and 35 deletions.
27 changes: 18 additions & 9 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2081,21 +2081,30 @@ export class JavaScriptParserVisitor {
}

visitForInStatement(node: ts.ForInStatement) {
return this.visitUnknown(node);
return new JS.JSForInLoop(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.suffix(this.findChildNode(node, ts.SyntaxKind.ForKeyword)!),
this.rightPadded(this.visit(node.initializer), this.prefix(node.initializer)),
this.rightPadded(this.visit(node.expression), this.suffix(node.expression)),
this.rightPadded(
this.convert(node.statement),
this.semicolonPrefix(node.statement),
node.statement.getLastToken()?.kind == ts.SyntaxKind.SemicolonToken ? Markers.build([new Semicolon(randomId())]) : Markers.EMPTY
)
);
}

visitForOfStatement(node: ts.ForOfStatement) {
return new J.ForEachLoop(
return new JS.JSForOfLoop(
randomId(),
this.prefix(node),
Markers.EMPTY,
new J.ForEachLoop.Control(
randomId(),
this.prefix(this.findChildNode(node, ts.SyntaxKind.OpenParenToken)!),
Markers.EMPTY,
this.rightPadded(this.visit(node.initializer), Space.EMPTY),
this.rightPadded(this.visit(node.expression), this.suffix(node.expression))
),
this.suffix(this.findChildNode(node, ts.SyntaxKind.ForKeyword)!),
node.awaitModifier ? this.rightPadded(true, this.suffix(node.awaitModifier)) : this.rightPadded(false, Space.EMPTY),
this.rightPadded(this.visit(node.initializer), this.prefix(node.initializer)),
this.rightPadded(this.visit(node.expression), this.suffix(node.expression)),
this.rightPadded(
this.convert(node.statement),
this.semicolonPrefix(node.statement),
Expand Down
50 changes: 49 additions & 1 deletion openrewrite/src/javascript/remote/receiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
import {Checksum, Cursor, FileAttributes, ListUtils, Tree} from '../../core';
import {DetailsReceiver, Receiver, ReceiverContext, ReceiverFactory, ValueType} from '@openrewrite/rewrite-remote';
import {JavaScriptVisitor} from '..';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsImportSpecifier, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSMethodInvocation, NamespaceDeclaration, FunctionDeclaration} from '../tree';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsImportSpecifier, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSMethodInvocation, JSForOfLoop, JSForInLoop, NamespaceDeclaration, FunctionDeclaration} from '../tree';
import {Expression, J, JContainer, JLeftPadded, JRightPadded, NameTree, Space, Statement, TypeTree, TypedTree} from "../../java";
import * as Java from "../../java/tree";

Expand Down Expand Up @@ -364,6 +364,29 @@ class Visitor extends JavaScriptVisitor<ReceiverContext> {
return jSMethodInvocation;
}

public visitJSForOfLoop(jSForOfLoop: JSForOfLoop, ctx: ReceiverContext): J {
jSForOfLoop = jSForOfLoop.withId(ctx.receiveValue(jSForOfLoop.id, ValueType.UUID)!);
jSForOfLoop = jSForOfLoop.withPrefix(ctx.receiveNode(jSForOfLoop.prefix, receiveSpace)!);
jSForOfLoop = jSForOfLoop.withMarkers(ctx.receiveNode(jSForOfLoop.markers, ctx.receiveMarkers)!);
jSForOfLoop = jSForOfLoop.withFor_suffix(ctx.receiveNode(jSForOfLoop.for_suffix, receiveSpace));
jSForOfLoop = jSForOfLoop.padding.withAwait(ctx.receiveNode(jSForOfLoop.padding.await, rightPaddedValueReceiver(ValueType.Primitive))!);
jSForOfLoop = jSForOfLoop.padding.withInitializer(ctx.receiveNode(jSForOfLoop.padding.initializer, receiveRightPaddedTree)!);
jSForOfLoop = jSForOfLoop.padding.withIterable(ctx.receiveNode(jSForOfLoop.padding.iterable, receiveRightPaddedTree)!);
jSForOfLoop = jSForOfLoop.padding.withBody(ctx.receiveNode(jSForOfLoop.padding.body, receiveRightPaddedTree)!);
return jSForOfLoop;
}

public visitJSForInLoop(jSForInLoop: JSForInLoop, ctx: ReceiverContext): J {
jSForInLoop = jSForInLoop.withId(ctx.receiveValue(jSForInLoop.id, ValueType.UUID)!);
jSForInLoop = jSForInLoop.withPrefix(ctx.receiveNode(jSForInLoop.prefix, receiveSpace)!);
jSForInLoop = jSForInLoop.withMarkers(ctx.receiveNode(jSForInLoop.markers, ctx.receiveMarkers)!);
jSForInLoop = jSForInLoop.withFor_suffix(ctx.receiveNode(jSForInLoop.for_suffix, receiveSpace));
jSForInLoop = jSForInLoop.padding.withInitializer(ctx.receiveNode(jSForInLoop.padding.initializer, receiveRightPaddedTree)!);
jSForInLoop = jSForInLoop.padding.withIterable(ctx.receiveNode(jSForInLoop.padding.iterable, receiveRightPaddedTree)!);
jSForInLoop = jSForInLoop.padding.withBody(ctx.receiveNode(jSForInLoop.padding.body, receiveRightPaddedTree)!);
return jSForInLoop;
}

public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, ctx: ReceiverContext): J {
namespaceDeclaration = namespaceDeclaration.withId(ctx.receiveValue(namespaceDeclaration.id, ValueType.UUID)!);
namespaceDeclaration = namespaceDeclaration.withPrefix(ctx.receiveNode(namespaceDeclaration.prefix, receiveSpace)!);
Expand Down Expand Up @@ -1428,6 +1451,31 @@ class Factory implements ReceiverFactory {
);
}

if (type === "org.openrewrite.javascript.tree.JS$JSForOfLoop") {
return new JSForOfLoop(
ctx.receiveValue(null, ValueType.UUID)!,
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveNode(null, receiveSpace),
ctx.receiveNode<JRightPadded<boolean>>(null, rightPaddedValueReceiver(ValueType.Primitive))!,
ctx.receiveNode<JRightPadded<Expression>>(null, receiveRightPaddedTree)!,
ctx.receiveNode<JRightPadded<Expression>>(null, receiveRightPaddedTree)!,
ctx.receiveNode<JRightPadded<Statement>>(null, receiveRightPaddedTree)!
);
}

if (type === "org.openrewrite.javascript.tree.JS$JSForInLoop") {
return new JSForInLoop(
ctx.receiveValue(null, ValueType.UUID)!,
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveNode(null, receiveSpace),
ctx.receiveNode<JRightPadded<Expression>>(null, receiveRightPaddedTree)!,
ctx.receiveNode<JRightPadded<Expression>>(null, receiveRightPaddedTree)!,
ctx.receiveNode<JRightPadded<Statement>>(null, receiveRightPaddedTree)!
);
}

if (type === "org.openrewrite.javascript.tree.JS$NamespaceDeclaration") {
return new NamespaceDeclaration(
ctx.receiveValue(null, ValueType.UUID)!,
Expand Down
25 changes: 24 additions & 1 deletion openrewrite/src/javascript/remote/sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
import {Cursor, ListUtils, Tree} from '../../core';
import {Sender, SenderContext, ValueType} from '@openrewrite/rewrite-remote';
import {JavaScriptVisitor} from '..';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsImportSpecifier, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSMethodInvocation, NamespaceDeclaration, FunctionDeclaration} from '../tree';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, DefaultType, Delete, Export, ExpressionStatement, FunctionType, JsImport, JsImportSpecifier, JsBinary, ObjectBindingDeclarations, PropertyAssignment, ScopedVariableDeclarations, StatementExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeOperator, Unary, Union, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSMethodInvocation, JSForOfLoop, JSForInLoop, NamespaceDeclaration, FunctionDeclaration} from '../tree';
import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../../java";
import * as Java from "../../java/tree";

Expand Down Expand Up @@ -359,6 +359,29 @@ class Visitor extends JavaScriptVisitor<SenderContext> {
return jSMethodInvocation;
}

public visitJSForOfLoop(jSForOfLoop: JSForOfLoop, ctx: SenderContext): J {
ctx.sendValue(jSForOfLoop, v => v.id, ValueType.UUID);
ctx.sendNode(jSForOfLoop, v => v.prefix, Visitor.sendSpace);
ctx.sendNode(jSForOfLoop, v => v.markers, ctx.sendMarkers);
ctx.sendNode(jSForOfLoop, v => v.for_suffix, Visitor.sendSpace);
ctx.sendNode(jSForOfLoop, v => v.padding.await, Visitor.sendRightPadded(ValueType.Primitive));
ctx.sendNode(jSForOfLoop, v => v.padding.initializer, Visitor.sendRightPadded(ValueType.Tree));
ctx.sendNode(jSForOfLoop, v => v.padding.iterable, Visitor.sendRightPadded(ValueType.Tree));
ctx.sendNode(jSForOfLoop, v => v.padding.body, Visitor.sendRightPadded(ValueType.Tree));
return jSForOfLoop;
}

public visitJSForInLoop(jSForInLoop: JSForInLoop, ctx: SenderContext): J {
ctx.sendValue(jSForInLoop, v => v.id, ValueType.UUID);
ctx.sendNode(jSForInLoop, v => v.prefix, Visitor.sendSpace);
ctx.sendNode(jSForInLoop, v => v.markers, ctx.sendMarkers);
ctx.sendNode(jSForInLoop, v => v.for_suffix, Visitor.sendSpace);
ctx.sendNode(jSForInLoop, v => v.padding.initializer, Visitor.sendRightPadded(ValueType.Tree));
ctx.sendNode(jSForInLoop, v => v.padding.iterable, Visitor.sendRightPadded(ValueType.Tree));
ctx.sendNode(jSForInLoop, v => v.padding.body, Visitor.sendRightPadded(ValueType.Tree));
return jSForInLoop;
}

public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, ctx: SenderContext): J {
ctx.sendValue(namespaceDeclaration, v => v.id, ValueType.UUID);
ctx.sendNode(namespaceDeclaration, v => v.prefix, Visitor.sendSpace);
Expand Down
15 changes: 13 additions & 2 deletions openrewrite/src/javascript/tree/support_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,11 @@ export namespace JsSpace {
NAMESPACE_DECLARATION_KEYWORD_PREFIX,
JSMETHOD_DECLARATION_PREFIX,
FUNCTION_DECLARATION_PREFIX,
JSMETHOD_INVOCATION_PREFIX
JSMETHOD_INVOCATION_PREFIX,
JSFOR_OF_LOOP_PREFIX,
JSFOR_OF_LOOP_FOR_SUFFIX,
JSFOR_IN_LOOP_FOR_SUFFIX,
JSFOR_IN_LOOP_PREFIX,
}
}
export namespace JsLeftPadded {
Expand Down Expand Up @@ -260,7 +264,14 @@ export namespace JsRightPadded {
UNION_TYPES,
JSVARIABLE_DECLARATIONS_VARIABLES,
NAMESPACE_DECLARATION_NAME,
JSMETHOD_INVOCATION_SELECT
JSMETHOD_INVOCATION_SELECT,
JSFOR_OF_LOOP_AWAIT,
JSFOR_OF_LOOP_INITIALIZER,
JSFOR_OF_LOOP_ITERABLE,
JSFOR_OF_LOOP_BODY,
JSFOR_IN_LOOP_INITIALIZER,
JSFOR_IN_LOOP_ITERABLE,
JSFOR_IN_LOOP_BODY,
}
}
export namespace JsContainer {
Expand Down
Loading

0 comments on commit e2ef997

Please sign in to comment.