Skip to content

Commit

Permalink
- introduced JS.ImportType
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrii Rodionov committed Nov 29, 2024
1 parent df99153 commit 7941c98
Show file tree
Hide file tree
Showing 18 changed files with 537 additions and 8 deletions.
22 changes: 21 additions & 1 deletion openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1553,7 +1553,27 @@ export class JavaScriptParserVisitor {
}

visitImportType(node: ts.ImportTypeNode) {
return this.visitUnknown(node);
return new JS.ImportType(
randomId(),
this.prefix(node),
Markers.EMPTY,
node.isTypeOf ? this.rightPadded(true, this.suffix(this.findChildNode(node, ts.SyntaxKind.TypeOfKeyword)!)) : this.rightPadded(false, Space.EMPTY),
new J.ParenthesizedTypeTree(
randomId(),
this.suffix(this.findChildNode(node, ts.SyntaxKind.ImportKeyword)!),
Markers.EMPTY,
[],
new J.Parentheses(
randomId(),
Space.EMPTY,
Markers.EMPTY,
this.rightPadded(this.visit(node.argument), this.suffix(node.argument))
)
),
node.qualifier ? this.leftPadded(this.prefix(this.findChildNode(node, ts.SyntaxKind.DotToken)!), this.visit(node.qualifier)): null,
node.typeArguments ? this.mapTypeArguments(this.suffix(node.qualifier!), node.typeArguments) : null,
this.mapType(node)
);
}

visitObjectBindingPattern(node: ts.ObjectBindingPattern) {
Expand Down
27 changes: 26 additions & 1 deletion openrewrite/src/javascript/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 {JavaScriptVisitor} from '..';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement} from '../tree';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement} from '../tree';
import {Expression, J, JContainer, JLeftPadded, JRightPadded, NameTree, Space, Statement, TypeTree, TypedTree} from "../../java";
import * as Java from "../../java/tree";

Expand Down Expand Up @@ -153,6 +153,18 @@ class Visitor extends JavaScriptVisitor<ReceiverContext> {
return inferType;
}

public visitImportType(importType: ImportType, ctx: ReceiverContext): J {
importType = importType.withId(ctx.receiveValue(importType.id, ValueType.UUID)!);
importType = importType.withPrefix(ctx.receiveNode(importType.prefix, receiveSpace)!);
importType = importType.withMarkers(ctx.receiveNode(importType.markers, ctx.receiveMarkers)!);
importType = importType.padding.withHasTypeof(ctx.receiveNode(importType.padding.hasTypeof, rightPaddedValueReceiver(ValueType.Primitive))!);
importType = importType.withImportArgument(ctx.receiveNode(importType.importArgument, ctx.receiveTree)!);
importType = importType.padding.withQualifier(ctx.receiveNode(importType.padding.qualifier, receiveLeftPaddedTree));
importType = importType.padding.withTypeArguments(ctx.receiveNode(importType.padding.typeArguments, receiveContainer));
importType = importType.withType(ctx.receiveValue(importType.type, ValueType.Object));
return importType;
}

public visitJsImport(jsImport: JsImport, ctx: ReceiverContext): J {
jsImport = jsImport.withId(ctx.receiveValue(jsImport.id, ValueType.UUID)!);
jsImport = jsImport.withPrefix(ctx.receiveNode(jsImport.prefix, receiveSpace)!);
Expand Down Expand Up @@ -1327,6 +1339,19 @@ class Factory implements ReceiverFactory {
);
}

if (type === "org.openrewrite.javascript.tree.JS$ImportType") {
return new ImportType(
ctx.receiveValue(null, ValueType.UUID)!,
ctx.receiveNode(null, receiveSpace)!,
ctx.receiveNode(null, ctx.receiveMarkers)!,
ctx.receiveNode<JRightPadded<boolean>>(null, rightPaddedValueReceiver(ValueType.Primitive))!,
ctx.receiveNode<Java.ParenthesizedTypeTree>(null, ctx.receiveTree)!,
ctx.receiveNode<JLeftPadded<Expression>>(null, receiveLeftPaddedTree),
ctx.receiveNode<JContainer<Expression>>(null, receiveContainer),
ctx.receiveValue(null, ValueType.Object)
);
}

