Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite Hub as interface #5047 #5050

Merged
merged 3 commits into from Feb 13, 2017
Merged

Rewrite Hub as interface #5047 #5050

merged 3 commits into from Feb 13, 2017

Conversation

yongxu
Copy link
Contributor

@yongxu yongxu commented Dec 28, 2016

Q A
Patch: Bug Fix? yes
Major: Breaking Change? no
Minor: New Feature? yes
Deprecations? no
Spec Compliancy? yes
Tests Added/Pass? yes
Fixed Tickets Fixes #5047, Fixes #4640, Fixes #4413
License MIT
Doc PR no
Dependency Changes no

This PR implements Rewrite Hub as interface #5047 <--check out more details in this issue
will make babel-traverse a standalone package

@codecov-io
Copy link

codecov-io commented Dec 28, 2016

Codecov Report

❗ No coverage uploaded for pull request base (master@283d9cb).

@@            Coverage Diff            @@
##             master    #5050   +/-   ##
=========================================
  Coverage          ?   89.22%           
=========================================
  Files             ?      203           
  Lines             ?     9848           
  Branches          ?     2628           
=========================================
  Hits              ?     8787           
  Misses            ?     1061           
  Partials          ?        0
Impacted Files Coverage Δ
packages/babel-traverse/src/path/index.js 88.65% <100%> (ø)
packages/babel-traverse/src/hub.js 100% <100%> (ø)
packages/babel-traverse/src/scope/index.js 84.63% <100%> (ø)
packages/babel-traverse/src/index.js 93.47% <100%> (ø)
packages/babel-traverse/src/path/introspection.js 57.95% <75%> (ø)
...ckages/babel-core/src/transformation/file/index.js 90.42% <80%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 283d9cb...7f1e8dc. Read the comment docs.

@@ -9,7 +9,8 @@ import * as cache from "./cache";

export { default as NodePath } from "./path";
export { default as Scope } from "./scope";
export { default as Hub } from "./hub";
import type Hub from "./hub";
export type { Hub };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess there isn't an export shortcut as in ES6 ? Like:

export type Hub from "./hub";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no it isn't, this is how flow export types. this has no influence to the compiled code.

message,
loc: this.node.loc
});
this.hub.mark && this.hub.mark(type, message, this.node.loc);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent in coding style, could you use an explicit if there?

addHelper: (name: string) => Object;
getScope: () => Object;
getCode: () => string;
buildError:(node: Object, msg: string, Error: Error) => Error;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if some users rely on this class.

I would like to keep the class there, what do you think? I'm not sure because the class is empty anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, totally! I think using export default class Hub instead export type Hub would probably be good here.
Though Hub itself wasn't been referred in repo, it is possible that someone used Hub to store states. We can totally keep it.

@@ -50,7 +50,8 @@ export default function ({ types: t }) {
: null;

const fileNameIdentifier = path.scope.generateUidIdentifier(FILE_NAME_VAR);
path.hub.file.scope.push({id: fileNameIdentifier, init: t.stringLiteral(fileName)});
const scope = path.hub.getScope();
scope && scope.push({id: fileNameIdentifier, init: t.stringLiteral(fileName)});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use an explicit if there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absolutely! Thanks for reviewing. Working on it :)

