-
Notifications
You must be signed in to change notification settings - Fork 464
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
Refactoring / back-porting selectors and extend #2908
Conversation
e1e806f
to
1312e93
Compare
Had to throw out some facy template functions for dart sass "compatibility". |
By porting over dart sass' extend behaviour does this mean loose extending of compound selectors? I believe this feature was deprecated and maybe even removes from dart sass' entirely. This is important to know given its a breaking change and we haven't had a deprecation period yet. |
Thanks, good point. It seems that spec tests for this have gone missing?
Should be simple enough to get the old behavior back though. Will try to come up with a fix. |
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.
Reviewing this piecemeal. Not the big picture, which I don't fully understand yet, but C++ stuff.
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 not a big fan of ObjPtrEquality*
and PtrObjEquality*
. They are very similar and confusing.
As I mentioned before, I don't think (Obj)?Ptr(Equality|Hash)(Fn)?
functions and structs should exist: they are the default comparison / hash functions, and having them is confusing because the reader thinks they are custom / non-default ones. It is also confusing because we now have very similarly named PtrObj
functions / structs.
Please, let's properly clean up before submitting: it is easier to clean up at review time than later. |
The problem is we don't always want the same behavior on every hash. Sometimes I want the hash to have unique pointers and sometimes I want the hash to have unique objects. To do this I need to pass the functor structs to the hash declaration. Also we mostly use SharedImpl as keys, so for those the default implementation is even less obvious. Therefore I needed these explicit functions and functors. On the naming I could agree a bit more. But I believe it is not too hard to get it right. |
It is idiomatic for smart pointers (like
I have an idea about this:
There is no need for |
I need to compare objects in hashes here: https://github.com/sass/libsass/pull/2908/files#diff-61f3048af5edbbaf974fb08271245c6eR32 ... also see the first one, that compares the raw pointers. |
0ba6876
to
7188542
Compare
Polished up the extender code once more ... |
3478153
to
232ac40
Compare
Something tripped up MSVC debug build, need to go back to last success and go from there ... |
17fd694
to
fe268ae
Compare
b18ba7d
to
909b970
Compare
Latest error: Failing test: %default-color {color: red}
%alt-color {color: green}
%default-style {
@extend %default-color;
&:hover {@extend %alt-color}
&:active {@extend %default-color}
}
.test-case {@extend %default-style} (from sass-spec\spec\extend-tests\215_test_multiple_source_redundancy_elimination.hrx) |
Maybe if you have time feel free to debug. I'm going to bed now. I think the latest commit is ok, but changing the other function prototypes keep triggering MSVC debug build. Will continue tomorrow. |
Figured out where extensionsByExtender[simple].push_back(withExtender); Here once enough elements are pushed, Since this invalidates the pointers ( This is unsafe because pointer addresses may change when the vector resizes its buffer. Patch to expose the issue (not a fix): https://gist.github.com/glebm/75a6ddf05cf4533e79601adddb6047fc |
I feel that it might have something to do with |
e7300f8
to
8ca3b00
Compare
Definitely not iterators. This is caused by pointers (SharedImpl) pointing to elements in a vector storage. When the backing vector's buffer is resized, these SharedImpls' become dangling pointers. Evidenced by stepping through with a debugger to the crash (more obvious with my patch above). |
IMO the for range loops do iterate from begin to end, so if in the meantime, the underlying container is relocated, it makes kinda sense that the iteration in progress is about to fail. I could be wrong but my tests (I did now install MSVC 2013) seem to indicate that this is the case. Not saying the other thing you mention is also an issue. |
OK, got it to pass both tests. Will squash now to see what I got to clean up ... |
13f3b2d
to
bb1e687
Compare
So I finally seem to have found the culprit, took way longer than it should have 😓 It basically boils down to: - for (Extension extension : oldExtensions) {
- for (size_t i = 0; i < oldExtensions.size(); i += 1) {
+ for (size_t i = 0, iL = oldExtensions.size(); i < iL; i += 1) { As expected we seem to append to the underlying vector somewhere. As I wrote earlier, this does invalidate the for range based loop, but also made clang on mac read the newly added items, which is not how the original dart sass behavior is (probably because it does in fact work on a copy). That's why once MSVC timed out and on another occasion clang on mac os did. Will finish up now ... |
7265ab3
to
dadadd0
Compare
Just to gain back my sanity, I made a test: for (size_t i = 0, iL = oldExtensions.size(); i < iL; i += 1) {
if (iL != oldExtensions.size()) {
std::cerr << "Gotcha\n";
} And who would have guessed:
The actual change is in the same loop: sources.insert(complex, mergeExtension(
sources.get(complex), withExtender)); |
a911b38
to
62484b1
Compare
30fe17e
to
7c40b00
Compare
That should be the 🚀 final version. Just waiting for 💚 ! |
While CI is doing its job, I just wanted to mention the magnitude of this commit. It closes and cuts-off one of the most "alien" code bases we dragged around for so many years, namely node.cpp and extend.cpp. To bad the bounty is no longer up for grab. Nearly 8000 lines of code mean about 20% of the whole libsass code base. And thanks to the base work by dart-sass and @nex3 this was possible. The time investment was something around 200h as I initially estimated. 🔥 🎆 🍻 |
Here we go 🛫 |
Great work! 🎉 |
Very impressive effort
…On Mon., 17 Jun. 2019, 9:00 pm Gleb Mazovetskiy, ***@***.***> wrote:
Great work! 🎉
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2908?email_source=notifications&email_token=AAENSWAJHRFKCQH447Y7OQTP27NK7A5CNFSM4HYKAJQ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODX4EHKQ#issuecomment-502809514>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAENSWDNU4GOID354IEERTDP27NK7ANCNFSM4HYKAJQQ>
.
|
Needs sass/sass-spec#1396
Continued from #2904.
I know this is a big commit, and it took quite some effort to get this ready
for review. Positive thing is that it removes more lines than it adds 😄
Feel free to poke at the changes. I know there are still a lot of loose ends.
Some stuff is just there to really make it work. I tried hard to clean this up
to at least have a better state than before. But maybe don't be too picky.
There are over 7000 lines of code. Easy to nitpick, but I would like to get
this merged at some point, so please focus on the big picture. As always
we can adjust and polish spots in the future.
Main features
New selector structure (equal to dart sass)
SelectorList
is an array ofComplexSelector
ComplexSelector
is an array ofSelectorComponent
SelectorComponent
is aspace
SelectorComponent
is a base class for eitherSelectorCombinator
is either>
,+
or~
CompoundSelector
in an array ofSimple_Selector
ID_Selector
)I removed
Parent_Selector
, but there is still theParent_Refernce
. The referenceis only used in interpolations. Actual selector now get rid of all the fake parent. The
logic is that a parent selector can only occur at the begining of a
CompoundSelector
.Therefore this class has a flag
hasRealParent
that indicates that we parsed a real parent!reference on the input. Implicit connections (previously fake parents) are now indicated
by the
chroots
flag on theComplexSelector
. If a selector is chrooted, it should notconnect implicitly to its parent (
hasRealParent
might still play a role here).Known spots for improvement
originalSelectorStack
in order to support parent resolvinglike dart sass does. Dart sass stores both items in an object, which we lack.
classes only to store this interpolation. Find or create/adjust a parser that
parses exactly the schema we need for this interpolation. For now it works.
by the target node (e.g.
SelectorList
vsRuleset
). It IMO makes more senseto store the
Selector_Schema
for aRuleset
on hatRuleset
. Once it isevaled the selector object can be set. This should solve the disambiguate from
storing a
Selector_Schema
as a baseSelector
.Known spots to develop further
TO_CSS
output target. Currently it takes care to throw anerror if something css incompatible is being printed (e.g. invalid units).
ToDo: we might should move more error into this code path (TBD)
CssMediaRule
class. On extend we directly work withmedia-queries and need them to be evaluated and parsed beforehand.
Dart-sass seems to have certain ast-nodes only for static css syntax. This
is not only useful when parsing pure css, once nodes are evaluated, their
result should match that of any static css. If we ever want to support
a pure css parser, we probably need to adopt this route anyway!