diff --git a/openrewrite/src/javascript/parser.ts b/openrewrite/src/javascript/parser.ts index fd372547..4f7e30cd 100644 --- a/openrewrite/src/javascript/parser.ts +++ b/openrewrite/src/javascript/parser.ts @@ -1686,15 +1686,20 @@ export class JavaScriptParserVisitor { ) ): null, node.questionToken ? this.leftPadded(this.prefix(this.findChildNode(node, ts.SyntaxKind.QuestionToken)!), true) : this.leftPadded(Space.EMPTY, false), - new JContainer( + node.type ? new JContainer( this.prefix(this.findChildNode(node, ts.SyntaxKind.ColonToken)!), - [this.rightPadded(this.visit(node.type!), this.suffix(node.type!)), + [this.rightPadded(this.visit(node.type), this.suffix(node.type)), this.findChildNode(node, ts.SyntaxKind.SemicolonToken) ? this.rightPadded(this.newJEmpty(Space.EMPTY, Markers.build([new Semicolon(randomId())])), this.prefix(node.getLastToken()!)) : this.rightPadded(this.newJEmpty(), this.prefix(node.getLastToken()!)) ], Markers.EMPTY - ), + ) : new JContainer( + Space.EMPTY, + [this.findChildNode(node, ts.SyntaxKind.SemicolonToken) ? + this.rightPadded(this.newJEmpty(this.prefix(this.findChildNode(node, ts.SyntaxKind.SemicolonToken)!), Markers.build([new Semicolon(randomId())])), this.prefix(node.getLastToken()!)) + : this.rightPadded(this.newJEmpty(), this.prefix(node.getLastToken()!)) + ], Markers.EMPTY), this.mapType(node) ); } @@ -3606,7 +3611,7 @@ export class JavaScriptParserVisitor { visitImportAttributes(node: ts.ImportAttributes) { const openBraceIndex = node.getChildren().findIndex(n => n.kind === ts.SyntaxKind.OpenBraceToken); - const elements = this.mapCommaSeparatedList(node.getChildren(this.sourceFile).slice(openBraceIndex, openBraceIndex + 3)); + const elements = this.mapCommaSeparatedList(node.getChildren(this.sourceFile).slice(openBraceIndex, openBraceIndex + 3)); return new JS.ImportAttributes( randomId(), this.prefix(node), diff --git a/openrewrite/src/javascript/remote/receiver.ts b/openrewrite/src/javascript/remote/receiver.ts index f16f57aa..45f9dc17 100644 --- a/openrewrite/src/javascript/remote/receiver.ts +++ b/openrewrite/src/javascript/remote/receiver.ts @@ -1630,7 +1630,7 @@ class Factory implements ReceiverFactory { ctx.receiveNode(null, receiveSpace)!, ctx.receiveNode(null, ctx.receiveMarkers)!, ctx.receiveValue(null, ValueType.Enum)!, - ctx.receiveNode>(null, receiveContainer)! + ctx.receiveNode>(null, receiveContainer)! ); } diff --git a/openrewrite/src/javascript/tree/tree.ts b/openrewrite/src/javascript/tree/tree.ts index 50e57c11..e27ef4c7 100644 --- a/openrewrite/src/javascript/tree/tree.ts +++ b/openrewrite/src/javascript/tree/tree.ts @@ -1683,7 +1683,7 @@ export class JsImportSpecifier extends JSMixin(Object) implements Expression, Ty @LstType("org.openrewrite.javascript.tree.JS$ImportAttributes") export class ImportAttributes extends JSMixin(Object) { - public constructor(id: UUID, prefix: Space, markers: Markers, token: ImportAttributes.Token, elements: JContainer) { + public constructor(id: UUID, prefix: Space, markers: Markers, token: ImportAttributes.Token, elements: JContainer) { super(); this._id = id; this._prefix = prefix; @@ -1732,13 +1732,13 @@ export class ImportAttributes extends JSMixin(Object) { return token === this._token ? this : new ImportAttributes(this._id, this._prefix, this._markers, token, this._elements); } - private readonly _elements: JContainer; + private readonly _elements: JContainer; - public get elements(): ImportAttribute[] { + public get elements(): Statement[] { return this._elements.elements; } - public withElements(elements: ImportAttribute[]): ImportAttributes { + public withElements(elements: Statement[]): ImportAttributes { return this.padding.withElements(JContainer.withElements(this._elements, elements)); } @@ -1749,10 +1749,10 @@ export class ImportAttributes extends JSMixin(Object) { get padding() { const t = this; return new class { - public get elements(): JContainer { + public get elements(): JContainer { return t._elements; } - public withElements(elements: JContainer): ImportAttributes { + public withElements(elements: JContainer): ImportAttributes { return t._elements === elements ? t : new ImportAttributes(t._id, t._prefix, t._markers, t._token, elements); } } @@ -1866,7 +1866,7 @@ export class ImportTypeAttributes extends JSMixin(Object) { } @LstType("org.openrewrite.javascript.tree.JS$ImportAttribute") -export class ImportAttribute extends JSMixin(Object) { +export class ImportAttribute extends JSMixin(Object) implements Statement { public constructor(id: UUID, prefix: Space, markers: Markers, name: Expression, value: JLeftPadded) { super(); this._id = id; diff --git a/openrewrite/src/javascript/visitor.ts b/openrewrite/src/javascript/visitor.ts index fabc161f..1582fb0e 100644 --- a/openrewrite/src/javascript/visitor.ts +++ b/openrewrite/src/javascript/visitor.ts @@ -289,6 +289,12 @@ export class JavaScriptVisitor

extends JavaVisitor

{ public visitImportAttribute(importAttribute: ImportAttribute, p: P): J | null { importAttribute = importAttribute.withPrefix(this.visitJsSpace(importAttribute.prefix, JsSpace.Location.IMPORT_ATTRIBUTE_PREFIX, p)!); + let tempStatement = this.visitStatement(importAttribute, p) as Statement; + if (!(tempStatement instanceof ImportAttribute)) + { + return tempStatement; + } + importAttribute = tempStatement as ImportAttribute; importAttribute = importAttribute.withMarkers(this.visitMarkers(importAttribute.markers, p)); importAttribute = importAttribute.withName(this.visitAndCast(importAttribute.name, p)!); importAttribute = importAttribute.padding.withValue(this.visitJsLeftPadded(importAttribute.padding.value, JsLeftPadded.Location.IMPORT_ATTRIBUTE_VALUE, p)!); diff --git a/openrewrite/test/javascript/parser/export.test.ts b/openrewrite/test/javascript/parser/export.test.ts index 815df363..1b9bda00 100644 --- a/openrewrite/test/javascript/parser/export.test.ts +++ b/openrewrite/test/javascript/parser/export.test.ts @@ -178,6 +178,21 @@ describe('export keyword tests', () => { `) ); }); + + test('export/import with empty attributes', () => { + rewriteRun( + //language=typescript + typeScript(` + export * as foo from "foo.json" + export * as bar from "bar.json" assert { } + export * as baz from "baz.json" assert { /* comment */ } + + import * as foo from "foo.json" + import * as bar from "bar.json" assert { } + import * as baz from "baz.json" assert { /* comment */ } + `) + ); + }); }); diff --git a/openrewrite/test/javascript/parser/mappedType.test.ts b/openrewrite/test/javascript/parser/mappedType.test.ts index 2a1164ec..2e696008 100644 --- a/openrewrite/test/javascript/parser/mappedType.test.ts +++ b/openrewrite/test/javascript/parser/mappedType.test.ts @@ -176,4 +176,28 @@ describe('mapped type mapping', () => { ); }); + test('no node type ', () => { + rewriteRun( + //language=typescript + typeScript(` + type Type = { + // comment + readonly [T in number] /*a*/ + }; + `) + ); + }); + + test('no node type with ;', () => { + rewriteRun( + //language=typescript + typeScript(` + type Type = { + // comment + readonly [T in number] /*a*/;/*b*/ + }; + `) + ); + }); + }); 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 2502226e..f0c3fae9 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 @@ -189,7 +189,7 @@ public JS.JsImportSpecifier visitJsImportSpecifier(JS.JsImportSpecifier jsImport @Override public JS.ImportAttributes visitImportAttributes(JS.ImportAttributes importAttributes, P p) { - visitAndValidate(importAttributes.getElements(), JS.ImportAttribute.class, p); + visitAndValidate(importAttributes.getElements(), Statement.class, p); return importAttributes; } 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 2012fe2a..caa63fa4 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 @@ -531,7 +531,8 @@ public J visitMappedType(JS.MappedType mappedType, PrintOutputCapture

p) { visitLeftPaddedBoolean("?", mappedType.getPadding().getHasQuestionToken(), JsLeftPadded.Location.MAPPED_TYPE_QUESTION_TOKEN, p); } - visitContainer(":", mappedType.getPadding().getValueType(), JsContainer.Location.MAPPED_TYPE_VALUE_TYPE, "", "", p); + String colon = mappedType.getValueType().get(0) instanceof J.Empty ? "" : ":"; + visitContainer(colon, mappedType.getPadding().getValueType(), JsContainer.Location.MAPPED_TYPE_VALUE_TYPE, "", "", p); p.append("}"); afterSyntax(mappedType, p); 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 6cf68ad6..2ea5b147 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 @@ -1636,13 +1636,13 @@ final class ImportAttributes implements JS { @Getter Token token; - JContainer elements; + JContainer elements; - public List getElements() { + public List getElements() { return elements.getElements(); } - public ImportAttributes withElements(List elements) { + public ImportAttributes withElements(List elements) { return getPadding().withElements(JContainer.withElements(this.elements, elements)); } @@ -1675,11 +1675,11 @@ public Padding getPadding() { public static class Padding { private final ImportAttributes t; - public JContainer getElements() { + public JContainer getElements() { return t.elements; } - public ImportAttributes withElements(JContainer elements) { + public ImportAttributes withElements(JContainer elements) { return t.elements == elements ? t : new ImportAttributes(t.id, t.prefix, t.markers, t.token, elements); } } @@ -1777,7 +1777,7 @@ public ImportTypeAttributes withElements(JContainer elements) { @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) - final class ImportAttribute implements JS { + final class ImportAttribute implements JS, Statement { @Nullable @NonFinal transient WeakReference padding; @@ -1829,6 +1829,11 @@ public Padding getPadding() { return p; } + @Override + public CoordinateBuilder.Statement getCoordinates() { + return new CoordinateBuilder.Statement(this); + } + @RequiredArgsConstructor public static class Padding { private final ImportAttribute t;