export type Hub = {
mark: (type: string, message: string) => void;
addHelper: (name: string) => Object;
getScope: () => Object;
Copy link
Member

@xtuc xtuc Dec 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think getScope returns a Scope object.

@yongxu
Copy link
Contributor Author

yongxu commented Dec 31, 2016

@xtuc what do you think about this new version? I made some changes based on your suggestion.
happy new year btw 👍

getCode: () => this.code,
getScope: () => this.scope,
buildError: this.buildCodeFrameError.bind(this)
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you gonna replace the object with the Hub class in packages/babel-traverse/src/hub.js. Can we replace it?

Like:

hub: HubInterface;

this.hub = new Hub(this);

constructor(file, options) {
this.file = file;
this.options = options;
buildError(node, msg, Error): Error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coverage fails there because the method buildError isn't tested.

If you move the content of the object (as described above) there, we need to add tests for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test for this, though the test doesn't seem very necessary.
It did pass the coverage test now! Thanks for reviewing :)

@yongxu
Copy link
Contributor Author

yongxu commented Jan 8, 2017

@xtuc any progress or request on this PR? Thanks

@xtuc xtuc self-requested a review January 10, 2017 11:46
this.file = file;
this.options = options;
buildError(node, msg, Error): Error {
return new TypeError(msg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be new Error since this function should return a type based on the third parameter of the function.

@@ -99,7 +100,19 @@ export default class File extends Store {
this.code = "";
this.shebang = "";

this.hub = new Hub(this);
this.hub = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you removed the file property from the interface, but we'll definitely need to keep it for the usage in babel-core at least, or else it will break people's plugins that read properties off of hub. For example some plugins do path.hub.file.opts.filename to get the name of the file being compiled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch! fixed it :)

this.file = file;
this.options = options;
buildError(node, msg, BuildError = TypeError): Error {
return new BuildError(msg);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@loganfsmyth what do you think about this approach? when Error is not specified, use TypeError as defaiult.
also changed its name to BuildError in the implementation, which is more descriptive IMO.

@babel-bot
Copy link
Collaborator

Hey @yongxu! It looks like one or more of your builds have failed. I've copied the relevant info below to save you some time.

@loganfsmyth loganfsmyth merged commit 2985597 into babel:master Feb 13, 2017
@hzoo
Copy link
Member

hzoo commented Feb 13, 2017

Whoo thanks @yongxu 🎉, sorry for the delay!! 🙏

@hzoo hzoo added PR: Internal 🏠 A type of pull request used for our changelog categories PR: Bug Fix 🐛 A type of pull request used for our changelog categories labels Feb 13, 2017
@xtuc
Copy link
Member

xtuc commented Feb 13, 2017

Nice work 👍

@yongxu
Copy link
Contributor Author

yongxu commented Feb 13, 2017

Thanks guys! Appreciate it, will contribute more :)

@loganfsmyth
Copy link
Member

Heya @yongxu, unfortunately I missed in review that this would be a breaking change, so we've had to revert it in #5306 due to reports of errors in #5305.

@yongxu
Copy link
Contributor Author

yongxu commented Feb 14, 2017

I am really sorry about this breaking issue @loganfsmyth , I am looking into it.

danez added a commit that referenced this pull request Feb 14, 2017
* Add new flow preset (#5288)

* Fix PathHoister hoisting JSX member expressions on "this". (#5143)

The PathHoister ignored member references on "this", causing it
to potentially hoist an expression above its function scope.

This patch tells the hoister to watch for "this", and if seen,
mark the nearest non-arrow function scope as the upper limit
for hoistng.

This fixes #4397 and is an alternative to #4787.

* Fix PathHoister hoisting before bindings. (#5153)

Fixes #5149 and enables a few additional safe hoists.

* Fix linting error

* feature: Support pure expressions in transform-react-constant-elements (#4812)

* Fix loose for-of with label (#5298)

* Rewrite Hub as interface #5047 (#5050)

* Rewrite Hub as interface #5047

* Update index.js

* Avoid adding unnecessary closure for block scoping (#5246)

When you write

```
for (const x of l) {
  setTimeout(() => x);
}
```

we need to add a closure because the variable is meant to be block-scoped and recreated each time the block runs. We do this.

However, we also add the closure when no loop is present. This isn't necessary, because if no loop is present then each piece of code runs at most once. I changed the transform to only add a closure if a variable is referenced from within a loop.

* Add greenkeeperio-bot to mention-bot blacklist (#5301) [skip ci]

* Upgrade lerna to current beta. (#5300)

* Revert "Upgrade lerna to current beta." (#5303)

* Add charset so tests work with convert-source-map@>1.4 (#5302)

* Add CHANGELOG for 6.23.0 [skip ci] (#5304)

* Update babel-types README from script.

* v6.23.0

* Revert change that lerna force-committed.

* Revert "Rewrite Hub as interface #5047" (#5306)

* v6.23.1

* Revert lerna again
@loganfsmyth
Copy link
Member

@yongxu Let's pull this conversation back over here, since the other thread is about the revert.

The issue that this case is because babel-core is set up to depend on essentially babel-traverse@>6.x. That means that any past version of babel-core will use the most recent version of babel-traverse. That was the core issue here, because the old babel-coreversion would callnew Hub(this)and create aHubinstance with only a.fileproperty and no methods. But the new interface defined bybabel-traverse` in this PR.

babel-traverse's usage of new methods on Hub is a breaking change, since those methods were not required for usage of the old version of babel-traverse.

@yongxu
Copy link
Contributor Author

yongxu commented Feb 20, 2017

Yeah that is very true. Now I totally agree with you to leave this out in the current master.
I did see a 7.0 branch however, should I make another PR targeting that branch instead?

@loganfsmyth
Copy link
Member

Yup! If you'd like to resubmit this for 7.0, I think that would be fine, as long as you are cool with waiting a bit longer for it to be released.

@olsonpm
Copy link

olsonpm commented Mar 3, 2017

So I'm trying to use babel-traverse as a standalone library (just traverses an ast built from babylon). I found this pr and merged it into a local clone of babel branch 7.0. The below file links all point to yongxu's fork.

When trying to use path.buildCodeFrameError I get the following error

TypeError: Cannot read property 'buildError' of undefined
    at NodePath.buildCodeFrameError (/.../babel/packages/babel-traverse/lib/path/index.js:174:20)

where that line in source can be found here

buildCodeFrameError(msg: string, Error: typeof Error = SyntaxError): Error {
    return this.hub.buildError(this.node, msg, Error);
}

Looking into it, I don't see where a hub object is created besides in babel-core, which isn't included in babel-traverse. When I debug, sure enough the hub property is always undefined.

What am I missing? I just don't see how this is a standalone package as-is.

@yongxu
Copy link
Contributor Author

yongxu commented Mar 7, 2017

@olsonpm If you are using babel-traverse as a standalone and call hub, you'll have to inject hub yourself.

I think it would be great to have a definition for the hub interface, or probably a better name. I'll take a look sometime soon.

This PR was reverted due to minor version resolving issue. Now since we are progressing to v7, should we try to merge it back? @loganfsmyth

Sorry for the delayed response, had been too busy recently. :)

existentialism pushed a commit that referenced this pull request May 19, 2017
* Rewrite Hub as interface #5047

* Update index.js
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Bug Fix 🐛 A type of pull request used for our changelog categories PR: Internal 🏠 A type of pull request used for our changelog categories
Projects
None yet
7 participants