Comments (18)
A very big thank you for this investigation (and for your product in general!)
from dirac.
I force updated the Chrome extension to the latest version, and I don't see this anymore, everything looks correct, sorry for the false alarm:
from dirac.
Another example, this time with the function parameter "regy":
from dirac.
I can confirm this. It is caused by the way ClojureScript generates Javascript code and how default DevTools select local variables for display. I believe if you break the code at the same spot in internal DevTools (without Dirac installed), you will experience a similar thing.
I haven't tried to counter it yet because I don't fully understand the mechanism. The only thing Dirac does is that it tries to sort properties and put null and undefined values at the end of list. This way it mitigates the problem a bit without losing any information.
But I don't see this feature in your screenshots. Have you disabled "Enable clustered locals" in Dirac DevTools extension preferences?
from dirac.
from dirac.
If I remember well, ClojureScript generated Javascript similar to this one:
if (condition) {
var v = exp1;
...
// breakpoint here
} else {
var v = exp2;
...
}
There are two variables named "v", you stopped in true branch, but DevTools sees all branches. Of course this gets worse when nested.
I believe this will have to be solved on DevTools side, to display only locals from relevant code branches.
from dirac.
Investigated this issue a bit today. Scratch my previous comment. Javascript scope variables work as expected.
The problem is in case with source maps. DevTools tries to map real variable names to original names. Unfortunately the implementation does not expect that multiple distinct variables could potentially map to the same name in original sources.
I was able to reproduce it on this minimal repro case:
(let [x 1]
(let [x 2]
(js-debugger)))
Which generates javascript similar to this:
var x = (1);
var x__$1 = (2);
debugger;
Both x
and x__$1
map to original name x
. If naive code wants to construct reverse mapping keyed by original name, it ends up with { "x": "x__$1" }
(which overwrote previous { "x": "x" }
).
I have identified multiple places where they use some intermediate data structure for reverse-mapping names and it does not expect multiple variables with the same name. This confuses lookups in code relying on those mappings.
@aslushnikov I believe commit decf4d4 needs a review.
Secondary problem is in the code producing source code decorations:
I think this will deserve a ticket upstream, because this needs to be fixed in general.
from dirac.
@darwin thank you for the investigation. Would you mind filing bugs on the crbug.com (and posting links here so that they're triaged quickly)?
If you have any time for the CL to address the issue, I'll be happy to review
from dirac.
@aslushnikov sure, will do (probably at the end of this week).
from dirac.
I was able to implement a fix but it will need deeper changes to resolve all remaining issues.
New observations:
SDK.TextSourceMap.findEntry
method was wrong in some cases- the problem is not only mapping of compiled names to duplicit original names. I found a case where even compiled names can be duplicit in the context of a given scope.
Original ClojureScript:
(defn breakpoint-demo [count]
(let [x 1]
(let [y 2]
(let [x 3
z #(println x)]
(js-debugger))))
Produces:
var x = (1);
var y = (2);
var x__$1 = (3);
var z = ((function (x__$1,y,x){
return (function (){
return cljs.core.println.call(null,x__$1);
});})(x__$1,y,x))
Compiled variable names x
,y
and x__$1
are present twice. Second time as args to the anonymous function.
Mapping from compiled to original names should be:
x -> x
y -> y
x__$1 -> x
x__$1 -> null (second)
y -> null (second)
x -> null (second)
z -> z
This means that we have to care about general case of duplicit compiled names pointing arbitrarily to (potentially) duplicit original names. Any code using plain names to uniquely identify something is potentially wrong, both when mapping compiled names to original ones and reverse.
Implementation notes:
- 2f1268b
SDK.TextSourceMap.findEntry
method was returning false positives in some cases, the culprit was!first
test which was preventing the whole condition in most cases - 65c9264
I was able to fixSourceMapNamesResolver
to be aware of duplicit names, but I wasn't able to properly fixSources.SourceMapNamesResolver.RemoteObject
becasue I cannot modify its API design (that would lead to avalanche of more changes). The methodsgetAllProperties
andsetPropertyValue
expect string names to identify properties. But names are not enough, we need some kind of id-system for property names so we can distinguish them even if they have duplicit names. - 0ed1b3b
I was able to fixJavaScriptSourceFrame
to properly render decoration widgets even exposed to duplicit names. The trick was to invent string-based id-system which is used to do proper mapping between properties and widgets (see getLocationId)
from dirac.
@mtruyens please test it again with v1.1.2 release and report back.
from dirac.
The changes in 1.1.2 release were not enough to fix everything :-(
Found pretty nasty bug in adba577.
from dirac.
Reported upstream as ticket 687772:
https://bugs.chromium.org/p/chromium/issues/detail?id=687772
from dirac.
Here's another example of this which is slightly different:
(ns source-map-test2.core)
(defn test-fn
[one-one]
(let [two-two 2]
((fn rebind [] one-one))
(js-debugger)))
(test-fn 1)
from dirac.
@danielcompton Could you confirm this in Dirac? Dirac has a patch for this issue.
from dirac.
Dirac maps them correctly, but uses the generated JS name (one_one
, rather than the original ClojureScript name (one-one
):
from dirac.
This is fishy. Are you sure you really ran the source-maps-enabled case under Dirac?
from dirac.
Please note that this feature is broken in latest ClojureScript 1.10.439 due to CLJS-2993.
You might want to stay on 1.10.339 which is last good version.
from dirac.
Related Issues (20)
- On Dev Tools, how can I switch from Console to Diract? Or, in other words, how can I execute step 5 of the Quick Start Guide?
- ns/as-alias not supported
- TypeError: this._prompt.belowEditorElement is not a function HOT 2
- Error: uiSourceCode expected to have scriptFile associated
- Sources > Filesystem > "Add Folder To Workspace" not working in Dirac 1.2.37 HOT 8
- Need *source-map-data-gen-col* binding HOT 1
- Dirac window is blank on startup in Dirac 1.2.38 HOT 2
- Internal Dirac Error TypeError: target.emulationAgent(...).setFocusEmulationEnabled is not a function HOT 1
- Custom formatters not always applied HOT 1
- Internal Dirac Error Cannot find context with specified id
- Recipe for build.boot HOT 1
- Add electron support HOT 2
- first
- windows installation HOT 1
- Run Dirac CLI in the background HOT 2
- Loopback mode and pausing on a breakpoint HOT 2
- Does dirac need a proxy ? HOT 1
- Failed to create a ProcessSingleton for your profile directory HOT 1
- Missing is<Browser> methods with recent versions of ClojureScript
- I can't run Dirac on MacOS, it keeps complaining about org.clojure/data.json - even though it is listed as a dependency HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dirac.