Skip to content
This repository was archived by the owner on May 12, 2025. It is now read-only.

Commit 620ba5d

Browse files
authored
rework jsimport to reflect AST structure and fix remaining gaps (#194)
* rework jsimport to reflect AST structure and fix remaining gaps * polish
1 parent f127983 commit 620ba5d

File tree

21 files changed

+1236
-395
lines changed

21 files changed

+1236
-395
lines changed

openrewrite/src/java/remote/receiver.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
22
import {Checksum, Cursor, FileAttributes, ListUtils, Tree} from '../../core';
33
import {DetailsReceiver, Receiver, ReceiverContext, ReceiverFactory, ValueType} from '@openrewrite/rewrite-remote';
44
import {JavaVisitor} from '..';
5-
import {J, Comment, Expression, JavaSourceFile, JavaType, JContainer, JLeftPadded, JRightPadded, Loop, MethodCall, NameTree, Space, Statement, TextComment, TypedTree, TypeTree, AnnotatedType, Annotation, ArrayAccess, ArrayType, Assert, Assignment, AssignmentOperation, Binary, Block, Break, Case, ClassDeclaration, CompilationUnit, Continue, DoWhileLoop, Empty, EnumValue, EnumValueSet, FieldAccess, ForEachLoop, ForLoop, ParenthesizedTypeTree, Identifier, If, Import, InstanceOf, IntersectionType, Label, Lambda, Literal, MemberReference, MethodDeclaration, MethodInvocation, Modifier, MultiCatch, NewArray, ArrayDimension, NewClass, NullableType, Package, ParameterizedType, Parentheses, ControlParentheses, Primitive, Return, Switch, SwitchExpression, Synchronized, Ternary, Throw, Try, TypeCast, TypeParameter, TypeParameters, Unary, VariableDeclarations, WhileLoop, Wildcard, Yield, Unknown, Erroneous} from '../tree';
5+
import {J, Comment, Expression, JavaSourceFile, JavaType, JContainer, JLeftPadded, JRightPadded, Loop, MethodCall, NameTree, Space, Statement, TextComment, TypedTree, TypeTree, AnnotatedType, Annotation, ArrayAccess, ArrayType, Assert, Assignment, AssignmentOperation, Binary, Block, Break, Case, ClassDeclaration, CompilationUnit, Continue, DoWhileLoop, Empty, EnumValue, EnumValueSet, FieldAccess, ForEachLoop, ForLoop, ParenthesizedTypeTree, Identifier, If, Import, InstanceOf, IntersectionType, Label, Lambda, Literal, MemberReference, MethodDeclaration, MethodInvocation, Modifier, MultiCatch, NewArray, ArrayDimension, NewClass, NullableType, Package, ParameterizedType, Parentheses, ControlParentheses, Primitive, Return, Switch, SwitchExpression, Synchronized, Ternary, Throw, Try, TypeCast, TypeParameter, TypeParameters, Unary, VariableDeclarations, WhileLoop, Wildcard, Yield, Unknown} from '../tree';
66
import * as Java from "../../java/tree";
77

88
export class JavaReceiver implements Receiver<J> {
@@ -708,14 +708,6 @@ class Visitor extends JavaVisitor<ReceiverContext> {
708708
return source;
709709
}
710710

711-
public visitErroneous(erroneous: Erroneous, ctx: ReceiverContext): J {
712-
erroneous = erroneous.withId(ctx.receiveValue(erroneous.id, ValueType.UUID)!);
713-
erroneous = erroneous.withPrefix(ctx.receiveNode(erroneous.prefix, receiveSpace)!);
714-
erroneous = erroneous.withMarkers(ctx.receiveNode(erroneous.markers, ctx.receiveMarkers)!);
715-
erroneous = erroneous.withText(ctx.receiveValue(erroneous.text, ValueType.Primitive)!);
716-
return erroneous;
717-
}
718-
719711
}
720712

721713
class Factory implements ReceiverFactory {
@@ -1471,15 +1463,6 @@ class Factory implements ReceiverFactory {
14711463
);
14721464
}
14731465

1474-
if (type === "org.openrewrite.java.tree.J$Erroneous") {
1475-
return new Erroneous(
1476-
ctx.receiveValue(null, ValueType.UUID)!,
1477-
ctx.receiveNode(null, receiveSpace)!,
1478-
ctx.receiveNode(null, ctx.receiveMarkers)!,
1479-
ctx.receiveValue(null, ValueType.Primitive)!
1480-
);
1481-
}
1482-
14831466
throw new Error("No factory method for type: " + type);
14841467
}
14851468
}

