Skip to content

Commit

Permalink
Only reference helpers from external helpers or runtime helpers if th…
Browse files Browse the repository at this point in the history
…ey are known to be available.
  • Loading branch information
loganfsmyth committed Jul 29, 2018
1 parent adca165 commit 156c1dd
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 8 deletions.
14 changes: 14 additions & 0 deletions lib/third-party-libs.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ declare module "lodash/merge" {
declare export default <T: Object>(T, Object) => T;
}

declare module "semver" {
declare module.exports: {
valid(v: string): boolean;
gt(v1: string, v2: string): boolean;
lt(v1: string, v2: string): boolean;
major(v: string): number;
minor(v: string): number;
patch(v: string): number;
satisfies(v1: string, r1: string): boolean;

intersects(r1: string, r2: string): boolean;
}
}

declare module "source-map" {
declare export type SourceMap = {
version: 3,
Expand Down
36 changes: 33 additions & 3 deletions packages/babel-core/src/transformation/file/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { NodePath, Hub, Scope } from "@babel/traverse";
import { codeFrameColumns } from "@babel/code-frame";
import traverse from "@babel/traverse";
import * as t from "@babel/types";
import semver from "semver";

import type { NormalizedFile } from "../normalize-file";

Expand Down Expand Up @@ -64,6 +65,14 @@ export default class File {
}

set(key: mixed, val: mixed) {
if (key === "helpersNamespace") {
throw new Error(
"Babel 7.0.0-beta.56 has dropped support for the 'helpersNamespace' utility." +
"If you are using @babel/plugin-external-helpers you will need to use a newer " +
"version than the one you currently have installed.",
);
}

this._map.set(key, val);
}

Expand Down Expand Up @@ -136,17 +145,38 @@ export default class File {
);
}

/**
* Check if a given helper is available in @babel/core's helper list.
*
* This _also_ allows you to pass a Babel version specifically. If the
* helper exists, but was not available for the full given range, it will be
* considered unavailable.
*/
availableHelper(name: string, versionRange: ?string) {
let minVersion;
try {
minVersion = helpers.minVersion(name);
} catch (err) {
if (err.code !== "BABEL_HELPER_UNKNOWN") throw err;

return false;
}

return (
typeof versionRange !== "string" ||
(!semver.intersects(`<${minVersion}`, versionRange) &&
!semver.intersects(`>=8.0.0`, versionRange))
);
}

addHelper(name: string): Object {
const declar = this.declarations[name];
if (declar) return t.cloneNode(declar);

const generator = this.get("helperGenerator");
const runtime = this.get("helpersNamespace");
if (generator) {
const res = generator(name);
if (res) return res;
} else if (runtime) {
return t.memberExpression(t.cloneNode(runtime), t.identifier(name));
}

const uid = (this.declarations[name] = this.scope.generateUidIdentifier(
Expand Down
4 changes: 4 additions & 0 deletions packages/babel-core/src/transformation/plugin-pass.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export default class PluginPass {
return this._map.get(key);
}

availableHelper(name: string, versionRange: ?string) {
return this.file.availableHelper(name, versionRange);
}

addHelper(name: string) {
return this.file.addHelper(name);
}
Expand Down
7 changes: 6 additions & 1 deletion packages/babel-helper-module-imports/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ function test(sourceType, opts, initializer, expectedCode) {
function({ types: t }) {
return {
pre(file) {
file.set("helpersNamespace", t.identifier("babelHelpers"));
file.set("helperGenerator", name =>
t.memberExpression(
t.identifier("babelHelpers"),
t.identifier(name),
),
);
},
visitor: {
Program(path) {
Expand Down
Loading

0 comments on commit 156c1dd

Please sign in to comment.