-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Discussion: Supporting plugins #5320
Comments
As an (hopefully interesting, though not useful) historical tidbit; CoffeeScript had "extensions" up until the middle of 2010. Michael Ficarra's CoffeeScriptRedux project also was meant to be (more) extensible. |
So something that's been discussed over the years (particularly by @lydell if I remember correctly) has been potentially refactoring out the need for jison. Basically look at I say this up front because I think a basic requirement of any plugin architecture is that plugins need to be able to be loaded at runtime, without necessitating a rebuild of CoffeeScript in order to execute. Look at Babel for comparison: you can add and remove Babel plugins via a configuration, and that just causes Babel to load and execute a few more functions (or not) at specified points in its flow, but the Babel code itself never changes. CoffeeScript needs to be the same way. Especially considering how easy it is to screw up the grammar, creating grammars with inconsistencies that jison refuses to build, we need to keep the CoffeeScript core static. I haven't dug through Babel's code, but that would probably be the blueprint for us to follow. I would assume our version would be something like this:
This is what I'm familiar with from other contexts as a plugin hooks model: CoffeeScript provides a method where plugins register functions with hooks. Like the first hook I mention above could be called something like # This plugin adds a naughty message at the bottom of every source file,
# by defining a function to be run within the `onSourceLoad` hook.
CoffeeScript.registerPlugin
onSourceLoad: (source) -> "#{source}\nconsole.log 'not!'" The anonymous function passed to |
Wow! Let me get my leaking noob brain back. Jison looks like a good tool to me, however makes CoffeeScript static looks better. After my first contribution to the compiler i wold like to have something more solid in my hands. How hard will be to accomplish this decoupling? I agree that lex/grammar functions should be sync, however limit pre and post processing to be sync may be very bad for many plugins. As this feature can push a major release, I believe it will be ok to break compatibility with CoffeeScript module users. |
The naïve approach would be to just port However the resulting So the short version is that to do it right, it would be a significant challenge. It doesn't require too much CoffeeScript codebase knowledge, so if you're an experienced developer and want a big task to bite off, it's self-contained albeit challenging. Alternatively, you could implement a plugin architecture that just avoids the grammar, at least at first. Then you could tackle the grammar refactor as a second stage, or try to find more workarounds like we've already been doing for passing data through the parser. One workaround could be adding more places where |
Barista, who can build new flavors of coffee for you.
It looks like we agree that is interesting to have a pluggable coffee compiler in the "TypeScript Output" discussion, for a health evolution of the language and the CoffeeScript ecosystem.
As I understand, the CoffeeScript source is a elaborated Jison configuration, and the compiler itself is a parser code generated by Jison. Make this generated code pluggable can be hard to do and harder to maintain.
I believe, the right path to make a pluggable coffee compiler is to have
jison
as a execution dependency and the compiler itself must to be build at runtime.Well it obviously will make the coffee compiler heavier and slower.
So I propose a new build task on the Cakefile to create the "barista compiler". It will be the same CoffeeScript compiler source, but not generated by Jison, its API will have plugin related configs, as its bin's CLI will have some plugins args. And, sure, it must be shipped with a different
package.json
with"jison"
in the"dependencies"
list.How a plugin may work
A plugin must implement methods to parameterize, extend or replace the transpiler units:
Lexer.tokenize()
: Looks like it will be the harder process to become pluggable. The method itself may stay untouchable by plugins, but they must to be able to change or parameterize its specialized tokenizers (identifierToken()
,stringToken()
, ...) or add new ones on any position of the tokenizers call line.grammar
must be exported as it is and freely modifiable by the plugin code.nodes
module looks like the most important is already exported and can be changed by the plugin. But it need to be clear where a new collection of node classes must to be attached to be used by the extended transpiler. Somenodes.coffee
helpers must to be exported to become usable by new node classes, and it must export a method to enable the plugins to replace this helpers if needed.What you think? What is missed? Is there a better path? Do you know specific details that need to be described?
The text was updated successfully, but these errors were encountered: