-
Notifications
You must be signed in to change notification settings - Fork 751
Parse to extract all scopes and bindings. #3852
Conversation
codehag
left a comment
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.
Phew! great work here. a few comments. let me know if you have questions
src/utils/parser/getScopes.js
Outdated
| parent: TempScope | null, | ||
| loc: BabelLocation | ||
| ): TempScope { | ||
| let result = { |
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 be const
src/utils/parser/getScopes.js
Outdated
| parent, | ||
| scopes: [], | ||
| loc: loc, | ||
| names: Object.create(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.
why do we want to use Object.create here?
src/utils/parser/getScopes.js
Outdated
| function _parseDeclarator( | ||
| declaratorId: Node, | ||
| targetScope: TempScope, | ||
| kind: string |
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.
type might be a bit clearer here
src/utils/parser/getScopes.js
Outdated
| let result = { | ||
| type, | ||
| parent, | ||
| scopes: [], |
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 might be renamed children?
src/utils/parser/getScopes.js
Outdated
| name: string, | ||
| loc: BabelLocation | ||
| ) { | ||
| for (let s = scope; s; s = s.parent) { |
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 is hard to tell what is going on here. if i am guessing i would say we are traversing the temp scope s via the parents, as long as we have a truthy s object. and within this loop we are taking... the first? name from the array names, and pushing the start location. probably to add up the locations until we have a line number value.
I gave it a try myself... not sure it is any better
traverseTempScope(tempScope, callback) {
function _recurse(s) {
if (!s) return;
if (name in s.names) {
callback(s.names[name].refs)
}
return _recurse(s.parent, callback);
}
}
function _recordIdentifierPosition(scope, name, loc) {
_traverseTempScope(
scope,
(nameRefs) => nameRefs.push(loc.start)
)
}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.
The recursive functions (even with tails call) are not really efficient in comparison with just a loop. I recommend to not introduce any unneeded recursion for simple algorithms, and in this case simple loop easier to read.
src/utils/parser/getScopes.js
Outdated
| let search = parsedScopes; | ||
| let found = []; | ||
| while (search) { | ||
| let foundOne = search.some(s => { |
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.
search.some stops execution after one is found; but we are modifying the found array here and the search object. perhaps what we want here again is reduce?
const found = search.reduce((found, s) => {
if (
_compareLocations(s.start, location) <= 0 &&
_compareLocations(location, s.end) < 0
) {
return [s, ...found];
}
return found;
})you can also factor that out into an independant function and do (imagining that the reduce is its own function, and the map is another):
return search.reduce(findLocations).map(createScope);
src/utils/parser/sources.js
Outdated
|
|
||
| import type { Source, SourceId } from "debugger-html"; | ||
|
|
||
| var cachedSources = new Map(); |
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 do we want to use var here? would let work?
src/utils/parser/getScopes.js
Outdated
| return a.line == b.line ? a.column - b.column : a.line - b.line; | ||
| } | ||
|
|
||
| var parsedScopesCache = new Map(); |
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.
we are using var here, is there a particular reason? i would expect let to be used in this case
src/utils/parser/sources.js
Outdated
| if (!cachedSources.has(sourceId)) { | ||
| throw new Error(`${sourceId} was not provided.`); | ||
| } | ||
| // $FlowIgnore |
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 are we ignoring here?
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.
Even if I did the check above, flow is convinced cacheSources.get can be undefined. Changing to ((x: any): Source) cast.
|
|
||
| describe("Parser.getScopes", () => { | ||
| it("parses simple generated/minified es5 source", () => { | ||
| const source = { |
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.
nit: we can use the parser's test helper and save this in its own file i think
its used via
import { getSource } from "../helpers";
//...
const source = getSource("getScopes/source1");
src/utils/parser/getScopes.js
Outdated
| }); | ||
| } | ||
|
|
||
| function _parseJSScopes(source: Source) { |
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.
what do the _ signify in these function names?
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.
probably private
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.
thats what i thought, but wouldn't it be private by default, since it isnt exported?
e0f9e89 to
827424c
Compare
827424c to
797f6a4
Compare
|
Moved scope parsing related code to the firefox-devtools/devtools-core#656 |
jasonLaster
left a comment
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.
Looks like a good start.
I don’t see where getScopes is used yet.
I mentioned this in a comment, but I think we can open a separate issue / PR for switching to a sources cache. I like it, but it is tough to review both changes at once
|
|
||
| export function clearSources() { | ||
| cachedSources = new Map(); | ||
| } |
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.
almost all of our APIs now expect to get a source.
I agree that this is a performance issue, but I think we should make the fix in a separate PR, that touches all of the spots.
https://github.com/devtools-html/debugger.html/blob/master/src/utils/parser/steps.js#L6-L8
https://github.com/devtools-html/debugger.html/blob/master/src/utils/parser/getSymbols.js#L335-L336
797f6a4 to
b476c20
Compare
Codecov Report
@@ Coverage Diff @@
## master #3852 +/- ##
=========================================
- Coverage 55.05% 55% -0.05%
=========================================
Files 132 132
Lines 5115 5123 +8
Branches 1051 1052 +1
=========================================
+ Hits 2816 2818 +2
- Misses 2299 2305 +6
Continue to review full report at Codecov.
|
|
Depends on #4008 |
d61366c to
ff305fb
Compare
ff305fb to
ba8877d
Compare
jasonLaster
left a comment
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.
👍
Associated Issue: #3817
Summary of Changes