openrewrite/src/java/remote/sender.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as extensions from "./remote_extensions";
22
import {Cursor, ListUtils, Tree} from '../../core';
33
import {Sender, SenderContext, ValueType} from '@openrewrite/rewrite-remote';
44
import {JavaVisitor} from '..';
5-
import {J, Comment, Expression, JavaSourceFile, JavaType, JContainer, JLeftPadded, JRightPadded, Loop, MethodCall, NameTree, Space, Statement, TextComment, TypedTree, TypeTree, AnnotatedType, Annotation, ArrayAccess, ArrayType, Assert, Assignment, AssignmentOperation, Binary, Block, Break, Case, ClassDeclaration, CompilationUnit, Continue, DoWhileLoop, Empty, EnumValue, EnumValueSet, FieldAccess, ForEachLoop, ForLoop, ParenthesizedTypeTree, Identifier, If, Import, InstanceOf, IntersectionType, Label, Lambda, Literal, MemberReference, MethodDeclaration, MethodInvocation, Modifier, MultiCatch, NewArray, ArrayDimension, NewClass, NullableType, Package, ParameterizedType, Parentheses, ControlParentheses, Primitive, Return, Switch, SwitchExpression, Synchronized, Ternary, Throw, Try, TypeCast, TypeParameter, TypeParameters, Unary, VariableDeclarations, WhileLoop, Wildcard, Yield, Unknown, Erroneous} from '../tree';
5+
import {J, Comment, Expression, JavaSourceFile, JavaType, JContainer, JLeftPadded, JRightPadded, Loop, MethodCall, NameTree, Space, Statement, TextComment, TypedTree, TypeTree, AnnotatedType, Annotation, ArrayAccess, ArrayType, Assert, Assignment, AssignmentOperation, Binary, Block, Break, Case, ClassDeclaration, CompilationUnit, Continue, DoWhileLoop, Empty, EnumValue, EnumValueSet, FieldAccess, ForEachLoop, ForLoop, ParenthesizedTypeTree, Identifier, If, Import, InstanceOf, IntersectionType, Label, Lambda, Literal, MemberReference, MethodDeclaration, MethodInvocation, Modifier, MultiCatch, NewArray, ArrayDimension, NewClass, NullableType, Package, ParameterizedType, Parentheses, ControlParentheses, Primitive, Return, Switch, SwitchExpression, Synchronized, Ternary, Throw, Try, TypeCast, TypeParameter, TypeParameters, Unary, VariableDeclarations, WhileLoop, Wildcard, Yield, Unknown} from '../tree';
66
import * as Java from "../../java/tree";
77

88
export class JavaSender implements Sender<J> {
@@ -708,14 +708,6 @@ class Visitor extends JavaVisitor<SenderContext> {
708708
return source;
709709
}
710710

711-
public visitErroneous(erroneous: Erroneous, ctx: SenderContext): J {
712-
ctx.sendValue(erroneous, v => v.id, ValueType.UUID);
713-
ctx.sendNode(erroneous, v => v.prefix, Visitor.sendSpace);
714-
ctx.sendNode(erroneous, v => v.markers, ctx.sendMarkers);
715-
ctx.sendValue(erroneous, v => v.text, ValueType.Primitive);
716-
return erroneous;
717-
}
718-
719711
private static sendContainer<T>(type: ValueType): (container: JContainer<T>, ctx: SenderContext) => void {
720712
return extensions.sendContainer(type);
721713
}

openrewrite/src/java/tree/tree.ts

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6320,67 +6320,3 @@ export namespace Unknown {
63206320
}
63216321

63226322
}
6323-
6324-
@LstType("org.openrewrite.java.tree.J$Erroneous")
6325-
export class Erroneous extends JMixin(Object) implements Statement, Expression {
6326-
public constructor(id: UUID, prefix: Space, markers: Markers, text: string) {
6327-
super();
6328-
this._id = id;
6329-
this._prefix = prefix;
6330-
this._markers = markers;
6331-
this._text = text;
6332-
}
6333-
6334-
private readonly _id: UUID;
6335-
6336-
public get id(): UUID {
6337-
return this._id;
6338-
}
6339-
6340-
public withId(id: UUID): Erroneous {
6341-
return id === this._id ? this : new Erroneous(id, this._prefix, this._markers, this._text);
6342-
}
6343-
6344-
private readonly _prefix: Space;
6345-
6346-
public get prefix(): Space {
6347-
return this._prefix;
6348-
}
6349-
6350-
public withPrefix(prefix: Space): Erroneous {
6351-
return prefix === this._prefix ? this : new Erroneous(this._id, prefix, this._markers, this._text);
6352-
}
6353-
6354-
private readonly _markers: Markers;
6355-
6356-
public get markers(): Markers {
6357-
return this._markers;
6358-
}
6359-
6360-
public withMarkers(markers: Markers): Erroneous {
6361-
return markers === this._markers ? this : new Erroneous(this._id, this._prefix, markers, this._text);
6362-
}
6363-
6364-
private readonly _text: string;
6365-
6366-
public get text(): string {
6367-
return this._text;
6368-
}
6369-
6370-
public withText(text: string): Erroneous {
6371-
return text === this._text ? this : new Erroneous(this._id, this._prefix, this._markers, text);
6372-
}
6373-
6374-
public acceptJava<P>(v: JavaVisitor<P>, p: P): J | null {
6375-
return v.visitErroneous(this, p);
6376-
}
6377-
6378-
public get type(): JavaType | null {
6379-
return extensions.getJavaType(this);
6380-
}
6381-
6382-
public withType(type: JavaType): Erroneous {
6383-
return extensions.withJavaType(this, type);
6384-
}
6385-
6386-
}

