Skip to content
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

Refactor to remove Context dependency from To_String and others #1754

Merged
merged 8 commits into from
Jan 14, 2016

Conversation

mgreter
Copy link
Contributor

@mgreter mgreter commented Nov 24, 2015

This is a continuation #1736.

Premise: The Context is the main Object which manages and abstracts all internas for parsing and compiling. It takes an option C struct to construct and implements the parse and compile methods. It also serves as main lifecycle for created objects (as in Ast Nodes).

Currently we have still a lot of places which need the main Context (aka ctx) instance to be around, which makes it often impossible to call certain functions (like To_String visitor) from methods that simply don't have any direct connection to the main Context (and therefore don't have access to it).

In the past we mostly just passed around and stored the ctx everywhere. This worked as long as we lived inside our own execution path, but this first bit me when I wanted to expose operations and stringification on the C-API. It's absolutely legal to create two Sass Values outside of any actual Context and then call an operation on them. This is just one example where we need the ctx for mainly two reasons.

a) accessing the options (output style, precision and others)
b) to create object with a managed life-cycle

This PR will be a first round to finally decouple those two needs from class Context. I already have refactored the Memory_Manager at an earlier point to make this feasible, since we can now create life-cycles on demand when needed (first use case was the exposure of sass operations). So the second problem is pretty much already solved.

I also made quite a few refactorings to have the options decoupled from context already. The to_string methods on Ast Nodes of the base class Value takes two arguments (output style and precision), since they never need any other. We also have To_String CRTP vistors, which pretty much do the same, but for all Ast Nodes, but as already mentioned they need access to ctx.

I hope this explains the motivations behind this refactoring. I'm aware that this will not be the perfect solution and will probably require more refactorings, until also the internal API gets more and more sane.

I will now create meaningfull commits out of my now passing local branch ... could take some time.

@mgreter mgreter self-assigned this Nov 24, 2015
@mgreter mgreter added this to the 3.3.4 milestone Jan 13, 2016
Ensures we always have a valid object by not
allowing NULL to be passed to the constructor.
Stores `Memory_Manager` instead of `Context` on `Listize`
Ruby sass often uses inspect internally, which can produce
different results than with any other output mode. So far
I was not really aware of that fact. This should allow us
to match ruby sass output better and not produce to much
code duplication. Ultimately we should only have one
`inspect` visitor class.
@mgreter mgreter modified the milestones: 3.3.3, 3.3.4 Jan 13, 2016
@mgreter
Copy link
Contributor Author

mgreter commented Jan 13, 2016

Once green this is also ready to be merged. It's the base work to reunite all stringification functions again. They deviated because I often could not use the visitor classes due to the dependency on context. With this now gone, we can implement a visitor class that only has a bare minimum of internal dependecies (bascially what inspect visitor class is now with the new option for ruby inspect).

mgreter added a commit that referenced this pull request Jan 14, 2016
Refactor to remove `Context` dependency from `To_String` and others
@mgreter mgreter merged commit 199817e into sass:master Jan 14, 2016
@xzyfer
Copy link
Contributor

xzyfer commented Jan 14, 2016

It's the base work to reunite all stringification functions again.

Keen in mind we should aim to have two stringification functions. One for inspect (@debug), and one for css. In Ruby Sass these are to_css and to_sass/inspect (depending on the node type) methods on the AST nodes.

@mgreter
Copy link
Contributor Author

mgreter commented Jan 14, 2016

We don't want to have two visitor classes for this, so we need one option to pass to one visitor class. I added an additional "output style" for that puropse. We have 4 to_css and 1 inspect option on the same visitor class. That's the goal.

Reason we do not want to have 2 visitor classes: Once we fall back from to_css to inspect all further calls are within inspect. So one visitor class fits bests, and with that 5th option we have everything covered.

@mgreter
Copy link
Contributor Author

mgreter commented Jan 14, 2016

For that purpose I introduced struct Sass_Output_Style, which holds all options for stringification (output style and precision). I could have added a bool inspect to it, but that would basically give 8 variations in regard to output style, so adding an additional type seemed most consistent. It does not have much purpose on the API, but it doesn't hurt either. Not sure if consumers like node-sass should expose that output mode, but could be handy to have a ruby equivalent for sass values.

@mgreter
Copy link
Contributor Author

mgreter commented Jan 14, 2016

Also worth noting: the approach I chose with adding virtual to_string to AST_Nodes was mainly to circumvent the fact I could not use to_string visitor. Now that it is no longer directly dependent on context we can start to use it for everything. The approach with the virtual to_string is suboptimal, as the more nested nodes are involved, the more unnecessary string operations we do (since we do stuff like "(" + node->to_string() + ")", which can create a lot of unnecessary intermediate strings).

@mgreter
Copy link
Contributor Author

mgreter commented Jan 14, 2016

I hope that makes sense, I do not take these changes lightly either!
But to remove the dep of the visitor classes from context was needed!
And with the last commit I was able to do the first fix of this kind!

@mgreter
Copy link
Contributor Author

mgreter commented Jan 14, 2016

To clarify the goal: We should have one to_string (probably non virtual to ensure compile time resolution) method implemented in the base class AST_Node. That function should invoke a To_String visitor class and just pass the Sass_Output_Option struct. This will alleviate the need to create an instance of To_String over and over again. One problem currently is that the underlying inspect visitor class insists to create source-mappings. From a performance stand-point this is also not very optimal, but I guess we can overlook this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants