Lona / Lona

A tool for defining design systems and using them to generate cross-platform UI code, Sketch files, and other artifacts.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compiler status & tasks

dabbott opened this issue Β· comments

Hello friends! I just merged in what I have so far for Swift code generation. Here's a status update on code generation overall:

Status

The new ReasonML compiler is significantly easier to work with than the original JavaScript one (and the small proof-of-concept TypeScript one I made), so I'm very happy with ReasonML and plan to continue in this direction.

I've made pretty good progress toward correct, performant Swift component code. There's still a lot left to do though. JS code is also close to working, but definitely needs a lot of tweaks. You can browse the current generated output for a test workspace I made here: https://github.com/airbnb/Lona/tree/master/examples/generated/test

I'll categorize what's left into a few categories below. The tasks vary a lot in size, but I think some will be pretty easy for others to pick up and can be done in parallel. Let me know if you see something you want to try!

Language-agnostic

  • The code is pretty messy. Most Swift generation code is in one 1000 line file. I couldn't decide what would work better: organizing code by target (e.g. js, swift) or by purpose (e.g. outputting colors) so there's a mix of both right now. I think now that there's a decent amount of code, it might make sense to figure out what's working and what isn't and decide on the best organization. [Update: I organized code by target and started using subdirectories. I think future refactoring can be more incremental]
  • Test cases. One day I think we'll want automated screenshots per target to catch visual regressions. I think for now we can just commit the generated code for the test workspace, and compare the diff when we change the compiler. It would be good to figure out a set of test cases that cover most of the core flexbox use cases. The code to generate constraints is complicated and I suspect it'll be easy to cause regressions without a comprehensive set of test cases.
  • The Logic language is designed around the current UI of Lona Studio, which I think will be limiting going forward. We should use a more standard AST format that the compiler and future tools can read and write more easily. Lona Studio will translate from the internal data structure to the new Logic AST we define.
  • Logic AST optimizations. After we've improved the Logic AST, there are some optimizations that can be performed on the Logic AST instead of being duplicated in the Swift/JS AST.
  • There will probably eventually be multiple targets per language. E.g. JS => React, React Native, Vue, Angular. Swift => UIKit, ComponentKit. Might make sense to update the code to use the framework names instead.
  • Configurability. There are lots of ways people will want to customize the generated code. I have a few ideas here.
    1. I think we should have CLI options for extremely most common stuff.
    2. I think we should allow a config file (likely using cosmiconfig) akin to webpack/babel/eslint where more details options can be specified. If this config file can run JS code (e.g. config.js) then we can also support hooks for more detailed customization.
    3. Eventually, separate the various targets of the compiler into different repos. Allow easy forking of individual targets. Code generation will likely need to be customized in an infinite number of ways that we can't support through a config-based approach.

Swift

  • [@dabbott] Flexbox. I've handled some of the core layout properties, but there are many more to cover. E.g. alignment. Also, the current implementation has some issues even in the test files I've committed.
  • Style properties. Properties like background color, border, etc, all need to be generated.
  • [@dabbott] TextStyles. I think we should start by including something similar to the AttributedFont class in Lona Studio (this is similar to what we do in the Airbnb app), and then generating an instance of AttributedFont for each text style.
  • Images. People will likely want to use their own image fetching/caches classes, so at some point we'll want to make this configurable. We'll also need to figure out how to bundle image assets from desk. I think to start, we can do something pretty simple to fetch remote images via URL, and not think about images on disk (Lona Studio doesn't handle these very well yet -- absolute file paths aren't very useful).
  • [@dabbott] Custom components. I think the main challenge here will be that we need to figure out how to constrain the custom component to its parent. So far I've "solved" this in JS by assuming all custom components are within a parent with flexDirection: 'column'. This makes components entirely self-contained, which I think is an acceptable tradeoff. I'm not sure if the same technique will work in Swift though.
  • Optional parameters. Lona Studio will likely need to make nullability more clear in a lot of places before this makes sense.
  • View visibility. Currently the visible style is correctly applied to the isHidden property of views, but when a view is hidden, we need to update constraints so that other children within the same parent rearrange themselves. Otherwise, there may be a gap between components when a view is hidden.

JS

I haven't touched the JS code generation in a bit. The original compiler still works better than this new one. But it's mainly a matter of adding more features and fixing bugs.

  • Refactoring. This was the first code I wrote in ReasonML and some of it isn't very good. I'd probably have to look through the code more to find all the specifics, but e.g. the Swift AST uses objects which works very well, so the JS AST should do this too. The idea of converting all ASTs to a generic tree structure (tree.re) probably isn't a very good idea, since each AST node likely needs custom rules.
  • Fixing bugs. There are lots of buggy things currently - e.g. we need to normalize layer names before using them as keys in the styles object.
  • Imports. We don't import anything at the top of the file yet. We need this before the generated code is functional.
  • Color generation - the format for this already exists in the original compiler -- we just need to regenerate it using the JS AST in Reason
  • Text style generation - like colors, the format for this already exists

Kotlin/Java

  • Find somebody with Kotlin/Java knowledge?

FYI @ryngonzalez @NghiaTranUIT @GuillaumeSalles @jasonzurita

Appreciate @dabbott πŸ₯‡. It's super clear if we have the road-map.
The Swift sections could be more easier to take start off firstly from my experience.

I will take a look and pick one πŸ‘

This is awesome @dabbott!!

I will take a closer look at the remaining work to see where I can be most effective 😎.

Awesome @jasonzurita! Let me know what you want to do and I can give you an overview of what I have so far.

@NghiaTranUIT I'm happy to have you take one of these, but I also don't wanna take you away from Travis and undo/redo which are also really great. Up to you though!

Nice! Looks really good. I think I can't help you out with the JS part :)

@dabbott The initial cut at organizing the files by target is great -- easier to reason (no pun intended 😁) about what is going on.

As far as what is left, I figure I should take something smaller to start. I am very comfortable with Swift, but I will have some growing pains using ReasonML / getting used to the code base. What are your thoughts on taking either View visibility or Style properties?

@jasonzurita I think adding a style property would be a great place to start! I opened a new issue to track adding borderColor and borderWidth: #83

So far I'm the only person who's touched the Reason code, so it's very messy/prototypey. But this'll be a great forcing function to improve it :). As a first thought, I should probably add some scripts that generate the "snapshot tests" (the outputted code that I commit to the repo), since right now I've been running the commands just by typing it out, which means you'll probably want to read main.re to understand the CLI commands.

PS: My github notifications became unusable a long time ago, so I basically only see new issues if I happen to check πŸ˜›. I'm also happy to give you an overview of everything over video chat if you want -- just DM me on twitter.

@dabbott Good to know and sounds like a plan!

re: ps πŸ˜¬πŸ‘πŸΌ. I appreciate it! I am going to dig in a bit more first, and then I will touch base.

Most specific tasks here are done. Closing