openrewrite/src/java/visitor.ts

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as extensions from "./extensions";
22
import {ListUtils, SourceFile, Tree, TreeVisitor} from "../core";
33
import {J, isJava, Comment, Expression, JavaSourceFile, JavaType, JContainer, JLeftPadded, JRightPadded, Loop, MethodCall, NameTree, Space, Statement, TextComment, TypedTree, TypeTree} from "./tree";
4-
import {AnnotatedType, Annotation, ArrayAccess, ArrayType, Assert, Assignment, AssignmentOperation, Binary, Block, Break, Case, ClassDeclaration, CompilationUnit, Continue, DoWhileLoop, Empty, EnumValue, EnumValueSet, FieldAccess, ForEachLoop, ForLoop, ParenthesizedTypeTree, Identifier, If, Import, InstanceOf, IntersectionType, Label, Lambda, Literal, MemberReference, MethodDeclaration, MethodInvocation, Modifier, MultiCatch, NewArray, ArrayDimension, NewClass, NullableType, Package, ParameterizedType, Parentheses, ControlParentheses, Primitive, Return, Switch, SwitchExpression, Synchronized, Ternary, Throw, Try, TypeCast, TypeParameter, TypeParameters, Unary, VariableDeclarations, WhileLoop, Wildcard, Yield, Unknown, Erroneous} from "./tree";
4+
import {AnnotatedType, Annotation, ArrayAccess, ArrayType, Assert, Assignment, AssignmentOperation, Binary, Block, Break, Case, ClassDeclaration, CompilationUnit, Continue, DoWhileLoop, Empty, EnumValue, EnumValueSet, FieldAccess, ForEachLoop, ForLoop, ParenthesizedTypeTree, Identifier, If, Import, InstanceOf, IntersectionType, Label, Lambda, Literal, MemberReference, MethodDeclaration, MethodInvocation, Modifier, MultiCatch, NewArray, ArrayDimension, NewClass, NullableType, Package, ParameterizedType, Parentheses, ControlParentheses, Primitive, Return, Switch, SwitchExpression, Synchronized, Ternary, Throw, Try, TypeCast, TypeParameter, TypeParameters, Unary, VariableDeclarations, WhileLoop, Wildcard, Yield, Unknown} from "./tree";
55

