diff --git a/openrewrite/src/javascript/parser.ts b/openrewrite/src/javascript/parser.ts index 7d25226..6fc3085 100644 --- a/openrewrite/src/javascript/parser.ts +++ b/openrewrite/src/javascript/parser.ts @@ -771,7 +771,14 @@ export class JavaScriptParserVisitor { let _arguments: JContainer | null = null; if (ts.isCallExpression(node.expression)) { - annotationType = this.convert(node.expression.expression); + annotationType = new JS.ExpressionWithTypeArguments( + randomId(), + Space.EMPTY, + Markers.EMPTY, + this.convert(node.expression.expression), + node.expression.typeArguments ? this.mapTypeArguments(this.suffix(node.expression.expression), node.expression.typeArguments) : null, + null + ); _arguments = this.mapCommaSeparatedList(node.expression.getChildren(this.sourceFile).slice(-3)) } else if (ts.isIdentifier(node.expression)) { annotationType = this.convert(node.expression); @@ -1146,7 +1153,7 @@ export class JavaScriptParserVisitor { randomId(), this.prefix(node), Markers.EMPTY, - [], + this.mapDecorators(node), this.mapModifiers(node), null, this.mapTypeInfo(node), @@ -1163,7 +1170,7 @@ export class JavaScriptParserVisitor { randomId(), this.prefix(node), Markers.EMPTY, - [], + this.mapDecorators(node), this.mapModifiers(node), null, this.mapTypeInfo(node), @@ -1186,7 +1193,7 @@ export class JavaScriptParserVisitor { randomId(), this.prefix(node), Markers.EMPTY, - [], + this.mapDecorators(node), this.mapModifiers(node), null, null, @@ -1203,7 +1210,7 @@ export class JavaScriptParserVisitor { randomId(), this.prefix(node), Markers.EMPTY, - [], + this.mapDecorators(node), this.mapModifiers(node), null, null, @@ -2615,7 +2622,7 @@ export class JavaScriptParserVisitor { Markers.EMPTY, [node.initializer ? (ts.isVariableDeclarationList(node.initializer) ? this.rightPadded(this.visit(node.initializer), Space.EMPTY) : - this.rightPadded(new ExpressionStatement(randomId(), this.visit(node.initializer)), this.suffix(node.initializer.getLastToken()!))) : + this.rightPadded(new ExpressionStatement(randomId(), this.visit(node.initializer)), this.suffix(node.initializer))) : this.rightPadded(this.newJEmpty(), this.suffix(this.findChildNode(node, ts.SyntaxKind.OpenParenToken)!))], // to handle for (/*_*/; ; ); node.condition ? this.rightPadded(ts.isStatement(node.condition) ? this.visit(node.condition) : new ExpressionStatement(randomId(), this.visit(node.condition)), this.suffix(node.condition)) : this.rightPadded(this.newJEmpty(), this.suffix(this.findChildNode(node, ts.SyntaxKind.SemicolonToken)!)), // to handle for ( ;/*_*/; ); @@ -2758,7 +2765,7 @@ export class JavaScriptParserVisitor { visitVariableDeclaration(node: ts.VariableDeclaration) { const nameExpression = this.visit(node.name); - if (nameExpression instanceof J.Identifier) { + if (nameExpression instanceof J.Identifier && !node.exclamationToken) { return new J.VariableDeclarations.NamedVariable( randomId(), this.prefix(node), @@ -2774,7 +2781,17 @@ export class JavaScriptParserVisitor { randomId(), this.prefix(node), Markers.EMPTY, - nameExpression, + node.exclamationToken ? new JS.Unary( + randomId(), + Space.EMPTY, + Markers.EMPTY, + this.leftPadded( + this.suffix(node.name), + JS.Unary.Type.Exclamation + ), + nameExpression, + this.mapType(node) + ) : nameExpression, [], node.initializer ? this.leftPadded(this.prefix(node.getChildAt(node.getChildCount(this.sourceFile) - 2)), this.visit(node.initializer)) : null, this.mapVariableType(node) @@ -2945,9 +2962,15 @@ export class JavaScriptParserVisitor { visitModuleDeclaration(node: ts.ModuleDeclaration) { const body = node.body ? this.visit(node.body as ts.Node) : null; - let namespaceKeyword = this.findChildNode(node, ts.SyntaxKind.NamespaceKeyword); - const keywordType = namespaceKeyword ? JS.NamespaceDeclaration.KeywordType.Namespace : JS.NamespaceDeclaration.KeywordType.Module - namespaceKeyword ??= this.findChildNode(node, ts.SyntaxKind.ModuleKeyword); + let namespaceKeyword = this.findChildNode(node, ts.SyntaxKind.NamespaceKeyword) ?? this.findChildNode(node, ts.SyntaxKind.ModuleKeyword); + let keywordType: JS.NamespaceDeclaration.KeywordType; + if (namespaceKeyword == undefined) { + keywordType = JS.NamespaceDeclaration.KeywordType.Empty; + } else if (namespaceKeyword?.kind === ts.SyntaxKind.NamespaceKeyword) { + keywordType = JS.NamespaceDeclaration.KeywordType.Namespace; + } else { + keywordType = JS.NamespaceDeclaration.KeywordType.Module; + } if (body instanceof JS.NamespaceDeclaration) { return new JS.NamespaceDeclaration( randomId(), @@ -3368,6 +3391,7 @@ export class JavaScriptParserVisitor { this.prefix(node), Markers.EMPTY, this.rightPadded(this.visit(node.name), this.suffix(node.name)), + JS.PropertyAssignment.AssigmentToken.Colon, this.visit(node.initializer) ); } @@ -3378,7 +3402,8 @@ export class JavaScriptParserVisitor { this.prefix(node), Markers.EMPTY, this.rightPadded(this.visit(node.name), this.suffix(node.name)), - null + JS.PropertyAssignment.AssigmentToken.Equals, + node.objectAssignmentInitializer ? this.visit(node.objectAssignmentInitializer) : null ); } @@ -3401,6 +3426,7 @@ export class JavaScriptParserVisitor { ), this.suffix(node.expression) ), + JS.PropertyAssignment.AssigmentToken.Empty, null ); } @@ -3740,7 +3766,7 @@ export class JavaScriptParserVisitor { return args; } - private mapDecorators(node: ts.ClassDeclaration | ts.FunctionDeclaration | ts.MethodDeclaration | ts.ConstructorDeclaration | ts.ParameterDeclaration | ts.PropertyDeclaration): J.Annotation[] { + private mapDecorators(node: ts.ClassDeclaration | ts.FunctionDeclaration | ts.MethodDeclaration | ts.ConstructorDeclaration | ts.ParameterDeclaration | ts.PropertyDeclaration | ts.SetAccessorDeclaration | ts.GetAccessorDeclaration): J.Annotation[] { return node.modifiers?.filter(ts.isDecorator)?.map(this.convert) ?? []; } @@ -3748,7 +3774,10 @@ export class JavaScriptParserVisitor { return node.typeParameters ? JContainer.build( this.suffix(this.findChildNode(node, ts.SyntaxKind.Identifier)!), - this.mapTypeParametersList(node.typeParameters), + this.mapTypeParametersList(node.typeParameters) + .concat(node.typeParameters.hasTrailingComma ? this.rightPadded( + new J.TypeParameter(randomId(), Space.EMPTY, Markers.EMPTY, [], [], this.newJEmpty(), null), + this.prefix(this.findChildNode(node, ts.SyntaxKind.GreaterThanToken)!)) : []), Markers.EMPTY ) : null; @@ -3765,7 +3794,9 @@ export class JavaScriptParserVisitor { Markers.EMPTY, [], typeParameters.map(tp => this.rightPadded(this.visit(tp), this.suffix(tp))) - .concat(typeParameters.hasTrailingComma ? this.rightPadded(this.newJEmpty(), this.prefix(this.findChildNode(node, ts.SyntaxKind.GreaterThanToken)!)) : []), + .concat(typeParameters.hasTrailingComma ? this.rightPadded( + new J.TypeParameter(randomId(), Space.EMPTY, Markers.EMPTY, [], [], this.newJEmpty(), null), + this.prefix(this.findChildNode(node, ts.SyntaxKind.GreaterThanToken)!)) : []), ); } diff --git a/openrewrite/src/javascript/remote/receiver.ts b/openrewrite/src/javascript/remote/receiver.ts index aeb2bff..390112a 100644 --- a/openrewrite/src/javascript/remote/receiver.ts +++ b/openrewrite/src/javascript/remote/receiver.ts @@ -258,6 +258,7 @@ class Visitor extends JavaScriptVisitor { propertyAssignment = propertyAssignment.withPrefix(ctx.receiveNode(propertyAssignment.prefix, receiveSpace)!); propertyAssignment = propertyAssignment.withMarkers(ctx.receiveNode(propertyAssignment.markers, ctx.receiveMarkers)!); propertyAssignment = propertyAssignment.padding.withName(ctx.receiveNode(propertyAssignment.padding.name, receiveRightPaddedTree)!); + propertyAssignment = propertyAssignment.withAssigmentToken(ctx.receiveValue(propertyAssignment.assigmentToken, ValueType.Enum)!); propertyAssignment = propertyAssignment.withInitializer(ctx.receiveNode(propertyAssignment.initializer, ctx.receiveTree)); return propertyAssignment; } @@ -1575,6 +1576,7 @@ class Factory implements ReceiverFactory { ctx.receiveNode(null, receiveSpace)!, ctx.receiveNode(null, ctx.receiveMarkers)!, ctx.receiveNode>(null, receiveRightPaddedTree)!, + ctx.receiveValue(null, ValueType.Enum)!, ctx.receiveNode(null, ctx.receiveTree) ); } @@ -1941,7 +1943,7 @@ class Factory implements ReceiverFactory { ctx.receiveValue(null, ValueType.UUID)!, ctx.receiveNode(null, receiveSpace)!, ctx.receiveNode(null, ctx.receiveMarkers)!, - ctx.receiveNode>(null, receiveContainer)!, + ctx.receiveNode>(null, receiveContainer)!, ctx.receiveValue(null, ValueType.Object) ); } diff --git a/openrewrite/src/javascript/remote/sender.ts b/openrewrite/src/javascript/remote/sender.ts index 535bcde..4d27d2e 100644 --- a/openrewrite/src/javascript/remote/sender.ts +++ b/openrewrite/src/javascript/remote/sender.ts @@ -253,6 +253,7 @@ class Visitor extends JavaScriptVisitor { ctx.sendNode(propertyAssignment, v => v.prefix, Visitor.sendSpace); ctx.sendNode(propertyAssignment, v => v.markers, ctx.sendMarkers); ctx.sendNode(propertyAssignment, v => v.padding.name, Visitor.sendRightPadded(ValueType.Tree)); + ctx.sendValue(propertyAssignment, v => v.assigmentToken, ValueType.Enum); ctx.sendNode(propertyAssignment, v => v.initializer, ctx.sendTree); return propertyAssignment; } diff --git a/openrewrite/src/javascript/tree/tree.ts b/openrewrite/src/javascript/tree/tree.ts index 96bd95a..00db5c0 100644 --- a/openrewrite/src/javascript/tree/tree.ts +++ b/openrewrite/src/javascript/tree/tree.ts @@ -2101,12 +2101,13 @@ export class ObjectBindingDeclarations extends JSMixin(Object) implements Expres @LstType("org.openrewrite.javascript.tree.JS$PropertyAssignment") export class PropertyAssignment extends JSMixin(Object) implements Statement, TypedTree { - public constructor(id: UUID, prefix: Space, markers: Markers, name: JRightPadded, initializer: Expression | null) { + public constructor(id: UUID, prefix: Space, markers: Markers, name: JRightPadded, assigmentToken: PropertyAssignment.AssigmentToken, initializer: Expression | null) { super(); this._id = id; this._prefix = prefix; this._markers = markers; this._name = name; + this._assigmentToken = assigmentToken; this._initializer = initializer; } @@ -2117,7 +2118,7 @@ export class PropertyAssignment extends JSMixin(Object) implements Statement, Ty } public withId(id: UUID): PropertyAssignment { - return id === this._id ? this : new PropertyAssignment(id, this._prefix, this._markers, this._name, this._initializer); + return id === this._id ? this : new PropertyAssignment(id, this._prefix, this._markers, this._name, this._assigmentToken, this._initializer); } private readonly _prefix: Space; @@ -2127,7 +2128,7 @@ export class PropertyAssignment extends JSMixin(Object) implements Statement, Ty } public withPrefix(prefix: Space): PropertyAssignment { - return prefix === this._prefix ? this : new PropertyAssignment(this._id, prefix, this._markers, this._name, this._initializer); + return prefix === this._prefix ? this : new PropertyAssignment(this._id, prefix, this._markers, this._name, this._assigmentToken, this._initializer); } private readonly _markers: Markers; @@ -2137,7 +2138,7 @@ export class PropertyAssignment extends JSMixin(Object) implements Statement, Ty } public withMarkers(markers: Markers): PropertyAssignment { - return markers === this._markers ? this : new PropertyAssignment(this._id, this._prefix, markers, this._name, this._initializer); + return markers === this._markers ? this : new PropertyAssignment(this._id, this._prefix, markers, this._name, this._assigmentToken, this._initializer); } private readonly _name: JRightPadded; @@ -2150,6 +2151,16 @@ export class PropertyAssignment extends JSMixin(Object) implements Statement, Ty return this.padding.withName(this._name.withElement(name)); } + private readonly _assigmentToken: PropertyAssignment.AssigmentToken; + + public get assigmentToken(): PropertyAssignment.AssigmentToken { + return this._assigmentToken; + } + + public withAssigmentToken(assigmentToken: PropertyAssignment.AssigmentToken): PropertyAssignment { + return assigmentToken === this._assigmentToken ? this : new PropertyAssignment(this._id, this._prefix, this._markers, this._name, assigmentToken, this._initializer); + } + private readonly _initializer: Expression | null; public get initializer(): Expression | null { @@ -2157,7 +2168,7 @@ export class PropertyAssignment extends JSMixin(Object) implements Statement, Ty } public withInitializer(initializer: Expression | null): PropertyAssignment { - return initializer === this._initializer ? this : new PropertyAssignment(this._id, this._prefix, this._markers, this._name, initializer); + return initializer === this._initializer ? this : new PropertyAssignment(this._id, this._prefix, this._markers, this._name, this._assigmentToken, initializer); } public acceptJavaScript

(v: JavaScriptVisitor

, p: P): J | null { @@ -2179,13 +2190,23 @@ export class PropertyAssignment extends JSMixin(Object) implements Statement, Ty return t._name; } public withName(name: JRightPadded): PropertyAssignment { - return t._name === name ? t : new PropertyAssignment(t._id, t._prefix, t._markers, name, t._initializer); + return t._name === name ? t : new PropertyAssignment(t._id, t._prefix, t._markers, name, t._assigmentToken, t._initializer); } } } } +export namespace PropertyAssignment { + export enum AssigmentToken { + Colon = 0, + Equals = 1, + Empty = 2, + + } + +} + @LstType("org.openrewrite.javascript.tree.JS$SatisfiesExpression") export class SatisfiesExpression extends JSMixin(Object) implements Expression { public constructor(id: UUID, prefix: Space, markers: Markers, expression: J, satisfiesType: JLeftPadded, _type: JavaType | null) { @@ -4482,6 +4503,7 @@ export namespace NamespaceDeclaration { export enum KeywordType { Namespace = 0, Module = 1, + Empty = 2, } @@ -5211,7 +5233,7 @@ export class ExportAssignment extends JSMixin(Object) implements Statement { @LstType("org.openrewrite.javascript.tree.JS$NamedExports") export class NamedExports extends JSMixin(Object) implements Expression { - public constructor(id: UUID, prefix: Space, markers: Markers, elements: JContainer, _type: JavaType | null) { + public constructor(id: UUID, prefix: Space, markers: Markers, elements: JContainer, _type: JavaType | null) { super(); this._id = id; this._prefix = prefix; @@ -5250,13 +5272,13 @@ export class NamedExports extends JSMixin(Object) implements Expression { return markers === this._markers ? this : new NamedExports(this._id, this._prefix, markers, this._elements, this._type); } - private readonly _elements: JContainer; + private readonly _elements: JContainer; - public get elements(): ExportSpecifier[] { + public get elements(): Expression[] { return this._elements.elements; } - public withElements(elements: ExportSpecifier[]): NamedExports { + public withElements(elements: Expression[]): NamedExports { return this.padding.withElements(JContainer.withElements(this._elements, elements)); } @@ -5277,10 +5299,10 @@ export class NamedExports extends JSMixin(Object) implements Expression { get padding() { const t = this; return new class { - public get elements(): JContainer { + public get elements(): JContainer { return t._elements; } - public withElements(elements: JContainer): NamedExports { + public withElements(elements: JContainer): NamedExports { return t._elements === elements ? t : new NamedExports(t._id, t._prefix, t._markers, elements, t._type); } } diff --git a/openrewrite/test/javascript/parser/call.test.ts b/openrewrite/test/javascript/parser/call.test.ts index 8dc2289..ae670a5 100644 --- a/openrewrite/test/javascript/parser/call.test.ts +++ b/openrewrite/test/javascript/parser/call.test.ts @@ -162,6 +162,7 @@ describe('call mapping', () => { //language=typescript typeScript(` var d = (new Date).getTime() + // use marker omit `) ); }); diff --git a/openrewrite/test/javascript/parser/class.test.ts b/openrewrite/test/javascript/parser/class.test.ts index 91096c4..743e985 100644 --- a/openrewrite/test/javascript/parser/class.test.ts +++ b/openrewrite/test/javascript/parser/class.test.ts @@ -542,4 +542,15 @@ describe('class mapping', () => { ); }); + test('class with type param with trailing comma', () => { + rewriteRun( + //language=typescript + typeScript(` + export class APIError< + TData extends null | object = { [key: string]: unknown } | null, + > extends ExtendableError {} + `) + ); + }); + }); diff --git a/openrewrite/test/javascript/parser/decorator.test.ts b/openrewrite/test/javascript/parser/decorator.test.ts index 571eeab..369e05f 100644 --- a/openrewrite/test/javascript/parser/decorator.test.ts +++ b/openrewrite/test/javascript/parser/decorator.test.ts @@ -45,6 +45,15 @@ describe('class decorator mapping', () => { `) ); }); + test('decorator with type params', () => { + rewriteRun( + //language=typescript + typeScript(` + @StaticInterfaceImplement/*a*//*b*/() + export class SimpleSpriteAssembler {} + `) + ); + }); test('class / method / params / properties decorators', () => { rewriteRun( //language=typescript diff --git a/openrewrite/test/javascript/parser/do-while.test.ts b/openrewrite/test/javascript/parser/do-while.test.ts index 44b0c5a..aeeaf4f 100644 --- a/openrewrite/test/javascript/parser/do-while.test.ts +++ b/openrewrite/test/javascript/parser/do-while.test.ts @@ -38,4 +38,16 @@ describe('do-while mapping', () => { `) ); }); + + test.skip('do-while with labeled statement', () => { + rewriteRun( + //language=typescript + typeScript(` + partition: do { + break partition; + } while (from < to)/*a*/;/*b*/ + `) + ); + }); + }); diff --git a/openrewrite/test/javascript/parser/export.test.ts b/openrewrite/test/javascript/parser/export.test.ts index 4f25ea1..035c314 100644 --- a/openrewrite/test/javascript/parser/export.test.ts +++ b/openrewrite/test/javascript/parser/export.test.ts @@ -158,6 +158,15 @@ describe('export keyword tests', () => { `) ); }); + + test('empty named export', () => { + rewriteRun( + //language=typescript + typeScript(` + export {/*a*/} + `) + ); + }); }); diff --git a/openrewrite/test/javascript/parser/expressionStatement.test.ts b/openrewrite/test/javascript/parser/expressionStatement.test.ts index 95dc8b2..99abc6f 100644 --- a/openrewrite/test/javascript/parser/expressionStatement.test.ts +++ b/openrewrite/test/javascript/parser/expressionStatement.test.ts @@ -202,4 +202,16 @@ describe('expression statement mapping', () => { ); }); + test('shorthand property assignment with initializer', () => { + rewriteRun( + //language=typescript + typeScript(` + ({ + initialState, + resultSelector/*a*/ = /*b*/identity as ResultFunc, + } = initialStateOrOptions as GenerateOptions); + `) + ); + }); + }); diff --git a/openrewrite/test/javascript/parser/method.test.ts b/openrewrite/test/javascript/parser/method.test.ts index 7afc89b..4726569 100644 --- a/openrewrite/test/javascript/parser/method.test.ts +++ b/openrewrite/test/javascript/parser/method.test.ts @@ -199,17 +199,12 @@ describe('method mapping', () => { ); }); - test('method invocation with empty body', () => { + test('extends as a call expression', () => { rewriteRun( //language=typescript typeScript(` export class ResultLengthMismatch extends TypeIdError(SqlErrorTypeId, "ResultLengthMismatch")<{ - readonly expected: number - readonly actual: number }> { - get message() { - return \`Expected \${this.expected} results but got \${this.actual}\` - } } `) ); diff --git a/openrewrite/test/javascript/parser/namespace.test.ts b/openrewrite/test/javascript/parser/namespace.test.ts index 08f71f0..17886c2 100644 --- a/openrewrite/test/javascript/parser/namespace.test.ts +++ b/openrewrite/test/javascript/parser/namespace.test.ts @@ -271,4 +271,19 @@ describe('namespace mapping', () => { `) ); }); + + + test('extend global type definitions without namespace keyword', () => { + rewriteRun( + //language=typescript + typeScript(` + declare global { + interface Window { + myCustomGlobalFunction?: () => void; // Add a custom global function + } + } + `) + ); + }); + }); diff --git a/openrewrite/test/javascript/parser/variableDeclarations.test.ts b/openrewrite/test/javascript/parser/variableDeclarations.test.ts index f2ab59f..2d7be9b 100644 --- a/openrewrite/test/javascript/parser/variableDeclarations.test.ts +++ b/openrewrite/test/javascript/parser/variableDeclarations.test.ts @@ -169,4 +169,13 @@ describe('variable declaration mapping', () => { `), ); }); + + test('variable with exclamation token', () => { + rewriteRun( + //language=typescript + typeScript(` + let schema/*a*/!/*b*/: number; + `) + ); + }); }); 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 442961b..cfc53a7 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 @@ -327,6 +327,7 @@ public JS.PropertyAssignment visitPropertyAssignment(JS.PropertyAssignment prope propertyAssignment = propertyAssignment.withPrefix(ctx.receiveNonNullNode(propertyAssignment.getPrefix(), JavaScriptReceiver::receiveSpace)); propertyAssignment = propertyAssignment.withMarkers(ctx.receiveNonNullNode(propertyAssignment.getMarkers(), ctx::receiveMarkers)); propertyAssignment = propertyAssignment.getPadding().withName(ctx.receiveNonNullNode(propertyAssignment.getPadding().getName(), JavaScriptReceiver::receiveRightPaddedTree)); + propertyAssignment = propertyAssignment.withAssigmentToken(ctx.receiveNonNullValue(propertyAssignment.getAssigmentToken(), JS.PropertyAssignment.AssigmentToken.class)); propertyAssignment = propertyAssignment.withInitializer(ctx.receiveNode(propertyAssignment.getInitializer(), ctx::receiveTree)); return propertyAssignment; } @@ -1863,6 +1864,7 @@ private static JS.PropertyAssignment createJSPropertyAssignment(ReceiverContext ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveSpace), ctx.receiveNonNullNode(null, ctx::receiveMarkers), ctx.receiveNonNullNode(null, JavaScriptReceiver::receiveRightPaddedTree), + ctx.receiveNonNullValue(null, JS.PropertyAssignment.AssigmentToken.class), ctx.receiveNode(null, ctx::receiveTree) ); } 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 f0c292f..bc0e009 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 @@ -309,6 +309,7 @@ public JS.PropertyAssignment visitPropertyAssignment(JS.PropertyAssignment prope ctx.sendNode(propertyAssignment, JS.PropertyAssignment::getPrefix, JavaScriptSender::sendSpace); ctx.sendNode(propertyAssignment, JS.PropertyAssignment::getMarkers, ctx::sendMarkers); ctx.sendNode(propertyAssignment, e -> e.getPadding().getName(), JavaScriptSender::sendRightPadded); + ctx.sendValue(propertyAssignment, JS.PropertyAssignment::getAssigmentToken); ctx.sendNode(propertyAssignment, JS.PropertyAssignment::getInitializer, ctx::sendTree); return propertyAssignment; } diff --git a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java index 39aa943..e98c3a6 100644 --- a/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java +++ b/rewrite-javascript-remote/src/main/java/org/openrewrite/javascript/remote/JavaScriptValidator.java @@ -455,7 +455,7 @@ public JS.ExportAssignment visitExportAssignment(JS.ExportAssignment exportAssig @Override public JS.NamedExports visitNamedExports(JS.NamedExports namedExports, P p) { - visitAndValidate(namedExports.getElements(), JS.ExportSpecifier.class, p); + visitAndValidate(namedExports.getElements(), Expression.class, p); return namedExports; } 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 208be2f..5953b1e 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 @@ -366,7 +366,11 @@ public J visitPropertyAssignment(JS.PropertyAssignment propertyAssignment, Print if (propertyAssignment.getInitializer() != null) { // if property is not null, we should print it like `{ a: b }` // otherwise it is a shorthanded assignment where we have stuff like `{ a }` only - p.append(':'); + if (propertyAssignment.getAssigmentToken() == JS.PropertyAssignment.AssigmentToken.Colon) { + p.append(':'); + } else if (propertyAssignment.getAssigmentToken() == JS.PropertyAssignment.AssigmentToken.Equals) { + p.append('='); + } visit(propertyAssignment.getInitializer(), p); } @@ -386,6 +390,8 @@ public J visitNamespaceDeclaration(JS.NamespaceDeclaration namespaceDeclaration, case Module: p.append("module"); break; + default: + break; } this.visitRightPadded(namespaceDeclaration.getPadding().getName(), JsRightPadded.Location.NAMESPACE_DECLARATION_NAME, p); if (namespaceDeclaration.getBody() != null) { 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 79df080..b69714a 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 @@ -2028,6 +2028,9 @@ public PropertyAssignment withName(Expression property) { return getPadding().withName(JRightPadded.withElement(this.name, property)); } + @With + AssigmentToken assigmentToken; + @With @Nullable Expression initializer; @@ -2040,7 +2043,7 @@ public PropertyAssignment withName(Expression property) { @SuppressWarnings("unchecked") @Override public PropertyAssignment withType(@Nullable JavaType type) { - return initializer.getType() == type ? this : new PropertyAssignment(id, prefix, markers, name, initializer.withType(type)); + return initializer.getType() == type ? this : new PropertyAssignment(id, prefix, markers, name, assigmentToken, initializer.withType(type)); } @Override @@ -2048,6 +2051,12 @@ public

J acceptJavaScript(JavaScriptVisitor

v, P p) { return v.visitPropertyAssignment(this, p); } + public enum AssigmentToken { + Colon, + Equals, + Empty + } + public Padding getPadding() { Padding p; if (this.padding == null) { @@ -2083,9 +2092,8 @@ public JRightPadded getName() { } public PropertyAssignment withName(JRightPadded target) { - return t.name == target ? t : new PropertyAssignment(t.id, t.prefix, t.markers, target, t.initializer); + return t.name == target ? t : new PropertyAssignment(t.id, t.prefix, t.markers, target, t.assigmentToken, t.initializer); } - } } @@ -4196,6 +4204,7 @@ public NamespaceDeclaration.Padding getPadding() { public enum KeywordType { Namespace, Module, + Empty } @RequiredArgsConstructor @@ -4885,13 +4894,13 @@ final class NamedExports implements JS, Expression { @Getter Markers markers; - JContainer elements; + JContainer elements; - public List getElements() { + public List getElements() { return elements.getElements(); } - public NamedExports withElements(List elements) { + public NamedExports withElements(List elements) { return getPadding().withElements(JContainer.withElements(this.elements, elements)); } @@ -4929,11 +4938,11 @@ public NamedExports.Padding getPadding() { public static class Padding { private final NamedExports t; - public JContainer getElements() { + public JContainer getElements() { return t.elements; } - public NamedExports withElements(JContainer elements) { + public NamedExports withElements(JContainer elements) { return t.elements == elements ? t : new NamedExports(t.id, t.prefix, t.markers, elements, t.type); } }