Skip to content

Commit

Permalink
Change model and printer to fix parse errors with ImportAttribute and…
Browse files Browse the repository at this point in the history
… MappedType (#205)

Co-authored-by: Andrii Rodionov <andriih@moderne.io>
  • Loading branch information
arodionov and Andrii Rodionov authored Feb 3, 2025
1 parent bfc57d6 commit 2454ee1
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 20 deletions.
13 changes: 9 additions & 4 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}
Expand Down Expand Up @@ -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<JS.ImportAttribute>(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),
Expand Down
2 changes: 1 addition & 1 deletion openrewrite/src/javascript/remote/receiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1630,7 +1630,7 @@ class Factory implements ReceiverFactory {
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveValue(null, ValueType.Enum)!,
ctx.receiveNode<JContainer<ImportAttribute>>(null, receiveContainer)!
ctx.receiveNode<JContainer<Statement>>(null, receiveContainer)!
);
}

Expand Down
14 changes: 7 additions & 7 deletions openrewrite/src/javascript/tree/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ImportAttribute>) {
public constructor(id: UUID, prefix: Space, markers: Markers, token: ImportAttributes.Token, elements: JContainer<Statement>) {
super();
this._id = id;
this._prefix = prefix;
Expand Down Expand Up @@ -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<ImportAttribute>;
private readonly _elements: JContainer<Statement>;

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));
}

Expand All @@ -1749,10 +1749,10 @@ export class ImportAttributes extends JSMixin(Object) {
get padding() {
const t = this;
return new class {
public get elements(): JContainer<ImportAttribute> {
public get elements(): JContainer<Statement> {
return t._elements;
}
public withElements(elements: JContainer<ImportAttribute>): ImportAttributes {
public withElements(elements: JContainer<Statement>): ImportAttributes {
return t._elements === elements ? t : new ImportAttributes(t._id, t._prefix, t._markers, t._token, elements);
}
}
Expand Down Expand Up @@ -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<Expression>) {
super();
this._id = id;
Expand Down
6 changes: 6 additions & 0 deletions openrewrite/src/javascript/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {

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)!);
Expand Down
15 changes: 15 additions & 0 deletions openrewrite/test/javascript/parser/export.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */ }
`)
);
});
});


24 changes: 24 additions & 0 deletions openrewrite/test/javascript/parser/mappedType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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*/
};
`)
);
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,8 @@ public J visitMappedType(JS.MappedType mappedType, PrintOutputCapture<P> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1636,13 +1636,13 @@ final class ImportAttributes implements JS {
@Getter
Token token;

JContainer<ImportAttribute> elements;
JContainer<Statement> elements;

public List<ImportAttribute> getElements() {
public List<Statement> getElements() {
return elements.getElements();
}

public ImportAttributes withElements(List<ImportAttribute> elements) {
public ImportAttributes withElements(List<Statement> elements) {
return getPadding().withElements(JContainer.withElements(this.elements, elements));
}

Expand Down Expand Up @@ -1675,11 +1675,11 @@ public Padding getPadding() {
public static class Padding {
private final ImportAttributes t;

public JContainer<ImportAttribute> getElements() {
public JContainer<Statement> getElements() {
return t.elements;
}

public ImportAttributes withElements(JContainer<ImportAttribute> elements) {
public ImportAttributes withElements(JContainer<Statement> elements) {
return t.elements == elements ? t : new ImportAttributes(t.id, t.prefix, t.markers, t.token, elements);
}
}
Expand Down Expand Up @@ -1777,7 +1777,7 @@ public ImportTypeAttributes withElements(JContainer<ImportAttribute> 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> padding;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 2454ee1

Please # to comment.