Skip to content

Commit

Permalink
feat: extract imports
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Mar 3, 2020
1 parent bc6c9f6 commit eb441be
Show file tree
Hide file tree
Showing 17 changed files with 308 additions and 34 deletions.
2 changes: 1 addition & 1 deletion core/instrument/.eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dist
dist
36 changes: 8 additions & 28 deletions core/instrument/src/babel/extract-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import traverse from '@babel/traverse';
import { CodeLocation } from '@component-controls/specification';
import { sourceLocation } from './utils';

interface ExportType {
export interface ExportType {
path: any;
node: any;
name: string;
exportedAs?: string;
internalName?: string;
loc: CodeLocation;
type: 'function' | 'indentifier';
}
Expand Down Expand Up @@ -35,6 +35,7 @@ export const traverseExports = (results: ExportTypes) => {
const exportType: ExportType = {
loc: sourceLocation(declaration.init.body.loc),
name,
internalName: name,
path,
node: path.node,
type: 'function',
Expand All @@ -53,30 +54,6 @@ export const traverseExports = (results: ExportTypes) => {
type: 'indentifier',
};
},
AssignmentExpression: (path: any) => {
const node = path.node;
if (
node.left.type === 'MemberExpression' &&
node.left.property.type === 'Identifier' &&
node.left.property.name === 'story' &&
node.right.type === 'ObjectExpression'
) {
const name = node.left.object.name;
globals[name] = {
loc: sourceLocation(node.loc),
path,
node: node.right,
name,
type: 'indentifier',
};

const parsed = results.named[name];

if (parsed) {
parsed.name = name;
}
}
},
VariableDeclaration: (path: any) => {
const { declarations } = path.node;
if (Array.isArray(declarations) && declarations.length > 0) {
Expand All @@ -98,10 +75,12 @@ export const traverseExports = (results: ExportTypes) => {
const localName = node.local.name;
const exportedName = node.exported.name;
const namedExport = localExports[localName];

if (namedExport) {
namedExport.internalName = namedExport.name;
namedExport.name = exportedName;
const global = globals[localName];
if (global) {
namedExport.name = global.name;
namedExport.path = global.path;
namedExport.node = global.node;
namedExport.loc = global.loc;
Expand All @@ -121,6 +100,7 @@ export const traverseExports = (results: ExportTypes) => {
const name = namedExport.name || '';
const global = globals[name];
if (global) {
namedExport.internalName = global.name;
namedExport.name = global.name;
namedExport.path = global.path;
namedExport.node = global.node;
Expand All @@ -139,7 +119,7 @@ const cleanExportType = (exportType?: ExportType) => {
return exportType
? {
name: exportType.name,
exportedAs: exportType.exportedAs,
internalName: exportType.internalName,
loc: exportType.loc,
}
: undefined;
Expand Down
58 changes: 58 additions & 0 deletions core/instrument/src/babel/extract-imports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as parser from '@babel/parser';
import traverse from '@babel/traverse';

export interface ImportType {
name: string;
importedName: 'default' | 'namespace' | string;
}

export interface ImportTypes {
[key: string]: ImportType[];
}

export const traverseImports = (results: ImportTypes) => {
return {
ImportDeclaration: (path: any) => {
const node = path.node;
const imports: ImportType[] = node.specifiers.map((specifier: any) => {
let importedName;
switch (specifier.type) {
case 'ImportDefaultSpecifier':
importedName = 'default';
break;
case 'ImportNamespaceSpecifier':
importedName = 'namespace';
break;

default:
importedName = specifier.imported
? specifier.imported.name
: specifier.local.name;
}
return {
name: specifier.local.name,
importedName,
};
});
if (Array.isArray(results[node.source.value])) {
results[node.source.value] = [
...results[node.source.value],
...imports,
];
} else {
results[node.source.value] = imports;
}
},
};
};

export const extractImports = (
source: string,
parserOptions?: parser.ParserOptions,
) => {
const results: ImportTypes = {};
const ast = parser.parse(source, parserOptions);

traverse(ast, traverseImports(results));
return results;
};
57 changes: 54 additions & 3 deletions core/instrument/test/__snapshots__/extract-exports.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`extract-exports props argument 1`] = `
exports[`extract-exports named const export 1`] = `
Object {
"default": undefined,
"named": Array [
Object {
"internalName": "myStory",
"loc": Object {
"end": Object {
"column": 24,
"line": 1,
},
"start": Object {
"column": 22,
"line": 1,
},
},
"name": "myStory",
},
],
}
`;

exports[`extract-exports named export 1`] = `
Object {
"default": Object {
"exportedAs": undefined,
"internalName": undefined,
"loc": Object {
"end": Object {
"column": 28,
Expand All @@ -18,7 +40,7 @@ Object {
},
"named": Array [
Object {
"exportedAs": undefined,
"internalName": "namedExport",
"loc": Object {
"end": Object {
"column": 40,
Expand All @@ -34,3 +56,32 @@ Object {
],
}
`;

exports[`extract-exports named export alias 1`] = `
Object {
"default": undefined,
"named": Array [
Object {
"internalName": "myStory",
"loc": Object {
"end": Object {
"column": 24,
"line": 1,
},
"start": Object {
"column": 22,
"line": 1,
},
},
"name": "exportedStory",
},
],
}
`;

exports[`extract-exports re-exported name 1`] = `
Object {
"default": undefined,
"named": Array [],
}
`;
103 changes: 103 additions & 0 deletions core/instrument/test/__snapshots__/extract-imports.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`extract-imports all imports 1`] = `
Object {
"./buttons": Array [
Object {
"importedName": "Button",
"name": "Btn",
},
],
"buttons": Array [
Object {
"importedName": "default",
"name": "Button1",
},
Object {
"importedName": "namespace",
"name": "Button2",
},
Object {
"importedName": "Button",
"name": "Button",
},
],
"react": Array [
Object {
"importedName": "default",
"name": "React",
},
Object {
"importedName": "FC",
"name": "FC",
},
Object {
"importedName": "MouseEvent",
"name": "MouseEvent",
},
],
}
`;

exports[`extract-imports default import 1`] = `
Object {
"buttons": Array [
Object {
"importedName": "default",
"name": "Button",
},
],
}
`;

exports[`extract-imports mixed import 1`] = `
Object {
"./react": Array [
Object {
"importedName": "default",
"name": "React",
},
Object {
"importedName": "FC",
"name": "FC",
},
Object {
"importedName": "MouseEvent",
"name": "MouseEvent",
},
],
}
`;

exports[`extract-imports named alias import 1`] = `
Object {
"buttons": Array [
Object {
"importedName": "Button",
"name": "Btn",
},
],
}
`;

exports[`extract-imports named import 1`] = `
Object {
"buttons": Array [
Object {
"importedName": "Button",
"name": "Button",
},
],
}
`;

exports[`extract-imports namespace import 1`] = `
Object {
"buttons": Array [
Object {
"importedName": "namespace",
"name": "Button",
},
],
}
`;
5 changes: 5 additions & 0 deletions core/instrument/test/examples/imports/all-imports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Button1 from 'buttons';
import * as Button2 from 'buttons';
import { Button } from 'buttons';
import React, { FC, MouseEvent } from 'react';
import { Button as Btn } from './buttons';
1 change: 1 addition & 0 deletions core/instrument/test/examples/imports/default-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import Button from 'buttons';
1 change: 1 addition & 0 deletions core/instrument/test/examples/imports/mixed-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import React, { FC, MouseEvent } from './react';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { Button as Btn } from 'buttons';
1 change: 1 addition & 0 deletions core/instrument/test/examples/imports/named-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { Button } from 'buttons';
1 change: 1 addition & 0 deletions core/instrument/test/examples/imports/namespace-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import * as Button from 'buttons';
3 changes: 3 additions & 0 deletions core/instrument/test/examples/named-const-export.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const myStory = () => {};

export { myStory };
3 changes: 3 additions & 0 deletions core/instrument/test/examples/named-export-alias.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const myStory = () => {};

export { myStory as exportedStory };
File renamed without changes.
3 changes: 3 additions & 0 deletions core/instrument/test/examples/re-exported-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { myStory } from 'stories.tsx';

export { myStory };
23 changes: 21 additions & 2 deletions core/instrument/test/extract-exports.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,26 @@ describe('extract-exports', () => {
const content = fs.readFileSync(path.join(__dirname, fileName), 'utf8');
return extractExports(content, defaultParserOptions);
};
it('props argument', () => {
expect(extractExportsForFile('./examples/main.js')).toMatchSnapshot();
it('named export', () => {
expect(
extractExportsForFile('./examples/named-export.js'),
).toMatchSnapshot();
});
it('named const export', () => {
expect(
extractExportsForFile('./examples/named-const-export.js'),
).toMatchSnapshot();
});

it('named export alias', () => {
expect(
extractExportsForFile('./examples/named-export-alias.js'),
).toMatchSnapshot();
});

it('re-exported name', () => {
expect(
extractExportsForFile('./examples/re-exported-name.js'),
).toMatchSnapshot();
});
});
Loading

0 comments on commit eb441be

Please sign in to comment.