diff --git a/openrewrite/src/javascript/parser.ts b/openrewrite/src/javascript/parser.ts index e2201616..6e235106 100644 --- a/openrewrite/src/javascript/parser.ts +++ b/openrewrite/src/javascript/parser.ts @@ -2085,9 +2085,13 @@ export class JavaScriptParserVisitor { 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)), + new JS.JSForInOfLoopControl( + randomId(), + this.prefix(this.findChildNode(node, ts.SyntaxKind.OpenParenToken)!), + Markers.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), @@ -2101,10 +2105,14 @@ export class JavaScriptParserVisitor { randomId(), this.prefix(node), Markers.EMPTY, - 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)), + node.awaitModifier ? this.leftPadded(this.prefix(node.awaitModifier), true) : this.leftPadded(Space.EMPTY, false), + new JS.JSForInOfLoopControl( + randomId(), + this.prefix(this.findChildNode(node, ts.SyntaxKind.OpenParenToken)!), + Markers.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), diff --git a/openrewrite/src/javascript/remote/receiver.ts b/openrewrite/src/javascript/remote/receiver.ts index ee987be3..32c209bb 100644 --- a/openrewrite/src/javascript/remote/receiver.ts +++ b/openrewrite/src/javascript/remote/receiver.ts @@ -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, JSForOfLoop, JSForInLoop, 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, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration} from '../tree'; import {Expression, J, JContainer, JLeftPadded, JRightPadded, NameTree, Space, Statement, TypeTree, TypedTree} from "../../java"; import * as Java from "../../java/tree"; @@ -368,10 +368,8 @@ class Visitor extends JavaScriptVisitor { 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.withAwait(ctx.receiveNode(jSForOfLoop.padding.await, leftPaddedValueReceiver(ValueType.Primitive))!); + jSForOfLoop = jSForOfLoop.withControl(ctx.receiveNode(jSForOfLoop.control, ctx.receiveTree)!); jSForOfLoop = jSForOfLoop.padding.withBody(ctx.receiveNode(jSForOfLoop.padding.body, receiveRightPaddedTree)!); return jSForOfLoop; } @@ -380,13 +378,20 @@ class Visitor extends JavaScriptVisitor { 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.withControl(ctx.receiveNode(jSForInLoop.control, ctx.receiveTree)!); jSForInLoop = jSForInLoop.padding.withBody(ctx.receiveNode(jSForInLoop.padding.body, receiveRightPaddedTree)!); return jSForInLoop; } + public visitJSForInOfLoopControl(jSForInOfLoopControl: JSForInOfLoopControl, ctx: ReceiverContext): J { + jSForInOfLoopControl = jSForInOfLoopControl.withId(ctx.receiveValue(jSForInOfLoopControl.id, ValueType.UUID)!); + jSForInOfLoopControl = jSForInOfLoopControl.withPrefix(ctx.receiveNode(jSForInOfLoopControl.prefix, receiveSpace)!); + jSForInOfLoopControl = jSForInOfLoopControl.withMarkers(ctx.receiveNode(jSForInOfLoopControl.markers, ctx.receiveMarkers)!); + jSForInOfLoopControl = jSForInOfLoopControl.padding.withVariable(ctx.receiveNode(jSForInOfLoopControl.padding.variable, receiveRightPaddedTree)!); + jSForInOfLoopControl = jSForInOfLoopControl.padding.withIterable(ctx.receiveNode(jSForInOfLoopControl.padding.iterable, receiveRightPaddedTree)!); + return jSForInOfLoopControl; + } + public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, ctx: ReceiverContext): J { namespaceDeclaration = namespaceDeclaration.withId(ctx.receiveValue(namespaceDeclaration.id, ValueType.UUID)!); namespaceDeclaration = namespaceDeclaration.withPrefix(ctx.receiveNode(namespaceDeclaration.prefix, receiveSpace)!); @@ -1456,10 +1461,8 @@ class Factory implements ReceiverFactory { ctx.receiveValue(null, ValueType.UUID)!, ctx.receiveNode(null, receiveSpace)!, ctx.receiveNode(null, ctx.receiveMarkers)!, - ctx.receiveNode(null, receiveSpace), - ctx.receiveNode>(null, rightPaddedValueReceiver(ValueType.Primitive))!, - ctx.receiveNode>(null, receiveRightPaddedTree)!, - ctx.receiveNode>(null, receiveRightPaddedTree)!, + ctx.receiveNode>(null, leftPaddedValueReceiver(ValueType.Primitive))!, + ctx.receiveNode(null, ctx.receiveTree)!, ctx.receiveNode>(null, receiveRightPaddedTree)! ); } @@ -1469,13 +1472,21 @@ class Factory implements ReceiverFactory { ctx.receiveValue(null, ValueType.UUID)!, ctx.receiveNode(null, receiveSpace)!, ctx.receiveNode(null, ctx.receiveMarkers)!, - ctx.receiveNode(null, receiveSpace), - ctx.receiveNode>(null, receiveRightPaddedTree)!, - ctx.receiveNode>(null, receiveRightPaddedTree)!, + ctx.receiveNode(null, ctx.receiveTree)!, ctx.receiveNode>(null, receiveRightPaddedTree)! ); } + if (type === "org.openrewrite.javascript.tree.JS$JSForInOfLoopControl") { + return new JSForInOfLoopControl( + ctx.receiveValue(null, ValueType.UUID)!, + ctx.receiveNode(null, receiveSpace)!, + ctx.receiveNode(null, ctx.receiveMarkers)!, + ctx.receiveNode>(null, receiveRightPaddedTree)!, + ctx.receiveNode>(null, receiveRightPaddedTree)! + ); + } + if (type === "org.openrewrite.javascript.tree.JS$NamespaceDeclaration") { return new NamespaceDeclaration( ctx.receiveValue(null, ValueType.UUID)!, diff --git a/openrewrite/src/javascript/remote/sender.ts b/openrewrite/src/javascript/remote/sender.ts index dcee288f..2b9b1205 100644 --- a/openrewrite/src/javascript/remote/sender.ts +++ b/openrewrite/src/javascript/remote/sender.ts @@ -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, JSForOfLoop, JSForInLoop, 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, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration} from '../tree'; import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../../java"; import * as Java from "../../java/tree"; @@ -363,10 +363,8 @@ class Visitor extends JavaScriptVisitor { 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.await, Visitor.sendLeftPadded(ValueType.Primitive)); + ctx.sendNode(jSForOfLoop, v => v.control, ctx.sendTree); ctx.sendNode(jSForOfLoop, v => v.padding.body, Visitor.sendRightPadded(ValueType.Tree)); return jSForOfLoop; } @@ -375,13 +373,20 @@ class Visitor extends JavaScriptVisitor { 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.control, ctx.sendTree); ctx.sendNode(jSForInLoop, v => v.padding.body, Visitor.sendRightPadded(ValueType.Tree)); return jSForInLoop; } + public visitJSForInOfLoopControl(jSForInOfLoopControl: JSForInOfLoopControl, ctx: SenderContext): J { + ctx.sendValue(jSForInOfLoopControl, v => v.id, ValueType.UUID); + ctx.sendNode(jSForInOfLoopControl, v => v.prefix, Visitor.sendSpace); + ctx.sendNode(jSForInOfLoopControl, v => v.markers, ctx.sendMarkers); + ctx.sendNode(jSForInOfLoopControl, v => v.padding.variable, Visitor.sendRightPadded(ValueType.Tree)); + ctx.sendNode(jSForInOfLoopControl, v => v.padding.iterable, Visitor.sendRightPadded(ValueType.Tree)); + return jSForInOfLoopControl; + } + public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, ctx: SenderContext): J { ctx.sendValue(namespaceDeclaration, v => v.id, ValueType.UUID); ctx.sendNode(namespaceDeclaration, v => v.prefix, Visitor.sendSpace); diff --git a/openrewrite/src/javascript/tree/support_types.ts b/openrewrite/src/javascript/tree/support_types.ts index 7b60a436..8e94ec3d 100644 --- a/openrewrite/src/javascript/tree/support_types.ts +++ b/openrewrite/src/javascript/tree/support_types.ts @@ -221,14 +221,13 @@ export namespace JsSpace { JSVARIABLE_DECLARATIONS_VARARGS, JSVARIABLE_DECLARATIONS_JSNAMED_VARIABLE_PREFIX, NAMESPACE_DECLARATION_PREFIX, - NAMESPACE_DECLARATION_KEYWORD_PREFIX, JSMETHOD_DECLARATION_PREFIX, FUNCTION_DECLARATION_PREFIX, JSMETHOD_INVOCATION_PREFIX, JSFOR_OF_LOOP_PREFIX, - JSFOR_OF_LOOP_FOR_SUFFIX, - JSFOR_IN_LOOP_FOR_SUFFIX, JSFOR_IN_LOOP_PREFIX, + JSFOR_IN_OF_LOOP_CONTROL_PREFIX, + TYPE_QUERY_PREFIX, } } export namespace JsLeftPadded { @@ -249,7 +248,8 @@ export namespace JsLeftPadded { JSMETHOD_DECLARATION_DEFAULT_VALUE, NAMESPACE_DECLARATION_KEYWORD_TYPE, SCOPED_VARIABLE_DECLARATIONS_SCOPE, - JS_IMPORT_SPECIFIER_IMPORT_TYPE + JS_IMPORT_SPECIFIER_IMPORT_TYPE, + JSFOR_OF_LOOP_AWAIT, } } export namespace JsRightPadded { @@ -265,13 +265,11 @@ export namespace JsRightPadded { JSVARIABLE_DECLARATIONS_VARIABLES, NAMESPACE_DECLARATION_NAME, JSMETHOD_INVOCATION_SELECT, - JSFOR_OF_LOOP_AWAIT, - JSFOR_OF_LOOP_INITIALIZER, - JSFOR_OF_LOOP_ITERABLE, + JSFOR_IN_OF_LOOP_CONTROL_VARIABLE, + JSFOR_IN_OF_LOOP_CONTROL_ITERABLE, JSFOR_OF_LOOP_BODY, - JSFOR_IN_LOOP_INITIALIZER, - JSFOR_IN_LOOP_ITERABLE, JSFOR_IN_LOOP_BODY, + FUNCTION_TYPE_CONSTRUCTOR_TYPE, } } export namespace JsContainer { diff --git a/openrewrite/src/javascript/tree/tree.ts b/openrewrite/src/javascript/tree/tree.ts index 1123a52d..ec4799c9 100644 --- a/openrewrite/src/javascript/tree/tree.ts +++ b/openrewrite/src/javascript/tree/tree.ts @@ -3098,15 +3098,13 @@ export class JSMethodInvocation extends JSMixin(Object) implements Statement, Ty @LstType("org.openrewrite.javascript.tree.JS$JSForOfLoop") export class JSForOfLoop extends JSMixin(Object) implements Loop { - public constructor(id: UUID, prefix: Space, markers: Markers, for_suffix: Space | null, await: JRightPadded, initializer: JRightPadded, iterable: JRightPadded, body: JRightPadded) { + public constructor(id: UUID, prefix: Space, markers: Markers, await: JLeftPadded, control: JSForInOfLoopControl, body: JRightPadded) { super(); this._id = id; this._prefix = prefix; this._markers = markers; - this._for_suffix = for_suffix; this._await = await; - this._initializer = initializer; - this._iterable = iterable; + this._control = control; this._body = body; } @@ -3117,7 +3115,7 @@ export class JSForOfLoop extends JSMixin(Object) implements Loop { } public withId(id: UUID): JSForOfLoop { - return id === this._id ? this : new JSForOfLoop(id, this._prefix, this._markers, this._for_suffix, this._await, this._initializer, this._iterable, this._body); + return id === this._id ? this : new JSForOfLoop(id, this._prefix, this._markers, this._await, this._control, this._body); } private readonly _prefix: Space; @@ -3127,7 +3125,7 @@ export class JSForOfLoop extends JSMixin(Object) implements Loop { } public withPrefix(prefix: Space): JSForOfLoop { - return prefix === this._prefix ? this : new JSForOfLoop(this._id, prefix, this._markers, this._for_suffix, this._await, this._initializer, this._iterable, this._body); + return prefix === this._prefix ? this : new JSForOfLoop(this._id, prefix, this._markers, this._await, this._control, this._body); } private readonly _markers: Markers; @@ -3137,20 +3135,10 @@ export class JSForOfLoop extends JSMixin(Object) implements Loop { } public withMarkers(markers: Markers): JSForOfLoop { - return markers === this._markers ? this : new JSForOfLoop(this._id, this._prefix, markers, this._for_suffix, this._await, this._initializer, this._iterable, this._body); - } - - private readonly _for_suffix: Space | null; - - public get for_suffix(): Space | null { - return this._for_suffix; - } - - public withFor_suffix(for_suffix: Space | null): JSForOfLoop { - return for_suffix === this._for_suffix ? this : new JSForOfLoop(this._id, this._prefix, this._markers, for_suffix, this._await, this._initializer, this._iterable, this._body); + return markers === this._markers ? this : new JSForOfLoop(this._id, this._prefix, markers, this._await, this._control, this._body); } - private readonly _await: JRightPadded; + private readonly _await: JLeftPadded; public get await(): boolean { return this._await.element; @@ -3160,24 +3148,14 @@ export class JSForOfLoop extends JSMixin(Object) implements Loop { return this.padding.withAwait(this._await.withElement(await)); } - private readonly _initializer: JRightPadded; - - public get initializer(): Expression { - return this._initializer.element; - } - - public withInitializer(initializer: Expression): JSForOfLoop { - return this.padding.withInitializer(this._initializer.withElement(initializer)); - } - - private readonly _iterable: JRightPadded; + private readonly _control: JSForInOfLoopControl; - public get iterable(): Expression { - return this._iterable.element; + public get control(): JSForInOfLoopControl { + return this._control; } - public withIterable(iterable: Expression): JSForOfLoop { - return this.padding.withIterable(this._iterable.withElement(iterable)); + public withControl(control: JSForInOfLoopControl): JSForOfLoop { + return control === this._control ? this : new JSForOfLoop(this._id, this._prefix, this._markers, this._await, control, this._body); } private readonly _body: JRightPadded; @@ -3197,29 +3175,17 @@ export class JSForOfLoop extends JSMixin(Object) implements Loop { get padding() { const t = this; return new class { - public get await(): JRightPadded { + public get await(): JLeftPadded { return t._await; } - public withAwait(await: JRightPadded): JSForOfLoop { - return t._await === await ? t : new JSForOfLoop(t._id, t._prefix, t._markers, t._for_suffix, await, t._initializer, t._iterable, t._body); - } - public get initializer(): JRightPadded { - return t._initializer; - } - public withInitializer(initializer: JRightPadded): JSForOfLoop { - return t._initializer === initializer ? t : new JSForOfLoop(t._id, t._prefix, t._markers, t._for_suffix, t._await, initializer, t._iterable, t._body); - } - public get iterable(): JRightPadded { - return t._iterable; - } - public withIterable(iterable: JRightPadded): JSForOfLoop { - return t._iterable === iterable ? t : new JSForOfLoop(t._id, t._prefix, t._markers, t._for_suffix, t._await, t._initializer, iterable, t._body); + public withAwait(await: JLeftPadded): JSForOfLoop { + return t._await === await ? t : new JSForOfLoop(t._id, t._prefix, t._markers, await, t._control, t._body); } public get body(): JRightPadded { return t._body; } public withBody(body: JRightPadded): JSForOfLoop { - return t._body === body ? t : new JSForOfLoop(t._id, t._prefix, t._markers, t._for_suffix, t._await, t._initializer, t._iterable, body); + return t._body === body ? t : new JSForOfLoop(t._id, t._prefix, t._markers, t._await, t._control, body); } } } @@ -3228,14 +3194,12 @@ export class JSForOfLoop extends JSMixin(Object) implements Loop { @LstType("org.openrewrite.javascript.tree.JS$JSForInLoop") export class JSForInLoop extends JSMixin(Object) implements Loop { - public constructor(id: UUID, prefix: Space, markers: Markers, for_suffix: Space | null, initializer: JRightPadded, iterable: JRightPadded, body: JRightPadded) { + public constructor(id: UUID, prefix: Space, markers: Markers, control: JSForInOfLoopControl, body: JRightPadded) { super(); this._id = id; this._prefix = prefix; this._markers = markers; - this._for_suffix = for_suffix; - this._initializer = initializer; - this._iterable = iterable; + this._control = control; this._body = body; } @@ -3246,7 +3210,7 @@ export class JSForInLoop extends JSMixin(Object) implements Loop { } public withId(id: UUID): JSForInLoop { - return id === this._id ? this : new JSForInLoop(id, this._prefix, this._markers, this._for_suffix, this._initializer, this._iterable, this._body); + return id === this._id ? this : new JSForInLoop(id, this._prefix, this._markers, this._control, this._body); } private readonly _prefix: Space; @@ -3256,7 +3220,7 @@ export class JSForInLoop extends JSMixin(Object) implements Loop { } public withPrefix(prefix: Space): JSForInLoop { - return prefix === this._prefix ? this : new JSForInLoop(this._id, prefix, this._markers, this._for_suffix, this._initializer, this._iterable, this._body); + return prefix === this._prefix ? this : new JSForInLoop(this._id, prefix, this._markers, this._control, this._body); } private readonly _markers: Markers; @@ -3266,73 +3230,126 @@ export class JSForInLoop extends JSMixin(Object) implements Loop { } public withMarkers(markers: Markers): JSForInLoop { - return markers === this._markers ? this : new JSForInLoop(this._id, this._prefix, markers, this._for_suffix, this._initializer, this._iterable, this._body); + return markers === this._markers ? this : new JSForInLoop(this._id, this._prefix, markers, this._control, this._body); } - private readonly _for_suffix: Space | null; + private readonly _control: JSForInOfLoopControl; - public get for_suffix(): Space | null { - return this._for_suffix; + public get control(): JSForInOfLoopControl { + return this._control; } - public withFor_suffix(for_suffix: Space | null): JSForInLoop { - return for_suffix === this._for_suffix ? this : new JSForInLoop(this._id, this._prefix, this._markers, for_suffix, this._initializer, this._iterable, this._body); + public withControl(control: JSForInOfLoopControl): JSForInLoop { + return control === this._control ? this : new JSForInLoop(this._id, this._prefix, this._markers, control, this._body); } - private readonly _initializer: JRightPadded; + private readonly _body: JRightPadded; - public get initializer(): Expression { - return this._initializer.element; + public get body(): Statement { + return this._body.element; } - public withInitializer(initializer: Expression): JSForInLoop { - return this.padding.withInitializer(this._initializer.withElement(initializer)); + public withBody(body: Statement): JSForInLoop { + return this.padding.withBody(this._body.withElement(body)); } - private readonly _iterable: JRightPadded; + public acceptJavaScript

(v: JavaScriptVisitor

, p: P): J | null { + return v.visitJSForInLoop(this, p); + } - public get iterable(): Expression { - return this._iterable.element; + get padding() { + const t = this; + return new class { + public get body(): JRightPadded { + return t._body; + } + public withBody(body: JRightPadded): JSForInLoop { + return t._body === body ? t : new JSForInLoop(t._id, t._prefix, t._markers, t._control, body); + } } + } - public withIterable(iterable: Expression): JSForInLoop { - return this.padding.withIterable(this._iterable.withElement(iterable)); +} + +@LstType("org.openrewrite.javascript.tree.JS$JSForInOfLoopControl") +export class JSForInOfLoopControl extends JSMixin(Object) { + public constructor(id: UUID, prefix: Space, markers: Markers, variable: JRightPadded, iterable: JRightPadded) { + super(); + this._id = id; + this._prefix = prefix; + this._markers = markers; + this._variable = variable; + this._iterable = iterable; + } + + private readonly _id: UUID; + + public get id(): UUID { + return this._id; } - private readonly _body: JRightPadded; + public withId(id: UUID): JSForInOfLoopControl { + return id === this._id ? this : new JSForInOfLoopControl(id, this._prefix, this._markers, this._variable, this._iterable); + } - public get body(): Statement { - return this._body.element; + private readonly _prefix: Space; + + public get prefix(): Space { + return this._prefix; } - public withBody(body: Statement): JSForInLoop { - return this.padding.withBody(this._body.withElement(body)); + public withPrefix(prefix: Space): JSForInOfLoopControl { + return prefix === this._prefix ? this : new JSForInOfLoopControl(this._id, prefix, this._markers, this._variable, this._iterable); + } + + private readonly _markers: Markers; + + public get markers(): Markers { + return this._markers; + } + + public withMarkers(markers: Markers): JSForInOfLoopControl { + return markers === this._markers ? this : new JSForInOfLoopControl(this._id, this._prefix, markers, this._variable, this._iterable); + } + + private readonly _variable: JRightPadded; + + public get variable(): Expression { + return this._variable.element; + } + + public withVariable(variable: Expression): JSForInOfLoopControl { + return this.padding.withVariable(this._variable.withElement(variable)); + } + + private readonly _iterable: JRightPadded; + + public get iterable(): Expression { + return this._iterable.element; + } + + public withIterable(iterable: Expression): JSForInOfLoopControl { + return this.padding.withIterable(this._iterable.withElement(iterable)); } public acceptJavaScript

(v: JavaScriptVisitor

, p: P): J | null { - return v.visitJSForInLoop(this, p); + return v.visitJSForInOfLoopControl(this, p); } get padding() { const t = this; return new class { - public get initializer(): JRightPadded { - return t._initializer; + public get variable(): JRightPadded { + return t._variable; } - public withInitializer(initializer: JRightPadded): JSForInLoop { - return t._initializer === initializer ? t : new JSForInLoop(t._id, t._prefix, t._markers, t._for_suffix, initializer, t._iterable, t._body); + public withVariable(variable: JRightPadded): JSForInOfLoopControl { + return t._variable === variable ? t : new JSForInOfLoopControl(t._id, t._prefix, t._markers, variable, t._iterable); } public get iterable(): JRightPadded { return t._iterable; } - public withIterable(iterable: JRightPadded): JSForInLoop { - return t._iterable === iterable ? t : new JSForInLoop(t._id, t._prefix, t._markers, t._for_suffix, t._initializer, iterable, t._body); - } - public get body(): JRightPadded { - return t._body; - } - public withBody(body: JRightPadded): JSForInLoop { - return t._body === body ? t : new JSForInLoop(t._id, t._prefix, t._markers, t._for_suffix, t._initializer, t._iterable, body); + public withIterable(iterable: JRightPadded): JSForInOfLoopControl { + return t._iterable === iterable ? t : new JSForInOfLoopControl(t._id, t._prefix, t._markers, t._variable, iterable); } } } diff --git a/openrewrite/src/javascript/visitor.ts b/openrewrite/src/javascript/visitor.ts index 7ea68e42..1783104a 100644 --- a/openrewrite/src/javascript/visitor.ts +++ b/openrewrite/src/javascript/visitor.ts @@ -1,7 +1,7 @@ import * as extensions from "./extensions"; import {ListUtils, SourceFile, Tree, TreeVisitor} from "../core"; import {JS, isJavaScript, JsLeftPadded, JsRightPadded, JsContainer, JsSpace} from "./tree"; -import {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 {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, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration} from "./tree"; import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../java/tree"; import {JavaVisitor} from "../java"; import * as Java from "../java/tree"; @@ -490,10 +490,8 @@ export class JavaScriptVisitor

extends JavaVisitor

{ } jSForOfLoop = tempStatement as JSForOfLoop; jSForOfLoop = jSForOfLoop.withMarkers(this.visitMarkers(jSForOfLoop.markers, p)); - jSForOfLoop = jSForOfLoop.withFor_suffix(this.visitJsSpace(jSForOfLoop.for_suffix, JsSpace.Location.JSFOR_OF_LOOP_FOR_SUFFIX, p)); - jSForOfLoop = jSForOfLoop.padding.withAwait(this.visitJsRightPadded(jSForOfLoop.padding.await, JsRightPadded.Location.JSFOR_OF_LOOP_AWAIT, p)!); - jSForOfLoop = jSForOfLoop.padding.withInitializer(this.visitJsRightPadded(jSForOfLoop.padding.initializer, JsRightPadded.Location.JSFOR_OF_LOOP_INITIALIZER, p)!); - jSForOfLoop = jSForOfLoop.padding.withIterable(this.visitJsRightPadded(jSForOfLoop.padding.iterable, JsRightPadded.Location.JSFOR_OF_LOOP_ITERABLE, p)!); + jSForOfLoop = jSForOfLoop.padding.withAwait(this.visitJsLeftPadded(jSForOfLoop.padding.await, JsLeftPadded.Location.JSFOR_OF_LOOP_AWAIT, p)!); + jSForOfLoop = jSForOfLoop.withControl(this.visitAndCast(jSForOfLoop.control, p)!); jSForOfLoop = jSForOfLoop.padding.withBody(this.visitJsRightPadded(jSForOfLoop.padding.body, JsRightPadded.Location.JSFOR_OF_LOOP_BODY, p)!); return jSForOfLoop; } @@ -507,13 +505,19 @@ export class JavaScriptVisitor

extends JavaVisitor

{ } jSForInLoop = tempStatement as JSForInLoop; jSForInLoop = jSForInLoop.withMarkers(this.visitMarkers(jSForInLoop.markers, p)); - jSForInLoop = jSForInLoop.withFor_suffix(this.visitJsSpace(jSForInLoop.for_suffix, JsSpace.Location.JSFOR_IN_LOOP_FOR_SUFFIX, p)); - jSForInLoop = jSForInLoop.padding.withInitializer(this.visitJsRightPadded(jSForInLoop.padding.initializer, JsRightPadded.Location.JSFOR_IN_LOOP_INITIALIZER, p)!); - jSForInLoop = jSForInLoop.padding.withIterable(this.visitJsRightPadded(jSForInLoop.padding.iterable, JsRightPadded.Location.JSFOR_IN_LOOP_ITERABLE, p)!); + jSForInLoop = jSForInLoop.withControl(this.visitAndCast(jSForInLoop.control, p)!); jSForInLoop = jSForInLoop.padding.withBody(this.visitJsRightPadded(jSForInLoop.padding.body, JsRightPadded.Location.JSFOR_IN_LOOP_BODY, p)!); return jSForInLoop; } + public visitJSForInOfLoopControl(jSForInOfLoopControl: JSForInOfLoopControl, p: P): J | null { + jSForInOfLoopControl = jSForInOfLoopControl.withPrefix(this.visitJsSpace(jSForInOfLoopControl.prefix, JsSpace.Location.JSFOR_IN_OF_LOOP_CONTROL_PREFIX, p)!); + jSForInOfLoopControl = jSForInOfLoopControl.withMarkers(this.visitMarkers(jSForInOfLoopControl.markers, p)); + jSForInOfLoopControl = jSForInOfLoopControl.padding.withVariable(this.visitJsRightPadded(jSForInOfLoopControl.padding.variable, JsRightPadded.Location.JSFOR_IN_OF_LOOP_CONTROL_VARIABLE, p)!); + jSForInOfLoopControl = jSForInOfLoopControl.padding.withIterable(this.visitJsRightPadded(jSForInOfLoopControl.padding.iterable, JsRightPadded.Location.JSFOR_IN_OF_LOOP_CONTROL_ITERABLE, p)!); + return jSForInOfLoopControl; + } + public visitNamespaceDeclaration(namespaceDeclaration: NamespaceDeclaration, p: P): J | null { namespaceDeclaration = namespaceDeclaration.withPrefix(this.visitJsSpace(namespaceDeclaration.prefix, JsSpace.Location.NAMESPACE_DECLARATION_PREFIX, p)!); let tempStatement = this.visitStatement(namespaceDeclaration, p) as Statement; diff --git a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptReceiver.java b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptReceiver.java index 7fc81c94..9f474528 100644 --- a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptReceiver.java +++ b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptReceiver.java @@ -447,10 +447,8 @@ public JS.JSForOfLoop visitJSForOfLoop(JS.JSForOfLoop jSForOfLoop, ReceiverConte jSForOfLoop = jSForOfLoop.withId(ctx.receiveNonNullValue(jSForOfLoop.getId(), UUID.class)); jSForOfLoop = jSForOfLoop.withPrefix(ctx.receiveNonNullNode(jSForOfLoop.getPrefix(), JavaScriptReceiver::receiveSpace)); jSForOfLoop = jSForOfLoop.withMarkers(ctx.receiveNonNullNode(jSForOfLoop.getMarkers(), ctx::receiveMarkers)); - jSForOfLoop = jSForOfLoop.withFor_suffix(ctx.receiveNode(jSForOfLoop.getFor_suffix(), JavaScriptReceiver::receiveSpace)); - jSForOfLoop = jSForOfLoop.getPadding().withAwait(ctx.receiveNonNullNode(jSForOfLoop.getPadding().getAwait(), rightPaddedValueReceiver(java.lang.Boolean.class))); - jSForOfLoop = jSForOfLoop.getPadding().withInitializer(ctx.receiveNonNullNode(jSForOfLoop.getPadding().getInitializer(), JavaScriptReceiver::receiveRightPaddedTree)); - jSForOfLoop = jSForOfLoop.getPadding().withIterable(ctx.receiveNonNullNode(jSForOfLoop.getPadding().getIterable(), JavaScriptReceiver::receiveRightPaddedTree)); + jSForOfLoop = jSForOfLoop.getPadding().withAwait(ctx.receiveNonNullNode(jSForOfLoop.getPadding().getAwait(), leftPaddedValueReceiver(java.lang.Boolean.class))); + jSForOfLoop = jSForOfLoop.withControl(ctx.receiveNonNullNode(jSForOfLoop.getControl(), ctx::receiveTree)); jSForOfLoop = jSForOfLoop.getPadding().withBody(ctx.receiveNonNullNode(jSForOfLoop.getPadding().getBody(), JavaScriptReceiver::receiveRightPaddedTree)); return jSForOfLoop; } @@ -460,13 +458,21 @@ public JS.JSForInLoop visitJSForInLoop(JS.JSForInLoop jSForInLoop, ReceiverConte jSForInLoop = jSForInLoop.withId(ctx.receiveNonNullValue(jSForInLoop.getId(), UUID.class)); jSForInLoop = jSForInLoop.withPrefix(ctx.receiveNonNullNode(jSForInLoop.getPrefix(), JavaScriptReceiver::receiveSpace)); jSForInLoop = jSForInLoop.withMarkers(ctx.receiveNonNullNode(jSForInLoop.getMarkers(), ctx::receiveMarkers)); - jSForInLoop = jSForInLoop.withFor_suffix(ctx.receiveNode(jSForInLoop.getFor_suffix(), JavaScriptReceiver::receiveSpace)); - jSForInLoop = jSForInLoop.getPadding().withInitializer(ctx.receiveNonNullNode(jSForInLoop.getPadding().getInitializer(), JavaScriptReceiver::receiveRightPaddedTree)); - jSForInLoop = jSForInLoop.getPadding().withIterable(ctx.receiveNonNullNode(jSForInLoop.getPadding().getIterable(), JavaScriptReceiver::receiveRightPaddedTree)); + jSForInLoop = jSForInLoop.withControl(ctx.receiveNonNullNode(jSForInLoop.getControl(), ctx::receiveTree)); jSForInLoop = jSForInLoop.getPadding().withBody(ctx.receiveNonNullNode(jSForInLoop.getPadding().getBody(), JavaScriptReceiver::receiveRightPaddedTree)); return jSForInLoop; } + @Override + public JS.JSForInOfLoopControl visitJSForInOfLoopControl(JS.JSForInOfLoopControl jSForInOfLoopControl, ReceiverContext ctx) { + jSForInOfLoopControl = jSForInOfLoopControl.withId(ctx.receiveNonNullValue(jSForInOfLoopControl.getId(), UUID.class)); + jSForInOfLoopControl = jSForInOfLoopControl.withPrefix(ctx.receiveNonNullNode(jSForInOfLoopControl.getPrefix(), JavaScriptReceiver::receiveSpace)); + jSForInOfLoopControl = jSForInOfLoopControl.withMarkers(ctx.receiveNonNullNode(jSForInOfLoopControl.getMarkers(), ctx::receiveMarkers)); + jSForInOfLoopControl = jSForInOfLoopControl.getPadding().withVariable(ctx.receiveNonNullNode(jSForInOfLoopControl.getPadding().getVariable(), JavaScriptReceiver::receiveRightPaddedTree)); + jSForInOfLoopControl = jSForInOfLoopControl.getPadding().withIterable(ctx.receiveNonNullNode(jSForInOfLoopControl.getPadding().getIterable(), JavaScriptReceiver::receiveRightPaddedTree)); + return jSForInOfLoopControl; + } + @Override public JS.NamespaceDeclaration visitNamespaceDeclaration(JS.NamespaceDeclaration namespaceDeclaration, ReceiverContext ctx) { namespaceDeclaration = namespaceDeclaration.withId(ctx.receiveNonNullValue(namespaceDeclaration.getId(), UUID.class)); @@ -1568,10 +1574,8 @@ public T create(Class type, ReceiverContext ctx) { ctx.receiveNonNullValue(null, UUID.class), ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveSpace), ctx.receiveNonNullNode(null, ctx::receiveMarkers), - ctx.receiveNode(null, JavaScriptReceiver::receiveSpace), - ctx.receiveNonNullNode(null, rightPaddedValueReceiver(java.lang.Boolean.class)), - ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree), - ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree), + ctx.receiveNonNullNode(null, leftPaddedValueReceiver(java.lang.Boolean.class)), + ctx.receiveNonNullNode(null, ctx::receiveTree), ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree) ); } @@ -1581,8 +1585,16 @@ public T create(Class type, ReceiverContext ctx) { ctx.receiveNonNullValue(null, UUID.class), ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveSpace), ctx.receiveNonNullNode(null, ctx::receiveMarkers), - ctx.receiveNode(null, JavaScriptReceiver::receiveSpace), - ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree), + ctx.receiveNonNullNode(null, ctx::receiveTree), + ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree) + ); + } + + if (type == JS.JSForInOfLoopControl.class) { + return (T) new JS.JSForInOfLoopControl( + ctx.receiveNonNullValue(null, UUID.class), + ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveSpace), + ctx.receiveNonNullNode(null, ctx::receiveMarkers), ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree), ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree) ); diff --git a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSender.java b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSender.java index 3d63e597..e1aac573 100644 --- a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSender.java +++ b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptSender.java @@ -430,10 +430,8 @@ public JS.JSForOfLoop visitJSForOfLoop(JS.JSForOfLoop jSForOfLoop, SenderContext ctx.sendValue(jSForOfLoop, JS.JSForOfLoop::getId); ctx.sendNode(jSForOfLoop, JS.JSForOfLoop::getPrefix, JavaScriptSender::sendSpace); ctx.sendNode(jSForOfLoop, JS.JSForOfLoop::getMarkers, ctx::sendMarkers); - ctx.sendNode(jSForOfLoop, JS.JSForOfLoop::getFor_suffix, JavaScriptSender::sendSpace); - ctx.sendNode(jSForOfLoop, e -> e.getPadding().getAwait(), JavaScriptSender::sendRightPadded); - ctx.sendNode(jSForOfLoop, e -> e.getPadding().getInitializer(), JavaScriptSender::sendRightPadded); - ctx.sendNode(jSForOfLoop, e -> e.getPadding().getIterable(), JavaScriptSender::sendRightPadded); + ctx.sendNode(jSForOfLoop, e -> e.getPadding().getAwait(), JavaScriptSender::sendLeftPadded); + ctx.sendNode(jSForOfLoop, JS.JSForOfLoop::getControl, ctx::sendTree); ctx.sendNode(jSForOfLoop, e -> e.getPadding().getBody(), JavaScriptSender::sendRightPadded); return jSForOfLoop; } @@ -443,13 +441,21 @@ public JS.JSForInLoop visitJSForInLoop(JS.JSForInLoop jSForInLoop, SenderContext ctx.sendValue(jSForInLoop, JS.JSForInLoop::getId); ctx.sendNode(jSForInLoop, JS.JSForInLoop::getPrefix, JavaScriptSender::sendSpace); ctx.sendNode(jSForInLoop, JS.JSForInLoop::getMarkers, ctx::sendMarkers); - ctx.sendNode(jSForInLoop, JS.JSForInLoop::getFor_suffix, JavaScriptSender::sendSpace); - ctx.sendNode(jSForInLoop, e -> e.getPadding().getInitializer(), JavaScriptSender::sendRightPadded); - ctx.sendNode(jSForInLoop, e -> e.getPadding().getIterable(), JavaScriptSender::sendRightPadded); + ctx.sendNode(jSForInLoop, JS.JSForInLoop::getControl, ctx::sendTree); ctx.sendNode(jSForInLoop, e -> e.getPadding().getBody(), JavaScriptSender::sendRightPadded); return jSForInLoop; } + @Override + public JS.JSForInOfLoopControl visitJSForInOfLoopControl(JS.JSForInOfLoopControl jSForInOfLoopControl, SenderContext ctx) { + ctx.sendValue(jSForInOfLoopControl, JS.JSForInOfLoopControl::getId); + ctx.sendNode(jSForInOfLoopControl, JS.JSForInOfLoopControl::getPrefix, JavaScriptSender::sendSpace); + ctx.sendNode(jSForInOfLoopControl, JS.JSForInOfLoopControl::getMarkers, ctx::sendMarkers); + ctx.sendNode(jSForInOfLoopControl, e -> e.getPadding().getVariable(), JavaScriptSender::sendRightPadded); + ctx.sendNode(jSForInOfLoopControl, e -> e.getPadding().getIterable(), JavaScriptSender::sendRightPadded); + return jSForInOfLoopControl; + } + @Override public JS.NamespaceDeclaration visitNamespaceDeclaration(JS.NamespaceDeclaration namespaceDeclaration, SenderContext ctx) { ctx.sendValue(namespaceDeclaration, JS.NamespaceDeclaration::getId); diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptVisitor.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptVisitor.java index 85cdd5df..2dae7ca9 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptVisitor.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/JavaScriptVisitor.java @@ -763,10 +763,8 @@ public J visitJSForOfLoop(JS.JSForOfLoop jsForOfLoop, P p) { } else { f = (JS.JSForOfLoop) temp; } - f = f.withFor_suffix(visitSpace(f.getFor_suffix(), JsSpace.Location.FOR_LOOP_SUFFIX, p)); - f = f.getPadding().withAwait(visitRightPadded(f.getPadding().getAwait(), JsRightPadded.Location.FOR_OF_AWAIT, p)); - f = f.getPadding().withInitializer(visitRightPadded(f.getPadding().getInitializer(), JsRightPadded.Location.FOR_INIT, p)); - f = f.getPadding().withIterable(visitRightPadded(f.getPadding().getIterable(), JsRightPadded.Location.FOR_ITER, p)); + f = f.getPadding().withAwait(visitLeftPadded(f.getPadding().getAwait(), JsLeftPadded.Location.FOR_OF_AWAIT, p)); + f = f.withControl(visitAndCast(f.getControl(), p)); f = f.getPadding().withBody(visitRightPadded(f.getPadding().getBody(), JsRightPadded.Location.FOR_BODY, p)); return f; } @@ -781,10 +779,17 @@ public J visitJSForInLoop(JS.JSForInLoop jsForInLoop, P p) { } else { f = (JS.JSForInLoop) temp; } - f = f.withFor_suffix(visitSpace(f.getFor_suffix(), JsSpace.Location.FOR_LOOP_SUFFIX, p)); - f = f.getPadding().withInitializer(visitRightPadded(f.getPadding().getInitializer(), JsRightPadded.Location.FOR_INIT, p)); - f = f.getPadding().withIterable(visitRightPadded(f.getPadding().getIterable(), JsRightPadded.Location.FOR_ITER, p)); + f = f.withControl(visitAndCast(f.getControl(), p)); f = f.getPadding().withBody(visitRightPadded(f.getPadding().getBody(), JsRightPadded.Location.FOR_BODY, p)); return f; } + + public J visitJSForInOfLoopControl(JS.JSForInOfLoopControl jsForInOfLoopControl, P p) { + JS.JSForInOfLoopControl c = jsForInOfLoopControl; + c = c.withPrefix(visitSpace(c.getPrefix(), JsSpace.Location.FOR_LOOP_CONTROL_PREFIX, p)); + c = c.withMarkers(visitMarkers(c.getMarkers(), p)); + c = c.getPadding().withVariable(visitRightPadded(c.getPadding().getVariable(), JsRightPadded.Location.FOR_CONTROL_VAR, p)); + c = c.getPadding().withIterable(visitRightPadded(c.getPadding().getIterable(), JsRightPadded.Location.FOR_CONTROL_ITER, p)); + return c; + } } diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/internal/JavaScriptPrinter.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/internal/JavaScriptPrinter.java index e664a40b..f68fe54d 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/internal/JavaScriptPrinter.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/internal/JavaScriptPrinter.java @@ -197,11 +197,7 @@ public J visitJsImport(JS.JsImport jsImport, PrintOutputCapture

p) { p.append("import"); if (jsImport.getImportType()) { - JLeftPadded importType = jsImport.getPadding().getImportType(); - JsLeftPadded.Location location = JsLeftPadded.Location.JS_IMPORT_IMPORT_TYPE; - beforeSyntax(importType.getBefore(), importType.getMarkers(), location.getBeforeLocation(), p); - p.append("type"); - afterSyntax(importType.getMarkers(), p); + visitLeftPaddedBoolean("type", jsImport.getPadding().getImportType(), JsLeftPadded.Location.JS_IMPORT_IMPORT_TYPE, p); } // for default export or `* as ` @@ -231,11 +227,7 @@ public J visitJsImport(JS.JsImport jsImport, PrintOutputCapture

p) { public J visitJsImportSpecifier(JS.JsImportSpecifier jis, PrintOutputCapture

p) { beforeSyntax(jis, JsSpace.Location.JS_IMPORT_SPECIFIER_PREFIX, p); if (jis.getImportType()) { - JLeftPadded importType = jis.getPadding().getImportType(); - JsLeftPadded.Location location = JsLeftPadded.Location.JS_IMPORT_SPECIFIER_IMPORT_TYPE; - beforeSyntax(importType.getBefore(), importType.getMarkers(), location.getBeforeLocation(), p); - p.append("type"); - afterSyntax(importType.getMarkers(), p); + visitLeftPaddedBoolean("type", jis.getPadding().getImportType(), JsLeftPadded.Location.JS_IMPORT_SPECIFIER_IMPORT_TYPE, p); } visit(jis.getSpecifier(), p); @@ -649,15 +641,16 @@ public J visitFunctionDeclaration(JS.FunctionDeclaration functionDeclaration, Pr public J visitJSForOfLoop(JS.JSForOfLoop loop, PrintOutputCapture

p) { beforeSyntax(loop, JsSpace.Location.FOR_OF_LOOP_PREFIX, p); p.append("for"); - visitSpace(loop.getFor_suffix(), JsSpace.Location.FOR_LOOP_SUFFIX, p); if (loop.isAwait()) { - p.append("await"); - visitRightPadded(loop.getPadding().getAwait(), JsRightPadded.Location.FOR_OF_AWAIT, p); + visitLeftPaddedBoolean("await", loop.getPadding().getAwait(), JsLeftPadded.Location.FOR_OF_AWAIT, p); } + + JS.JSForInOfLoopControl control = loop.getControl(); + visitSpace(control.getPrefix(), JsSpace.Location.FOR_LOOP_CONTROL_PREFIX, p); p.append('('); - visitRightPadded(loop.getPadding().getInitializer(), JsRightPadded.Location.FOR_INIT, p); + visitRightPadded(control.getPadding().getVariable(), JsRightPadded.Location.FOR_CONTROL_VAR, p); p.append("of"); - visitRightPadded(loop.getPadding().getIterable(), JsRightPadded.Location.FOR_ITER, p); + visitRightPadded(control.getPadding().getIterable(), JsRightPadded.Location.FOR_CONTROL_ITER, p); p.append(')'); visitRightPadded(loop.getPadding().getBody(), JsRightPadded.Location.FOR_BODY, p); afterSyntax(loop, p); @@ -668,11 +661,13 @@ public J visitJSForOfLoop(JS.JSForOfLoop loop, PrintOutputCapture

p) { public J visitJSForInLoop(JS.JSForInLoop loop, PrintOutputCapture

p) { beforeSyntax(loop, JsSpace.Location.FOR_IN_LOOP_PREFIX, p); p.append("for"); - visitSpace(loop.getFor_suffix(), JsSpace.Location.FOR_LOOP_SUFFIX, p); + + JS.JSForInOfLoopControl control = loop.getControl(); + visitSpace(control.getPrefix(), JsSpace.Location.FOR_LOOP_CONTROL_PREFIX, p); p.append('('); - visitRightPadded(loop.getPadding().getInitializer(), JsRightPadded.Location.FOR_INIT, p); + visitRightPadded(control.getPadding().getVariable(), JsRightPadded.Location.FOR_CONTROL_VAR, p); p.append("in"); - visitRightPadded(loop.getPadding().getIterable(), JsRightPadded.Location.FOR_ITER, p); + visitRightPadded(control.getPadding().getIterable(), JsRightPadded.Location.FOR_CONTROL_ITER, p); p.append(')'); visitRightPadded(loop.getPadding().getBody(), JsRightPadded.Location.FOR_BODY, p); afterSyntax(loop, p); @@ -1165,6 +1160,16 @@ protected void visitLeftPadded(@Nullable String prefix, @Nullable JLeftPadded leftPadded, JsLeftPadded.Location location, PrintOutputCapture

p) { + if (leftPadded != null) { + beforeSyntax(leftPadded.getBefore(), leftPadded.getMarkers(), location.getBeforeLocation(), p); + if (prefix != null) { + p.append(prefix); + } + afterSyntax(leftPadded.getMarkers(), p); + } + } + protected void visitRightPadded(List> nodes, JsRightPadded.Location location, String suffixBetween, PrintOutputCapture

p) { for (int i = 0; i < nodes.size(); i++) { JRightPadded node = nodes.get(i); diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JS.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JS.java index b729c55d..96d0b8b2 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JS.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JS.java @@ -2848,12 +2848,7 @@ final class JSForOfLoop implements JS, Loop { @Getter Markers markers; - @With - @Nullable - @Getter - Space for_suffix; - - JRightPadded await; + JLeftPadded await; public boolean isAwait() { return await.getElement(); @@ -2863,23 +2858,9 @@ public JSForOfLoop withAwait(boolean await) { return getPadding().withAwait(this.await.withElement(await)); } - JRightPadded initializer; - - public Expression getInitializer() { return initializer.getElement(); } - - public JSForOfLoop withInitializer(Expression initializer) { - return getPadding().withInitializer(this.initializer.withElement(initializer)); - } - - JRightPadded iterable; - - public Expression getIterable() { - return iterable.getElement(); - } - - public JSForOfLoop withIterable(Expression iterable) { - return getPadding().withIterable(this.iterable.withElement(iterable)); - } + @With + @Getter + JSForInOfLoopControl control; JRightPadded body; @@ -2925,28 +2906,12 @@ public JSForOfLoop.Padding getPadding() { public static class Padding { private final JSForOfLoop t; - public JRightPadded getAwait() { + public JLeftPadded getAwait() { return t.await; } - public JSForOfLoop withAwait(JRightPadded await) { - return t.await == await ? t : new JSForOfLoop(t.id, t.prefix, t.markers, t.for_suffix, await, t.initializer, t.iterable, t.body); - } - - public JRightPadded getInitializer() { - return t.initializer; - } - - public JSForOfLoop withInitializer(JRightPadded initializer) { - return t.initializer == initializer ? t : new JSForOfLoop(t.id, t.prefix, t.markers, t.for_suffix, t.await, initializer, t.iterable, t.body); - } - - public JRightPadded getIterable() { - return t.iterable; - } - - public JSForOfLoop withIterable(JRightPadded iterable) { - return t.iterable == iterable ? t : new JSForOfLoop(t.id, t.prefix, t.markers, t.for_suffix, t.await, t.initializer, iterable, t.body); + public JSForOfLoop withAwait(JLeftPadded await) { + return t.await == await ? t : new JSForOfLoop(t.id, t.prefix, t.markers, await, t.control, t.body); } public JRightPadded getBody() { @@ -2954,14 +2919,9 @@ public JRightPadded getBody() { } public JSForOfLoop withBody(JRightPadded body) { - return t.body == body ? t : new JSForOfLoop(t.id, t.prefix, t.markers, t.for_suffix, t.await, t.initializer, t.iterable, body); + return t.body == body ? t : new JSForOfLoop(t.id, t.prefix, t.markers, t.await, t.control, body); } } - - @Override - public String toString() { - return withPrefix(Space.EMPTY).printTrimmed(new JavaPrinter<>()); - } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @@ -2987,27 +2947,8 @@ final class JSForInLoop implements JS, Loop { Markers markers; @With - @Nullable @Getter - Space for_suffix; - - JRightPadded initializer; - - public Expression getInitializer() { return initializer.getElement(); } - - public JSForInLoop withInitializer(Expression initializer) { - return getPadding().withInitializer(this.initializer.withElement(initializer)); - } - - JRightPadded iterable; - - public Expression getIterable() { - return iterable.getElement(); - } - - public JSForInLoop withIterable(Expression iterable) { - return getPadding().withIterable(this.iterable.withElement(iterable)); - } + JSForInOfLoopControl control; JRightPadded body; @@ -3053,35 +2994,105 @@ public JSForInLoop.Padding getPadding() { public static class Padding { private final JSForInLoop t; - public JRightPadded getInitializer() { - return t.initializer; + public JRightPadded getBody() { + return t.body; } - public JSForInLoop withInitializer(JRightPadded initializer) { - return t.initializer == initializer ? t : new JSForInLoop(t.id, t.prefix, t.markers, t.for_suffix, initializer, t.iterable, t.body); + public JSForInLoop withBody(JRightPadded body) { + return t.body == body ? t : new JSForInLoop(t.id, t.prefix, t.markers, t.for_suffix, t.initializer, t.iterable, body); } - - public JRightPadded getIterable() { - return t.iterable; + return t.body == body ? t : new JSForInLoop(t.id, t.prefix, t.markers, t.control, body); } + } + } - public JSForInLoop withIterable(JRightPadded iterable) { - return t.iterable == iterable ? t : new JSForInLoop(t.id, t.prefix, t.markers, t.for_suffix, t.initializer, iterable, t.body); - } + @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) + @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) + @RequiredArgsConstructor + @AllArgsConstructor(access = AccessLevel.PRIVATE) + final class JSForInOfLoopControl implements JS { + @Nullable + @NonFinal + transient WeakReference padding; - public JRightPadded getBody() { - return t.body; - } + @With + @EqualsAndHashCode.Include + @Getter + UUID id; - public JSForInLoop withBody(JRightPadded body) { - return t.body == body ? t : new JSForInLoop(t.id, t.prefix, t.markers, t.for_suffix, t.initializer, t.iterable, body); + @With + @Getter + Space prefix; + + @With + @Getter + Markers markers; + + JRightPadded variable; + + public Expression getVariable() { + return variable.getElement(); + } + + public JSForInOfLoopControl withVariable(Expression variable) { + return getPadding().withVariable(this.variable.withElement(variable)); + } + + JRightPadded iterable; + + public Expression getIterable() { + return iterable.getElement(); + } + + public JSForInOfLoopControl withIterable(Expression iterable) { + return getPadding().withIterable(this.iterable.withElement(iterable)); + } + + @Override + public

J acceptJavaScript(JavaScriptVisitor

v, P p) { + return v.visitJSForInOfLoopControl(this, p); + } + + public Padding getPadding() { + Padding p; + if (this.padding == null) { + p = new Padding(this); + this.padding = new WeakReference<>(p); + } else { + p = this.padding.get(); + if (p == null || p.t != this) { + p = new Padding(this); + this.padding = new WeakReference<>(p); + } } + return p; } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new JavaPrinter<>()); } + + @RequiredArgsConstructor + public static class Padding { + private final JSForInOfLoopControl t; + + public JRightPadded getVariable() { + return t.variable; + } + + public JSForInOfLoopControl withVariable(JRightPadded variable) { + return t.variable == variable ? t : new JSForInOfLoopControl(t.id, t.prefix, t.markers, variable, t.iterable); + } + + public JRightPadded getIterable() { + return t.iterable; + } + + public JSForInOfLoopControl withIterable(JRightPadded iterable) { + return t.iterable == iterable ? t : new JSForInOfLoopControl(t.id, t.prefix, t.markers, t.variable, iterable); + } + } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsLeftPadded.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsLeftPadded.java index f4295f78..95869f82 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsLeftPadded.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsLeftPadded.java @@ -31,7 +31,7 @@ public enum Location { NAMESPACE_DECLARATION_KEYWORD_TYPE(JsSpace.Location.NAMESPACE_DECLARATION_KEYWORD_PREFIX), JS_IMPORT_IMPORT_TYPE(JsSpace.Location.JS_IMPORT_IMPORT_TYPE_PREFIX), JS_IMPORT_SPECIFIER_IMPORT_TYPE(JsSpace.Location.JS_IMPORT_SPECIFIER_IMPORT_TYPE_PREFIX), - ; + FOR_OF_AWAIT(JsSpace.Location.FOR_OF_AWAIT_PREFIX); private final JsSpace.Location beforeLocation; diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsRightPadded.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsRightPadded.java index a7351d47..60ed040f 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsRightPadded.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsRightPadded.java @@ -38,10 +38,10 @@ public enum Location { JSMETHOD_DECLARATION_PARAMETER(JsSpace.Location.JSMETHOD_DECLARATION_PARAMETERS), JSMETHOD_SELECT(JsSpace.Location.JSMETHOD_SELECT_SUFFIX), JSTYPE_PARAMETER(JsSpace.Location.JSTYPE_PARAMETER_SUFFIX), - FOR_OF_AWAIT(JsSpace.Location.FOR_OF_AWAIT_SUFFIX), - FOR_INIT(JsSpace.Location.FOR_INIT_SUFFIX), - FOR_ITER(JsSpace.Location.FOR_ITER_SUFFIX), - FOR_BODY(JsSpace.Location.FOR_BODY_SUFFIX); + FOR_CONTROL_VAR(JsSpace.Location.FOR_INIT_SUFFIX), + FOR_CONTROL_ITER(JsSpace.Location.FOR_ITER_SUFFIX), + FOR_BODY(JsSpace.Location.FOR_BODY_SUFFIX), + FUNCTION_TYPE_CONSTRUCTOR(JsSpace.Location.FUNCTION_TYPE_CONSTRUCTOR_SUFFIX); private final JsSpace.Location afterLocation; diff --git a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsSpace.java b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsSpace.java index b4a8da11..8d527bdf 100644 --- a/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsSpace.java +++ b/rewrite-javascript/src/main/java/org/openrewrite/javascript/tree/JsSpace.java @@ -90,8 +90,8 @@ public enum Location { JSTYPE_PARAMETERS, JSTYPE_PARAMETER_SUFFIX, FOR_OF_LOOP_PREFIX, - FOR_LOOP_SUFFIX, - FOR_OF_AWAIT_SUFFIX, + FOR_LOOP_CONTROL_PREFIX, + FOR_OF_AWAIT_PREFIX, FOR_BODY_SUFFIX, FOR_INIT_SUFFIX, FOR_ITER_SUFFIX,