66
export class JavaVisitor<P> extends TreeVisitor<J, P> {
77
isAcceptable(sourceFile: SourceFile, p: P): boolean {
@@ -965,24 +965,6 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
965965
return source;
966966
}
967967

968-
public visitErroneous(erroneous: Erroneous, p: P): J | null {
969-
erroneous = erroneous.withPrefix(this.visitSpace(erroneous.prefix, Space.Location.ERRONEOUS_PREFIX, p)!);
970-
let tempStatement = this.visitStatement(erroneous, p) as Statement;
971-
if (!(tempStatement instanceof Erroneous))
972-
{
973-
return tempStatement;
974-
}
975-
erroneous = tempStatement as Erroneous;
976-
let tempExpression = this.visitExpression(erroneous, p) as Expression;
977-
if (!(tempExpression instanceof Erroneous))
978-
{
979-
return tempExpression;
980-
}
981-
erroneous = tempExpression as Erroneous;
982-
erroneous = erroneous.withMarkers(this.visitMarkers(erroneous.markers, p));
983-
return erroneous;
984-
}
985-
986968
public visitContainer<T>(container: JContainer<T> | null, loc: JContainer.Location, p: P): JContainer<T> | null {
987969
return extensions.visitContainer(this, container, loc, p);
988970
}

openrewrite/src/javascript/parser.ts

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,12 @@ export class JavaScriptParserVisitor {
293293
| ts.FunctionDeclaration | ts.ParameterDeclaration | ts.MethodDeclaration | ts.EnumDeclaration | ts.InterfaceDeclaration
294294
| ts.PropertySignature | ts.ConstructorDeclaration | ts.ModuleDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration
295295
| ts.ArrowFunction | ts.IndexSignatureDeclaration | ts.TypeAliasDeclaration | ts.ExportDeclaration | ts.ExportAssignment | ts.FunctionExpression
296-
| ts.ConstructorTypeNode | ts.TypeParameterDeclaration) {
296+
| ts.ConstructorTypeNode | ts.TypeParameterDeclaration | ts.ImportDeclaration | ts.ImportEqualsDeclaration) {
297297
if (ts.isVariableStatement(node) || ts.isModuleDeclaration(node) || ts.isClassDeclaration(node) || ts.isEnumDeclaration(node)
298298
|| ts.isInterfaceDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isParameter(node)
299299
|| ts.isMethodDeclaration(node) || ts.isConstructorDeclaration(node) || ts.isArrowFunction(node)
300300
|| ts.isIndexSignatureDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isExportDeclaration(node)
301-
|| ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isConstructorTypeNode(node) || ts.isTypeParameterDeclaration(node)) {
301+
|| ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isConstructorTypeNode(node) || ts.isTypeParameterDeclaration(node) || ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node)) {
302302
return node.modifiers ? node.modifiers?.filter(ts.isModifier).map(this.mapModifier) : [];
303303
}
304304
else if (ts.isExportAssignment(node)) {
@@ -3214,7 +3214,46 @@ export class JavaScriptParserVisitor {
32143214
}
32153215

32163216
visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) {
3217-
return this.visitUnknown(node);
3217+
const kind = this.findChildNode(node, ts.SyntaxKind.ImportKeyword)!;
3218+
3219+
return new JS.ScopedVariableDeclarations(
3220+
randomId(),
3221+
this.prefix(node),
3222+
Markers.EMPTY,
3223+
this.mapModifiers(node),
3224+
this.leftPadded(
3225+
this.prefix(kind),
3226+
JS.ScopedVariableDeclarations.Scope.Import
3227+
),
3228+
[
3229+
this.rightPadded(new J.VariableDeclarations(
3230+
randomId(),
3231+
Space.EMPTY,
3232+
Markers.EMPTY,
3233+
[],
3234+
node.isTypeOnly ? [new J.Modifier(
3235+
randomId(),
3236+
this.prefix(this.findChildNode(node, ts.SyntaxKind.TypeKeyword)!),
3237+
Markers.EMPTY,
3238+
"type",
3239+
J.Modifier.Type.LanguageExtension,
3240+
[]
3241+
)] : [],
3242+
null,
3243+
null,
3244+
[],
3245+
[this.rightPadded(new J.VariableDeclarations.NamedVariable(
3246+
randomId(),
3247+
Space.EMPTY,
3248+
Markers.EMPTY,
3249+
this.visit(node.name),
3250+
[],
3251+
this.leftPadded(this.suffix(node.name), this.visit(node.moduleReference)),
3252+
this.mapVariableType(node)
3253+
), Space.EMPTY)]
3254+
), Space.EMPTY)
3255+
]
3256+
)
32183257
}
32193258

32203259
visitImportKeyword(node: ts.ImportExpression) {
@@ -3223,46 +3262,46 @@ export class JavaScriptParserVisitor {
32233262
}
32243263

32253264
visitImportDeclaration(node: ts.ImportDeclaration) {
3226-
const children = node.getChildren(this.sourceFile);
3227-
const _default = !!node.importClause?.name;
3228-
const onlyDefault = _default && node.importClause.namedBindings == undefined;
32293265
return new JS.JsImport(
32303266
randomId(),
32313267
this.prefix(node),
32323268
Markers.EMPTY,
3233-
_default ? this.rightPadded(this.visit(node.importClause?.name), this.suffix(node.importClause?.name)) : null,
3234-
node.importClause?.isTypeOnly ? this.leftPadded(this.prefix(this.findChildNode(node.importClause, ts.SyntaxKind.TypeKeyword)!), node.importClause.isTypeOnly) : this.leftPadded(Space.EMPTY, false),
3235-
node.importClause && !onlyDefault ? this.visit(node.importClause) : null,
3236-
children[children.indexOf(node.moduleSpecifier) - 1].kind == ts.SyntaxKind.FromKeyword ? this.prefix(children[children.indexOf(node.moduleSpecifier) - 1]) : null,
3237-
this.convert<J.Literal>(node.moduleSpecifier),
3238-
null
3269+
this.mapModifiers(node),
3270+
node.importClause ? this.visit(node.importClause) : null,
3271+
this.leftPadded(node.importClause ? this.prefix(this.findChildNode(node, ts.SyntaxKind.FromKeyword)!) : Space.EMPTY, this.visit(node.moduleSpecifier)),
3272+
node.attributes ? this.visit(node.attributes) : null
32393273
);
32403274
}
32413275

32423276
visitImportClause(node: ts.ImportClause) {
3243-
if (node.namedBindings && ts.isNamespaceImport(node.namedBindings)) {
3244-
return new JContainer(
3245-
this.prefix(node),
3246-
[this.rightPadded(new JS.Alias(
3247-
randomId(),
3248-
Space.EMPTY,
3249-
Markers.EMPTY,
3250-
// this.rightPadded(node.isTypeOnly, node.isTypeOnly ? this.suffix(this.findChildNode(node, ts.SyntaxKind.TypeKeyword)!) : Space.EMPTY),
3251-
this.rightPadded(this.mapIdentifier(node.namedBindings, "*"), this.prefix(node.namedBindings.getChildAt(1, this.sourceFile))),
3252-
this.convert(node.namedBindings.name)
3253-
), Space.EMPTY)],
3254-
Markers.EMPTY
3255-
);
3256-
}
3257-
return this.mapCommaSeparatedList(node.namedBindings?.getChildren(this.sourceFile)!);
3277+
return new JS.JsImportClause(
3278+
randomId(),
3279+
this.prefix(node),
3280+
Markers.EMPTY,
3281+
node.isTypeOnly,
3282+
node.name ? this.rightPadded(this.visit(node.name), this.suffix(node.name)) : null,
3283+
node.namedBindings ? this.visit(node.namedBindings) : null
3284+
);
32583285
}
32593286

32603287
visitNamespaceImport(node: ts.NamespaceImport) {
3261-
return this.visitUnknown(node);
3288+
return new JS.Alias(
3289+
randomId(),
3290+
this.prefix(node),
3291+
Markers.EMPTY,
3292+
this.rightPadded(this.mapIdentifier(node, "*"), this.prefix(this.findChildNode(node, ts.SyntaxKind.AsKeyword)!)),
3293+
this.visit(node.name)
3294+
);
32623295
}
32633296

32643297
visitNamedImports(node: ts.NamedImports) {
3265-
return this.visitUnknown(node);
3298+
return new JS.NamedImports(
3299+
randomId(),
3300+
this.prefix(node),
3301+
Markers.EMPTY,
3302+
this.mapCommaSeparatedList(node.getChildren(this.sourceFile)),
3303+
null
3304+
);
32663305
}
32673306

32683307
visitImportSpecifier(node: ts.ImportSpecifier) {
@@ -3514,11 +3553,25 @@ export class JavaScriptParserVisitor {
35143553
}
35153554

35163555
visitImportAttributes(node: ts.ImportAttributes) {
3517-
return this.visitUnknown(node);
3556+
const openBraceIndex = node.getChildren().findIndex(n => n.kind === ts.SyntaxKind.OpenBraceToken);
3557+
const elements = this.mapCommaSeparatedList<JS.ImportAttribute>(node.getChildren(this.sourceFile).slice(openBraceIndex, openBraceIndex + 3));
3558+
return new JS.ImportAttributes(
3559+
randomId(),
3560+
this.prefix(node),
3561+
Markers.EMPTY,
3562+
ts.SyntaxKind.WithKeyword === node.token ? JS.ImportAttributes.Token.With : JS.ImportAttributes.Token.Assert,
3563+
elements
3564+
);
35183565
}
35193566

35203567
visitImportAttribute(node: ts.ImportAttribute) {
3521-
return this.visitUnknown(node);
3568+
return new JS.ImportAttribute(
3569+
randomId(),
3570+
this.prefix(node),
3571+
Markers.EMPTY,
3572+
this.visit(node.name),
3573+
this.leftPadded(this.suffix(node.name), this.visit(node.value))
3574+
);
35223575
}
35233576

35243577
visitPropertyAssignment(node: ts.PropertyAssignment) {

0 commit comments

Comments
 (0)