Skip to content

Commit

Permalink
Map ts.ImportDeclaration
Browse files Browse the repository at this point in the history
I hope all cases are covered.
  • Loading branch information
knutwannheden committed Sep 27, 2024
1 parent 09ffb5f commit d91fed6
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 10 deletions.
5 changes: 4 additions & 1 deletion openrewrite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
".": "./dist/index.js",
"./core": "./dist/core/index.js",
"./java": "./dist/java/index.js",
"./java/tree": "./dist/java/tree/index.js",
"./javascript": "./dist/javascript/index.js",
"./javascript/tree": "./dist/javascript/tree/index.js",
"./json": "./dist/json/index.js",
"./yaml": "./dist/yaml/index.js"
"./yaml": "./dist/yaml/index.js",
"./yaml/tree": "./dist/yaml/tree/index.js"
},
"scripts": {
"build": "tsc --build tsconfig.build.json",
Expand Down
30 changes: 27 additions & 3 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1000,11 +1000,35 @@ export class JavaScriptParserVisitor {
}

visitImportDeclaration(node: ts.ImportDeclaration) {
return this.visitUnknown(node);
const children = node.getChildren();
const _default = !!node.importClause?.name;
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 ? 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
);
}

visitImportClause(node: ts.ImportClause) {
return this.visitUnknown(node);
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(this.mapIdentifier(node.namedBindings, "*"), this.prefix(node.namedBindings.getChildAt(1))),
this.convert(node.namedBindings.name)
), Space.EMPTY)],
Markers.EMPTY
);
}
return this.mapArguments(node.namedBindings?.getChildren()!);
}

visitNamespaceImport(node: ts.NamespaceImport) {
Expand All @@ -1016,7 +1040,7 @@ export class JavaScriptParserVisitor {
}

visitImportSpecifier(node: ts.ImportSpecifier) {
return this.visitUnknown(node);
return this.convert(node.name);
}

visitExportAssignment(node: ts.ExportAssignment) {
Expand Down
69 changes: 69 additions & 0 deletions openrewrite/test/javascript/parser/import.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {connect, disconnect, rewriteRun, typeScript} from '../testHarness';

describe('import mapping', () => {
beforeAll(() => connect());
afterAll(() => disconnect());

test('simple', () => {
rewriteRun(
//language=typescript
typeScript('import {foo} from "bar"')
);
});

test('for side effect', () => {
rewriteRun(
//language=typescript
typeScript('import "foo"')
);
});

test('space', () => {
rewriteRun(
//language=typescript
typeScript('import {foo} /*1*/ from /*2*/ "bar"/*3*/;')
);
});

test('multiple', () => {
rewriteRun(
//language=typescript
typeScript('import {foo, bar} from "baz"')
);
});

test('trailing comma', () => {
rewriteRun(
//language=typescript
typeScript('import {foo, } from "baz"')
);
});

test('default', () => {
rewriteRun(
//language=typescript
typeScript('import foo from "bar"')
);
});

test('namespace', () => {
rewriteRun(
//language=typescript
typeScript('import * as foo from "bar"')
);
});

test('default and namespace', () => {
rewriteRun(
//language=typescript
typeScript('import baz, * as foo from "bar"')
);
});

test('default and others', () => {
rewriteRun(
//language=typescript
typeScript('import baz, {foo1, } from "bar"')
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,25 @@ public J visitJsImport(JS.JsImport jsImport, PrintOutputCapture<P> p) {
beforeSyntax(jsImport, JsSpace.Location.EXPORT_PREFIX, p);
p.append("import");

visitRightPadded(jsImport.getPadding().getName(), JsRightPadded.Location.IMPORT_NAME_SUFFIX, p);
// for default export or `* as <alias>`
JS.JsImport.Padding padding = jsImport.getPadding();
visitRightPadded(padding.getName(), JsRightPadded.Location.IMPORT_NAME_SUFFIX, p);

if (jsImport.getName() != null && jsImport.getImports() != null) {
if (jsImport.getName() != null && padding.getImports() != null) {
p.append(",");
}

boolean printBrackets = jsImport.getPadding().getImports() != null && jsImport.getPadding().getImports().getMarkers().findFirst(Braces.class).isPresent();
visitContainer(printBrackets ? "{" : "", jsImport.getPadding().getImports(), JsContainer.Location.FUNCTION_TYPE_PARAMETER, ",", printBrackets ? "}" : "", p);
boolean braces = padding.getImports() != null &&
padding.getImports().getPadding().getElements().stream().noneMatch(e -> e.getElement() instanceof JS.Alias);
visitContainer(braces ? "{" : "", padding.getImports(), JsContainer.Location.IMPORT_ELEMENT, ",", braces ? "}" : "", p);

if (jsImport.getFrom() != null) {
visitSpace(jsImport.getFrom(), Space.Location.LANGUAGE_EXTENSION, p);
p.append("from");
visit(jsImport.getTarget(), p);
}
visit(jsImport.getTarget(), p);

visitLeftPadded("=", jsImport.getPadding().getInitializer(), JsLeftPadded.Location.IMPORT_INITIALIZER, p);
visitLeftPadded("=", padding.getInitializer(), JsLeftPadded.Location.IMPORT_INITIALIZER, p);
afterSyntax(jsImport, p);
return jsImport;
}
Expand Down

0 comments on commit d91fed6

Please sign in to comment.