Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Conversation

@yurydelendik
Copy link
Contributor

Associated Issue: #3817

Summary of Changes

  • allows to send source text independent from parsing of the scopes
  • parsing scopes to extract positions and its scope of every symbol in the source code

Copy link
Contributor

@codehag codehag left a 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

parent: TempScope | null,
loc: BabelLocation
): TempScope {
let result = {
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be const

parent,
scopes: [],
loc: loc,
names: Object.create(null)
Copy link
Contributor

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?

function _parseDeclarator(
declaratorId: Node,
targetScope: TempScope,
kind: string
Copy link
Contributor

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

let result = {
type,
parent,
scopes: [],
Copy link
Contributor

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?

name: string,
loc: BabelLocation
) {
for (let s = scope; s; s = s.parent) {
Copy link
Contributor

@codehag codehag Sep 6, 2017

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)
  )
}

Copy link
Contributor Author

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.

let search = parsedScopes;
let found = [];
while (search) {
let foundOne = search.some(s => {
Copy link
Contributor

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);


import type { Source, SourceId } from "debugger-html";

var cachedSources = new Map();
Copy link
Contributor

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?

return a.line == b.line ? a.column - b.column : a.line - b.line;
}

var parsedScopesCache = new Map();
Copy link
Contributor

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

if (!cachedSources.has(sourceId)) {
throw new Error(`${sourceId} was not provided.`);
}
// $FlowIgnore
Copy link
Contributor

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?

Copy link
Contributor Author

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 = {
Copy link
Contributor

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");

});
}

function _parseJSScopes(source: Source) {
Copy link
Contributor

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?

Copy link
Contributor

Choose a reason for hiding this comment

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

probably private

Copy link
Contributor

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?

@yurydelendik
Copy link
Contributor Author

Moved scope parsing related code to the firefox-devtools/devtools-core#656

Copy link
Contributor

@jasonLaster jasonLaster left a 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();
}
Copy link
Contributor

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

#3953

@codecov
Copy link

codecov bot commented Sep 13, 2017

Codecov Report

Merging #3852 into master will decrease coverage by 0.04%.
The diff coverage is 25%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
src/actions/sources.js 76.92% <0%> (-3.08%) ⬇️
src/actions/navigation.js 10% <0%> (-0.53%) ⬇️
src/utils/parser/index.js 100% <100%> (ø) ⬆️

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 4b63f2e...ba8877d. Read the comment docs.

@yurydelendik
Copy link
Contributor Author

Depends on #4008

Copy link
Contributor

@jasonLaster jasonLaster left a comment

Choose a reason for hiding this comment

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

👍

@jasonLaster jasonLaster merged commit 07107b7 into firefox-devtools:master Sep 14, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants