Skip to content

Commit

Permalink
rework jsimport to reflect AST structure and fix remaining gaps (#194)
Browse files Browse the repository at this point in the history
* rework jsimport to reflect AST structure and fix remaining gaps

* polish
  • Loading branch information
OlegDokuka authored Jan 14, 2025
1 parent f127983 commit 620ba5d
Show file tree
Hide file tree
Showing 21 changed files with 1,236 additions and 395 deletions.
19 changes: 1 addition & 18 deletions openrewrite/src/java/remote/receiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {JavaVisitor} from '..';
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';
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';
import * as Java from "../../java/tree";

export class JavaReceiver implements Receiver<J> {
Expand Down Expand Up @@ -708,14 +708,6 @@ class Visitor extends JavaVisitor<ReceiverContext> {
return source;
}

public visitErroneous(erroneous: Erroneous, ctx: ReceiverContext): J {
erroneous = erroneous.withId(ctx.receiveValue(erroneous.id, ValueType.UUID)!);
erroneous = erroneous.withPrefix(ctx.receiveNode(erroneous.prefix, receiveSpace)!);
erroneous = erroneous.withMarkers(ctx.receiveNode(erroneous.markers, ctx.receiveMarkers)!);
erroneous = erroneous.withText(ctx.receiveValue(erroneous.text, ValueType.Primitive)!);
return erroneous;
}

}

class Factory implements ReceiverFactory {
Expand Down Expand Up @@ -1471,15 +1463,6 @@ class Factory implements ReceiverFactory {
);
}

if (type === "org.openrewrite.java.tree.J$Erroneous") {
return new Erroneous(
ctx.receiveValue(null, ValueType.UUID)!,
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveValue(null, ValueType.Primitive)!
);
}

throw new Error("No factory method for type: " + type);
}
}
Expand Down
10 changes: 1 addition & 9 deletions openrewrite/src/java/remote/sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {JavaVisitor} from '..';
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';
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';
import * as Java from "../../java/tree";

export class JavaSender implements Sender<J> {
Expand Down Expand Up @@ -708,14 +708,6 @@ class Visitor extends JavaVisitor<SenderContext> {
return source;
}

public visitErroneous(erroneous: Erroneous, ctx: SenderContext): J {
ctx.sendValue(erroneous, v => v.id, ValueType.UUID);
ctx.sendNode(erroneous, v => v.prefix, Visitor.sendSpace);
ctx.sendNode(erroneous, v => v.markers, ctx.sendMarkers);
ctx.sendValue(erroneous, v => v.text, ValueType.Primitive);
return erroneous;
}

private static sendContainer<T>(type: ValueType): (container: JContainer<T>, ctx: SenderContext) => void {
return extensions.sendContainer(type);
}
Expand Down
64 changes: 0 additions & 64 deletions openrewrite/src/java/tree/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6320,67 +6320,3 @@ export namespace Unknown {
}

}

@LstType("org.openrewrite.java.tree.J$Erroneous")
export class Erroneous extends JMixin(Object) implements Statement, Expression {
public constructor(id: UUID, prefix: Space, markers: Markers, text: string) {
super();
this._id = id;
this._prefix = prefix;
this._markers = markers;
this._text = text;
}

private readonly _id: UUID;

public get id(): UUID {
return this._id;
}

public withId(id: UUID): Erroneous {
return id === this._id ? this : new Erroneous(id, this._prefix, this._markers, this._text);
}

private readonly _prefix: Space;

public get prefix(): Space {
return this._prefix;
}

public withPrefix(prefix: Space): Erroneous {
return prefix === this._prefix ? this : new Erroneous(this._id, prefix, this._markers, this._text);
}

private readonly _markers: Markers;

public get markers(): Markers {
return this._markers;
}

public withMarkers(markers: Markers): Erroneous {
return markers === this._markers ? this : new Erroneous(this._id, this._prefix, markers, this._text);
}

private readonly _text: string;

public get text(): string {
return this._text;
}

public withText(text: string): Erroneous {
return text === this._text ? this : new Erroneous(this._id, this._prefix, this._markers, text);
}

public acceptJava<P>(v: JavaVisitor<P>, p: P): J | null {
return v.visitErroneous(this, p);
}

public get type(): JavaType | null {
return extensions.getJavaType(this);
}

public withType(type: JavaType): Erroneous {
return extensions.withJavaType(this, type);
}

}
20 changes: 1 addition & 19 deletions openrewrite/src/java/visitor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as extensions from "./extensions";
import {ListUtils, SourceFile, Tree, TreeVisitor} from "../core";
import {J, isJava, Comment, Expression, JavaSourceFile, JavaType, JContainer, JLeftPadded, JRightPadded, Loop, MethodCall, NameTree, Space, Statement, TextComment, TypedTree, TypeTree} from "./tree";
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";
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";