if (type === "org.openrewrite.javascript.tree.JS$JsImport") {
return new JsImport(
ctx.receiveValue(null, ValueType.UUID)!,
Expand Down
14 changes: 13 additions & 1 deletion openrewrite/src/javascript/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 {JavaScriptVisitor} from '..';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement} from '../tree';
import {JS, JsLeftPadded, JsRightPadded, JsContainer, JsSpace, CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement} from '../tree';
import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../../java";
import * as Java from "../../java/tree";

Expand Down Expand Up @@ -148,6 +148,18 @@ class Visitor extends JavaScriptVisitor<SenderContext> {
return inferType;
}

public visitImportType(importType: ImportType, ctx: SenderContext): J {
ctx.sendValue(importType, v => v.id, ValueType.UUID);
ctx.sendNode(importType, v => v.prefix, Visitor.sendSpace);
ctx.sendNode(importType, v => v.markers, ctx.sendMarkers);
ctx.sendNode(importType, v => v.padding.hasTypeof, Visitor.sendRightPadded(ValueType.Primitive));
ctx.sendNode(importType, v => v.importArgument, ctx.sendTree);
ctx.sendNode(importType, v => v.padding.qualifier, Visitor.sendLeftPadded(ValueType.Tree));
ctx.sendNode(importType, v => v.padding.typeArguments, Visitor.sendContainer(ValueType.Tree));
ctx.sendTypedValue(importType, v => v.type, ValueType.Object);
return importType;
}

public visitJsImport(jsImport: JsImport, ctx: SenderContext): J {
ctx.sendValue(jsImport, v => v.id, ValueType.UUID);
ctx.sendNode(jsImport, v => v.prefix, Visitor.sendSpace);
Expand Down
4 changes: 4 additions & 0 deletions openrewrite/src/javascript/tree/support_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ export namespace JsSpace {
TYPE_PREDICATE_PREFIX,
LITERAL_TYPE_PREFIX,
SATISFIES_EXPRESSION_PREFIX,
IMPORT_TYPE_PREFIX,
}
}
export namespace JsLeftPadded {
Expand Down Expand Up @@ -274,6 +275,7 @@ export namespace JsLeftPadded {
TYPE_PREDICATE_ASSERTS,
TYPE_PREDICATE_EXPRESSION,
SATISFIES_EXPRESSION_SATISFIES_TYPE,
IMPORT_TYPE_QUALIFIER,
}
}
export namespace JsRightPadded {
Expand All @@ -297,6 +299,7 @@ export namespace JsRightPadded {
FUNCTION_TYPE_CONSTRUCTOR_TYPE,
TEMPLATE_EXPRESSION_TEMPLATE_SPANS,
TAGGED_TEMPLATE_EXPRESSION_TAG,
IMPORT_TYPE_HAS_TYPEOF,
}
}
export namespace JsContainer {
Expand All @@ -315,5 +318,6 @@ export namespace JsContainer {
EXPRESSION_WITH_TYPE_ARGUMENTS_TYPE_ARGUMENTS,
TAGGED_TEMPLATE_EXPRESSION_TYPE_ARGUMENTS,
CONDITIONAL_TYPE_CONDITION,
IMPORT_TYPE_TYPE_ARGUMENTS,
}
}
124 changes: 124 additions & 0 deletions openrewrite/src/javascript/tree/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,130 @@ export class InferType extends JSMixin(Object) implements TypeTree, Expression {

}

@LstType("org.openrewrite.javascript.tree.JS$ImportType")
export class ImportType extends JSMixin(Object) implements Expression, TypeTree {
public constructor(id: UUID, prefix: Space, markers: Markers, hasTypeof: JRightPadded<boolean>, importArgument: Java.ParenthesizedTypeTree, qualifier: JLeftPadded<Expression> | null, typeArguments: JContainer<Expression> | null, _type: JavaType | null) {
super();
this._id = id;
this._prefix = prefix;
this._markers = markers;
this._hasTypeof = hasTypeof;
this._importArgument = importArgument;
this._qualifier = qualifier;
this._typeArguments = typeArguments;
this._type = _type;
}

private readonly _id: UUID;

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

public withId(id: UUID): ImportType {
return id === this._id ? this : new ImportType(id, this._prefix, this._markers, this._hasTypeof, this._importArgument, this._qualifier, this._typeArguments, this._type);
}

private readonly _prefix: Space;

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

public withPrefix(prefix: Space): ImportType {
return prefix === this._prefix ? this : new ImportType(this._id, prefix, this._markers, this._hasTypeof, this._importArgument, this._qualifier, this._typeArguments, this._type);
}

private readonly _markers: Markers;

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

public withMarkers(markers: Markers): ImportType {
return markers === this._markers ? this : new ImportType(this._id, this._prefix, markers, this._hasTypeof, this._importArgument, this._qualifier, this._typeArguments, this._type);
}

private readonly _hasTypeof: JRightPadded<boolean>;

public get hasTypeof(): boolean {
return this._hasTypeof.element;
}

public withHasTypeof(hasTypeof: boolean): ImportType {
return this.padding.withHasTypeof(this._hasTypeof.withElement(hasTypeof));
}

private readonly _importArgument: Java.ParenthesizedTypeTree;

public get importArgument(): Java.ParenthesizedTypeTree {
return this._importArgument;
}

public withImportArgument(importArgument: Java.ParenthesizedTypeTree): ImportType {
return importArgument === this._importArgument ? this : new ImportType(this._id, this._prefix, this._markers, this._hasTypeof, importArgument, this._qualifier, this._typeArguments, this._type);
}

private readonly _qualifier: JLeftPadded<Expression> | null;

public get qualifier(): Expression | null {
return this._qualifier === null ? null : this._qualifier.element;
}

public withQualifier(qualifier: Expression | null): ImportType {
return this.padding.withQualifier(JLeftPadded.withElement(this._qualifier, qualifier));
}

private readonly _typeArguments: JContainer<Expression> | null;

public get typeArguments(): Expression[] | null {
return this._typeArguments === null ? null : this._typeArguments.elements;
}

public withTypeArguments(typeArguments: Expression[] | null): ImportType {
return this.padding.withTypeArguments(JContainer.withElementsNullable(this._typeArguments, typeArguments));
}

private readonly _type: JavaType | null;

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

public withType(_type: JavaType | null): ImportType {
return _type === this._type ? this : new ImportType(this._id, this._prefix, this._markers, this._hasTypeof, this._importArgument, this._qualifier, this._typeArguments, _type);
}

public acceptJavaScript<P>(v: JavaScriptVisitor<P>, p: P): J | null {
return v.visitImportType(this, p);
}

get padding() {
const t = this;
return new class {
public get hasTypeof(): JRightPadded<boolean> {
return t._hasTypeof;
}
public withHasTypeof(hasTypeof: JRightPadded<boolean>): ImportType {
return t._hasTypeof === hasTypeof ? t : new ImportType(t._id, t._prefix, t._markers, hasTypeof, t._importArgument, t._qualifier, t._typeArguments, t._type);
}
public get qualifier(): JLeftPadded<Expression> | null {
return t._qualifier;
}
public withQualifier(qualifier: JLeftPadded<Expression> | null): ImportType {
return t._qualifier === qualifier ? t : new ImportType(t._id, t._prefix, t._markers, t._hasTypeof, t._importArgument, qualifier, t._typeArguments, t._type);
}
public get typeArguments(): JContainer<Expression> | null {
return t._typeArguments;
}
public withTypeArguments(typeArguments: JContainer<Expression> | null): ImportType {
return t._typeArguments === typeArguments ? t : new ImportType(t._id, t._prefix, t._markers, t._hasTypeof, t._importArgument, t._qualifier, typeArguments, t._type);
}
}
}

}

@LstType("org.openrewrite.javascript.tree.JS$JsImport")
export class JsImport extends JSMixin(Object) implements Statement {
public constructor(id: UUID, prefix: Space, markers: Markers, name: JRightPadded<Java.Identifier> | null, importType: JLeftPadded<boolean>, imports: JContainer<Expression> | null, _from: Space | null, target: Java.Literal | null, initializer: JLeftPadded<Expression> | null) {
Expand Down
18 changes: 17 additions & 1 deletion openrewrite/src/javascript/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 {JS, isJavaScript, JsLeftPadded, JsRightPadded, JsContainer, JsSpace} from "./tree";
import {CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement} from "./tree";
import {CompilationUnit, Alias, ArrowFunction, Await, ConditionalType, DefaultType, Delete, Export, ExpressionStatement, ExpressionWithTypeArguments, FunctionType, InferType, ImportType, JsImport, JsImportSpecifier, JsBinary, LiteralType, ObjectBindingDeclarations, PropertyAssignment, SatisfiesExpression, ScopedVariableDeclarations, StatementExpression, TaggedTemplateExpression, TemplateExpression, Tuple, TypeDeclaration, TypeOf, TypeQuery, TypeOperator, TypePredicate, Unary, Union, Intersection, Void, Yield, TypeInfo, JSVariableDeclarations, JSMethodDeclaration, JSForOfLoop, JSForInLoop, JSForInOfLoopControl, NamespaceDeclaration, FunctionDeclaration, TypeLiteral, IndexSignatureDeclaration, ArrayBindingPattern, BindingElement} from "./tree";
import {Expression, J, JContainer, JLeftPadded, JRightPadded, Space, Statement} from "../java/tree";
import {JavaVisitor} from "../java";
import * as Java from "../java/tree";
Expand Down Expand Up @@ -184,6 +184,22 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
return inferType;
}

public visitImportType(importType: ImportType, p: P): J | null {
importType = importType.withPrefix(this.visitJsSpace(importType.prefix, JsSpace.Location.IMPORT_TYPE_PREFIX, p)!);
let tempExpression = this.visitExpression(importType, p) as Expression;
if (!(tempExpression instanceof ImportType))
{
return tempExpression;
}
importType = tempExpression as ImportType;
importType = importType.withMarkers(this.visitMarkers(importType.markers, p));
importType = importType.padding.withHasTypeof(this.visitJsRightPadded(importType.padding.hasTypeof, JsRightPadded.Location.IMPORT_TYPE_HAS_TYPEOF, p)!);
importType = importType.withImportArgument(this.visitAndCast(importType.importArgument, p)!);
importType = importType.padding.withQualifier(this.visitJsLeftPadded(importType.padding.qualifier, JsLeftPadded.Location.IMPORT_TYPE_QUALIFIER, p));
importType = importType.padding.withTypeArguments(this.visitJsContainer(importType.padding.typeArguments, JsContainer.Location.IMPORT_TYPE_TYPE_ARGUMENTS, p));
return importType;
}

public visitJsImport(jsImport: JsImport, p: P): J | null {
jsImport = jsImport.withPrefix(this.visitJsSpace(jsImport.prefix, JsSpace.Location.JS_IMPORT_PREFIX, p)!);
let tempStatement = this.visitStatement(jsImport, p) as Statement;
Expand Down
9 changes: 9 additions & 0 deletions openrewrite/test/javascript/parser/import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,13 @@ describe('import mapping', () => {
typeScript(`import type { Component } from "react";`)
);
});

test.skip('experimental: import with import attributes', () => {
rewriteRun(
//language=typescript
typeScript(`
import foo from 'module-name' with { type: "json" };
`)
);
});
});
Loading

0 comments on commit 7941c98

Please sign in to comment.