-
Notifications
You must be signed in to change notification settings - Fork 333
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
Move to ES6 #503
Move to ES6 #503
Conversation
let grammar = editor.getGrammar(); | ||
let language = kernelManager.getLanguageFor(grammar); | ||
let kernel = kernelManager.getRunningKernelFor(language); | ||
if (kernel == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(!kernel)
|
||
let foldable = this.editor.isFoldableAtBufferRow(row); | ||
let foldRange = this.editor.languageMode.rowRangeForCodeFoldAtBufferRow(row); | ||
if ((foldRange == null) || (foldRange[0] == null) || (foldRange[1] == null)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is how decaffeinate deals with ?
. 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should do the job:
if (!foldRange || !foldRange[0] || !foldRange[1])
if code? | ||
return code.replace /\r\n|\r/g, '\n' | ||
normalizeString(code) { | ||
if (code != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
return range | ||
getFoldRange(row) { | ||
let range = this.editor.languageMode.rowRangeForCodeFoldAtBufferRow(row); | ||
if (__guard__(this.getRow(range[1] + 1), x => x.trim()) === 'end') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! So decaffeinate sometimes uses a __guard__
...
|
||
unless regexString? | ||
return [start, end] | ||
if (regexString == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto (I'm going to stop marking these bugs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll cleanup the rest. 👍
range.push(i); | ||
} | ||
return range; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing EOL
function __guard__(value, transform) { | ||
return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; | ||
} | ||
function __range__(left, right, inclusive) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OMG!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed them in this commit.
@@ -1,95 +1,54 @@ | |||
_ = require 'lodash' | |||
let Config; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reckon this line can go.
@_kernelSpecs = @getKernelSpecsFromSettings() | ||
export default class KernelManager { | ||
constructor() { | ||
this.getAllKernelSpecs = this.getAllKernelSpecs.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I actually have no idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, you're right. This can be removed 👍
export default class KernelManager { | ||
constructor() { | ||
this.getAllKernelSpecs = this.getAllKernelSpecs.bind(this); | ||
this.getKernelSpecsFromJupyter = this.getKernelSpecsFromJupyter.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
marker = @editor.markBufferPosition | ||
row: row | ||
// coffeelint: disable = missing_fat_arrows | ||
let Hydrogen; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove?
this.subscriptions = new CompositeDisposable; | ||
|
||
this.subscriptions.add(atom.commands.add('atom-text-editor', { | ||
['hydrogen:run']: () => this.run(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are the square brackets really necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are just an artifact from decaffeinate.
export default class HydrogenKernel { | ||
constructor(_kernel) { | ||
this._kernel = _kernel; | ||
this.destroyed = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destroyed
should belong to _kernel
, since it's _kernel
's responsibility to set it to true
.
HydrogenKernel
is just an API wrapper around Kernel
. All the Kernel
state should be kept in Kernel
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that destroyed
is intentionally a part of the plugin API (i.e. plugins are expected and encouraged to use it). It can be switched to a property that proxies to _kernel
, but removing it entirely is a breaking change. For a plugin API, stability is more important than perfection -- i.e. I would encourage not getting into the habit of making breaking changes.
|
||
return @_hydrogen.kernel.getPluginWrapper() | ||
return this._hydrogen.kernel.getPluginWrapper(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is building a wrapper so expensive that a getter makes a difference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so that a plugin always gets the same wrapper object for the same kernel (same reference, not just equal-by-value). This should be true no matter the source API call, e.g. onDidChangeKernel
vs. getActiveKernel
.
Plugins need to be able to store metadata per-kernel. I decided to go with the approach of letting them attach custom fields to the wrapper object, and expecting the fields to be there later on. (It's possible to make a breaking change to some uuid-based thing, but that's separate from ES6 migration. Especially since hydrogen has no native notion of kernel ids.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so that a plugin always gets the same wrapper object for the same kernel (same reference, not just equal-by-value).
Wouldn't you get the same wrapper if the wrapper is created by Kernel's constructor?
Plugins need to be able to store metadata per-kernel.
That's a bad pattern, because API users don't have any guarantee to avoid name clashes.
Composition would be simple and safer pattern:
let myH2Kernel = {
kernel: kernelWrapper,
myMetadata1: myMetadata1,
myMetadata2: myMetadata2,
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name clashes are definitely a real issue, but the pattern you suggest is not an ideal solution either. If you listen to onDidChangeKernel
events, you get wrapper objects and not any custom struct. So each plug in will need to end up rolling their own dictionary lookup to fix that. I think adding some methods to encourage better namespacing (e.g. getData (namespace)
), or figuring out how to return a different set of wrapper objects to each consumer, are more promising approaches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! I see where you're coming from. Equality should work in this case; e.g.:
> var a = {}; (function(paramA) { return paramA === a; })(a);
true
this.cancel = this.cancel.bind(this); | ||
} | ||
|
||
static content(prompt) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't make sense that this method is static. Static methods don't use this
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored it in #508
if (this._executionCount === null) { | ||
return 'Copy to clipboard'; | ||
} else { | ||
return `Copy to clipboard (Out[${this._executionCount}])`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
race condition? Is there any guarantee that title
is invoked before the next _executionCount
update? This is important for kernels that can update their output asynchronously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, could you explain the race condition? I don't see any. Note that title()
gets called during the mouseover event, not at construction-time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My misunderstanding! I missed that addResult
is only invoked with results for a given request (and thus a unique execution count).
} | ||
constructor(...args) { | ||
super(...args); | ||
this.confirm = this.confirm.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this necessary?
constructor(...args) { | ||
super(...args); | ||
this.confirm = this.confirm.bind(this); | ||
this.cancel = this.cancel.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
} | ||
constructor(...args) { | ||
super(...args); | ||
this.confirm = this.confirm.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this necessary?
constructor(...args) { | ||
super(...args); | ||
this.confirm = this.confirm.bind(this); | ||
this.close = this.close.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
this.hide(); | ||
atom.workspace.addRightPanel({item: this.element}); | ||
constructor(kernel) { | ||
this.resizeStarted = this.resizeStarted.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this necessary?
atom.workspace.addRightPanel({item: this.element}); | ||
constructor(kernel) { | ||
this.resizeStarted = this.resizeStarted.bind(this); | ||
this.resizeStopped = this.resizeStopped.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
constructor(kernel) { | ||
this.resizeStarted = this.resizeStarted.bind(this); | ||
this.resizeStopped = this.resizeStopped.bind(this); | ||
this.resizeSidebar = this.resizeSidebar.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are actually necessary. I think because they are used here.
I haven't been able to go through all the commits. Here are a few more comments:
|
no-underscore-dangle: [0] | ||
no-useless-escape: [0] | ||
prefer-rest-params: [0] | ||
class-methods-use-this: [0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to remove this again and use static
methods as you mentioned above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to remove this again and use static methods as you mentioned above.
My bad. This won't work.
I'm using this rule mainly because it would error in files like [kernel.js] since a lot of the methods don't use this
.
|
||
rules: | ||
no-console: [0] | ||
no-use-before-define: [0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
no-console: [0] | ||
no-use-before-define: [0] | ||
no-param-reassign: [0] | ||
no-underscore-dangle: [0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we using underscore dangle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep we have methods like _execute
etc.
no-use-before-define: [0] | ||
no-param-reassign: [0] | ||
no-underscore-dangle: [0] | ||
no-useless-escape: [0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise it would complain about this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's actually a bug, isn't it?
Shouldn't it be?
const regexString =
`${escapedCommentStartString}(%%| %%| <codecell>| In\\[[0-9 ]*\\]:?)`;
This way we keep the git history.
and add babel-eslint to dependencies
Caused by if(0) returning false
Rebased |
Fixes #494
This will port all coffeescript code to ES6. There will be probably a few bugs since I didn't test all functionality.