add module metadata - closes #1601
This commit is contained in:
@@ -36,9 +36,18 @@ export default class File {
|
||||
this.declarations = {};
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.metadata = {};
|
||||
this.data = {};
|
||||
|
||||
this.metadata = {
|
||||
modules: {
|
||||
imports: [],
|
||||
exports: {
|
||||
exported: [],
|
||||
specifiers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.ast = {};
|
||||
@@ -493,15 +502,9 @@ export default class File {
|
||||
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
|
||||
modFormatter.init();
|
||||
}
|
||||
this.populateModuleMetadata();
|
||||
this.log.debug("End module formatter init");
|
||||
}
|
||||
|
||||
populateModuleMetadata() {
|
||||
var modules = {};
|
||||
this.metadata.modules = modules;
|
||||
}
|
||||
|
||||
transform() {
|
||||
this.call("pre");
|
||||
for (var pass of (this.transformerStack: Array)) {
|
||||
|
||||
@@ -77,31 +77,134 @@ var metadataVisitor = {
|
||||
|
||||
ImportDeclaration(node, parent, scope, formatter) {
|
||||
formatter.hasLocalImports = true;
|
||||
extend(formatter.localImports, this.getBindingIdentifiers());
|
||||
|
||||
var specifiers = [];
|
||||
var imported = [];
|
||||
formatter.metadata.imports.push({
|
||||
source: node.source.value,
|
||||
imported,
|
||||
specifiers
|
||||
});
|
||||
|
||||
for (var specifier of (this.get("specifiers"): Array)) {
|
||||
var ids = specifier.getBindingIdentifiers();
|
||||
extend(formatter.localImports, ids);
|
||||
|
||||
var local = specifier.node.local.name;
|
||||
|
||||
if (specifier.isImportDefaultSpecifier()) {
|
||||
imported.push("default");
|
||||
specifiers.push({
|
||||
kind: "named",
|
||||
imported: "default",
|
||||
local
|
||||
});
|
||||
}
|
||||
|
||||
if (specifier.isImportSpecifier()) {
|
||||
var importedName = specifier.node.imported.name;
|
||||
imported.push(importedName);
|
||||
specifiers.push({
|
||||
kind: "named",
|
||||
imported: importedName,
|
||||
local
|
||||
});
|
||||
}
|
||||
|
||||
if (specifier.isImportNamespaceSpecifier()) {
|
||||
imported.push("*");
|
||||
specifiers.push({
|
||||
kind: "namespace",
|
||||
local
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ExportDeclaration(node, parent, scope, formatter) {
|
||||
formatter.hasLocalExports = true;
|
||||
|
||||
var source = node.source ? node.source.value : null;
|
||||
var exports = formatter.metadata.exports;
|
||||
|
||||
// export function foo() {}
|
||||
// export var foo = "bar";
|
||||
var declar = this.get("declaration");
|
||||
if (declar.isStatement()) {
|
||||
var bindings = declar.getBindingIdentifiers();
|
||||
for (var name in bindings) {
|
||||
var binding = bindings[name];
|
||||
formatter._addExport(name, binding);
|
||||
|
||||
exports.exported.push(name);
|
||||
exports.specifiers.push({
|
||||
kind: "local",
|
||||
local: name,
|
||||
exported: this.isExportDefaultDeclaration() ? "default" : name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isExportNamedDeclaration() && node.specifiers) {
|
||||
for (var i = 0; i < node.specifiers.length; i++) {
|
||||
var specifier = node.specifiers[i];
|
||||
for (var specifier of (node.specifiers: Array)) {
|
||||
var exported = specifier.exported.name;
|
||||
exports.exported.push(exported);
|
||||
|
||||
// export foo from "bar";
|
||||
if (t.isExportDefaultSpecifier(specifier)) {
|
||||
exports.specifiers.push({
|
||||
kind: "external",
|
||||
local: exported,
|
||||
exported,
|
||||
source
|
||||
});
|
||||
}
|
||||
|
||||
// export * as foo from "bar";
|
||||
if (t.isExportNamespaceSpecifier(specifier)) {
|
||||
exports.specifiers.push({
|
||||
kind: "external-namespace",
|
||||
exported,
|
||||
source
|
||||
});
|
||||
}
|
||||
|
||||
var local = specifier.local;
|
||||
if (!local) continue;
|
||||
|
||||
formatter._addExport(local.name, specifier.exported);
|
||||
|
||||
// export { foo } from "bar";
|
||||
// export { foo as bar } from "bar";
|
||||
if (source) {
|
||||
exports.specifiers.push({
|
||||
kind: "external",
|
||||
local: local.name,
|
||||
exported,
|
||||
source
|
||||
});
|
||||
}
|
||||
|
||||
// export { foo };
|
||||
// export { foo as bar };
|
||||
if (!source) {
|
||||
exports.specifiers.push({
|
||||
kind: "local",
|
||||
local: local.name,
|
||||
exported
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// export * from "bar";
|
||||
if (this.isExportAllDeclaration()) {
|
||||
exports.specifiers.push({
|
||||
kind: "external-all",
|
||||
source
|
||||
});
|
||||
}
|
||||
|
||||
if (!t.isExportDefaultDeclaration(node)) {
|
||||
var onlyDefault = node.specifiers && node.specifiers.length === 1 && t.isSpecifierDefault(node.specifiers[0]);
|
||||
if (!onlyDefault) {
|
||||
@@ -131,6 +234,7 @@ export default class DefaultFormatter {
|
||||
this.localExports = object();
|
||||
this.localImports = object();
|
||||
|
||||
this.metadata = file.metadata.modules;
|
||||
this.getMetadata();
|
||||
}
|
||||
|
||||
|
||||
128
test/core/api.js
128
test/core/api.js
@@ -8,17 +8,17 @@ var assert = require("assert");
|
||||
var File = require("../../lib/babel/transformation/file");
|
||||
|
||||
suite("api", function () {
|
||||
test("{ code: false }", function () {
|
||||
test("code option false", function () {
|
||||
var result = transform("foo('bar');", { code: false });
|
||||
assert.ok(!result.code);
|
||||
});
|
||||
|
||||
test("{ ast: false }", function () {
|
||||
test("ast option false", function () {
|
||||
var result = transform("foo('bar');", { ast: false });
|
||||
assert.ok(!result.ast);
|
||||
});
|
||||
|
||||
test("{ auxiliaryComment }", function () {
|
||||
test("auxiliaryComment option", function () {
|
||||
assert.ok(transform("class Foo {}", {
|
||||
auxiliaryComment: "foobar"
|
||||
}).code.indexOf("foobar") >= 0);
|
||||
@@ -28,7 +28,115 @@ suite("api", function () {
|
||||
}).code.indexOf("foobar") >= 0);
|
||||
});
|
||||
|
||||
test("ignore", function () {
|
||||
test("modules metadata", function () {
|
||||
assert.deepEqual(transform('import { externalName as localName } from "external";').metadata.modules.imports[0], {
|
||||
source: "external",
|
||||
imported: ["externalName"],
|
||||
specifiers: [{
|
||||
kind: "named",
|
||||
imported: "externalName",
|
||||
local: "localName"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('import * as localName2 from "external";').metadata.modules.imports[0], {
|
||||
source: "external",
|
||||
imported: ["*"],
|
||||
specifiers: [{
|
||||
kind: "namespace",
|
||||
local: "localName2"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('import localName3 from "external";').metadata.modules.imports[0], {
|
||||
source: 'external',
|
||||
imported: ['default'],
|
||||
specifiers: [{
|
||||
kind: 'named',
|
||||
imported: 'default',
|
||||
local: 'localName3'
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('export * as externalName1 from "external";', {
|
||||
stage: 0
|
||||
}).metadata.modules.exports, {
|
||||
exported: ['externalName1'],
|
||||
specifiers: [{
|
||||
kind: 'external-namespace',
|
||||
exported: 'externalName1',
|
||||
source: "external",
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('export externalName2 from "external";', {
|
||||
stage: 0
|
||||
}).metadata.modules.exports, {
|
||||
exported: ["externalName2"],
|
||||
specifiers: [{
|
||||
kind: "external",
|
||||
local: "externalName2",
|
||||
exported: "externalName2",
|
||||
source: "external"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('export function namedFunction() {}').metadata.modules.exports, {
|
||||
exported: ["namedFunction"],
|
||||
specifiers: [{
|
||||
kind: "local",
|
||||
local: "namedFunction",
|
||||
exported: "namedFunction"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('export var foo = "bar";').metadata.modules.exports, {
|
||||
"exported": ["foo"],
|
||||
specifiers: [{
|
||||
kind: "local",
|
||||
local: "foo",
|
||||
exported: "foo"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform("export { localName as externalName3 };").metadata.modules.exports, {
|
||||
exported: ["externalName3"],
|
||||
specifiers: [{
|
||||
kind: "local",
|
||||
local: "localName",
|
||||
exported: "externalName3"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('export { externalName4 } from "external";').metadata.modules.exports, {
|
||||
exported: ["externalName4"],
|
||||
specifiers: [{
|
||||
kind: "external",
|
||||
local: "externalName4",
|
||||
exported: "externalName4",
|
||||
source: "external"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform('export * from "external";').metadata.modules.exports, {
|
||||
exported: [],
|
||||
specifiers: [{
|
||||
kind: "external-all",
|
||||
source: "external"
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(transform("export default function defaultFunction() {}").metadata.modules.exports, {
|
||||
exported: ["defaultFunction"],
|
||||
specifiers: [{
|
||||
kind: "local",
|
||||
local: "defaultFunction",
|
||||
exported: "default"
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
test("ignore option", function () {
|
||||
assert.ok(transform("", {
|
||||
ignore: "node_modules",
|
||||
filename: "/foo/node_modules/bar"
|
||||
@@ -45,7 +153,7 @@ suite("api", function () {
|
||||
}).ignored);
|
||||
});
|
||||
|
||||
test("only", function () {
|
||||
test("only option", function () {
|
||||
assert.ok(!transform("", {
|
||||
only: "node_modules",
|
||||
filename: "/foo/node_modules/bar"
|
||||
@@ -77,7 +185,7 @@ suite("api", function () {
|
||||
}).ignored);
|
||||
});
|
||||
|
||||
suite("getModuleId() {} option", function () {
|
||||
suite("getModuleId option", function () {
|
||||
// As of this commit, `getModuleId` is the only option that isn't JSON
|
||||
// compatible which is why it's not inside /test/core/fixtures/transformation
|
||||
|
||||
@@ -94,7 +202,7 @@ suite("api", function () {
|
||||
assert.equal(result.code, expected);
|
||||
}
|
||||
|
||||
test("{ modules: \"amd\" }", function () {
|
||||
test("amd", function () {
|
||||
var expected = [
|
||||
"define('foo/bar', ['exports'], function (exports) {",
|
||||
" 'use strict';",
|
||||
@@ -106,7 +214,7 @@ suite("api", function () {
|
||||
getModuleNameTest("amd", expected);
|
||||
});
|
||||
|
||||
test("{ modules: \"umd\" }", function () {
|
||||
test("umd", function () {
|
||||
var expected = [
|
||||
"(function (global, factory) {",
|
||||
" if (typeof define === 'function' && define.amd) {",
|
||||
@@ -130,7 +238,7 @@ suite("api", function () {
|
||||
getModuleNameTest("umd", expected);
|
||||
});
|
||||
|
||||
test("{ modules: \"system\" }", function () {
|
||||
test("system", function () {
|
||||
var expected = [
|
||||
"System.register('foo/bar', [], function (_export) {",
|
||||
" 'use strict';",
|
||||
@@ -196,7 +304,7 @@ suite("api", function () {
|
||||
}, /Unknown helper foob/);
|
||||
});
|
||||
|
||||
test("resolveModuleSource", function () {
|
||||
test("resolveModuleSource option", function () {
|
||||
var actual = 'import foo from "foo-import-default";\nimport "foo-import-bare";\nexport { foo } from "foo-export-named";';
|
||||
var expected = 'import foo from "resolved/foo-import-default";\nimport "resolved/foo-import-bare";\nexport { foo } from "resolved/foo-export-named";';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user