export class JavaVisitor<P> extends TreeVisitor<J, P> {
isAcceptable(sourceFile: SourceFile, p: P): boolean {
Expand Down Expand Up @@ -965,24 +965,6 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
return source;
}

public visitErroneous(erroneous: Erroneous, p: P): J | null {
erroneous = erroneous.withPrefix(this.visitSpace(erroneous.prefix, Space.Location.ERRONEOUS_PREFIX, p)!);
let tempStatement = this.visitStatement(erroneous, p) as Statement;
if (!(tempStatement instanceof Erroneous))
{
return tempStatement;
}
erroneous = tempStatement as Erroneous;
let tempExpression = this.visitExpression(erroneous, p) as Expression;
if (!(tempExpression instanceof Erroneous))
{
return tempExpression;
}
erroneous = tempExpression as Erroneous;
erroneous = erroneous.withMarkers(this.visitMarkers(erroneous.markers, p));
return erroneous;
}

public visitContainer<T>(container: JContainer<T> | null, loc: JContainer.Location, p: P): JContainer<T> | null {
return extensions.visitContainer(this, container, loc, p);
}
Expand Down
115 changes: 84 additions & 31 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,12 @@ export class JavaScriptParserVisitor {
| ts.FunctionDeclaration | ts.ParameterDeclaration | ts.MethodDeclaration | ts.EnumDeclaration | ts.InterfaceDeclaration
| ts.PropertySignature | ts.ConstructorDeclaration | ts.ModuleDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration
| ts.ArrowFunction | ts.IndexSignatureDeclaration | ts.TypeAliasDeclaration | ts.ExportDeclaration | ts.ExportAssignment | ts.FunctionExpression
| ts.ConstructorTypeNode | ts.TypeParameterDeclaration) {
| ts.ConstructorTypeNode | ts.TypeParameterDeclaration | ts.ImportDeclaration | ts.ImportEqualsDeclaration) {
if (ts.isVariableStatement(node) || ts.isModuleDeclaration(node) || ts.isClassDeclaration(node) || ts.isEnumDeclaration(node)
|| ts.isInterfaceDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isParameter(node)
|| ts.isMethodDeclaration(node) || ts.isConstructorDeclaration(node) || ts.isArrowFunction(node)
|| ts.isIndexSignatureDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isExportDeclaration(node)
|| ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isConstructorTypeNode(node) || ts.isTypeParameterDeclaration(node)) {
|| ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isConstructorTypeNode(node) || ts.isTypeParameterDeclaration(node) || ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node)) {
return node.modifiers ? node.modifiers?.filter(ts.isModifier).map(this.mapModifier) : [];
}
else if (ts.isExportAssignment(node)) {
Expand Down Expand Up @@ -3214,7 +3214,46 @@ export class JavaScriptParserVisitor {
}

visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) {
return this.visitUnknown(node);
const kind = this.findChildNode(node, ts.SyntaxKind.ImportKeyword)!;

return new JS.ScopedVariableDeclarations(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.mapModifiers(node),
this.leftPadded(
this.prefix(kind),
JS.ScopedVariableDeclarations.Scope.Import
),
[
this.rightPadded(new J.VariableDeclarations(
randomId(),
Space.EMPTY,
Markers.EMPTY,
[],
node.isTypeOnly ? [new J.Modifier(
randomId(),
this.prefix(this.findChildNode(node, ts.SyntaxKind.TypeKeyword)!),
Markers.EMPTY,
"type",
J.Modifier.Type.LanguageExtension,
[]
)] : [],
null,
null,
[],
[this.rightPadded(new J.VariableDeclarations.NamedVariable(
randomId(),
Space.EMPTY,
Markers.EMPTY,
this.visit(node.name),
[],
this.leftPadded(this.suffix(node.name), this.visit(node.moduleReference)),
this.mapVariableType(node)
), Space.EMPTY)]
), Space.EMPTY)
]
)
}

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

visitImportDeclaration(node: ts.ImportDeclaration) {
const children = node.getChildren(this.sourceFile);
const _default = !!node.importClause?.name;
const onlyDefault = _default && node.importClause.namedBindings == undefined;
return new JS.JsImport(
randomId(),
this.prefix(node),
Markers.EMPTY,
_default ? this.rightPadded(this.visit(node.importClause?.name), this.suffix(node.importClause?.name)) : null,
node.importClause?.isTypeOnly ? this.leftPadded(this.prefix(this.findChildNode(node.importClause, ts.SyntaxKind.TypeKeyword)!), node.importClause.isTypeOnly) : this.leftPadded(Space.EMPTY, false),
node.importClause && !onlyDefault ? this.visit(node.importClause) : null,
children[children.indexOf(node.moduleSpecifier) - 1].kind == ts.SyntaxKind.FromKeyword ? this.prefix(children[children.indexOf(node.moduleSpecifier) - 1]) : null,
this.convert<J.Literal>(node.moduleSpecifier),
null
this.mapModifiers(node),
node.importClause ? this.visit(node.importClause) : null,
this.leftPadded(node.importClause ? this.prefix(this.findChildNode(node, ts.SyntaxKind.FromKeyword)!) : Space.EMPTY, this.visit(node.moduleSpecifier)),
node.attributes ? this.visit(node.attributes) : null
);
}

visitImportClause(node: ts.ImportClause) {
if (node.namedBindings && ts.isNamespaceImport(node.namedBindings)) {
return new JContainer(
this.prefix(node),
[this.rightPadded(new JS.Alias(
randomId(),
Space.EMPTY,
Markers.EMPTY,
// this.rightPadded(node.isTypeOnly, node.isTypeOnly ? this.suffix(this.findChildNode(node, ts.SyntaxKind.TypeKeyword)!) : Space.EMPTY),
this.rightPadded(this.mapIdentifier(node.namedBindings, "*"), this.prefix(node.namedBindings.getChildAt(1, this.sourceFile))),
this.convert(node.namedBindings.name)
), Space.EMPTY)],
Markers.EMPTY
);
}
return this.mapCommaSeparatedList(node.namedBindings?.getChildren(this.sourceFile)!);
return new JS.JsImportClause(
randomId(),
this.prefix(node),
Markers.EMPTY,
node.isTypeOnly,
node.name ? this.rightPadded(this.visit(node.name), this.suffix(node.name)) : null,
node.namedBindings ? this.visit(node.namedBindings) : null
);
}

visitNamespaceImport(node: ts.NamespaceImport) {
return this.visitUnknown(node);
return new JS.Alias(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.rightPadded(this.mapIdentifier(node, "*"), this.prefix(this.findChildNode(node, ts.SyntaxKind.AsKeyword)!)),
this.visit(node.name)
);
}

visitNamedImports(node: ts.NamedImports) {
return this.visitUnknown(node);
return new JS.NamedImports(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.mapCommaSeparatedList(node.getChildren(this.sourceFile)),
null
);
}

visitImportSpecifier(node: ts.ImportSpecifier) {
Expand Down Expand Up @@ -3514,11 +3553,25 @@ export class JavaScriptParserVisitor {
}

visitImportAttributes(node: ts.ImportAttributes) {
return this.visitUnknown(node);
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));
return new JS.ImportAttributes(
randomId(),
this.prefix(node),
Markers.EMPTY,
ts.SyntaxKind.WithKeyword === node.token ? JS.ImportAttributes.Token.With : JS.ImportAttributes.Token.Assert,
elements
);
}

visitImportAttribute(node: ts.ImportAttribute) {
return this.visitUnknown(node);
return new JS.ImportAttribute(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.visit(node.name),
this.leftPadded(this.suffix(node.name), this.visit(node.value))
);
}

visitPropertyAssignment(node: ts.PropertyAssignment) {
Expand Down
Loading

0 comments on commit 620ba5d

Please sign in to comment.