davesnx / styled-ppx

Type-safe styled components for ReScript, Melange and native with type-safe CSS
https://styled-ppx.vercel.app
BSD 2-Clause "Simplified" License
399 stars 32 forks source link

Implement better errors #429

Open davesnx opened 5 months ago

davesnx commented 5 months ago

Current errors

The current errors are insuficient to learn how to resolve the issue when the parser is complaining, and lack a bit of context, they are classified by:

Lexing/Parsing errors

The current parser errors regarding variables and missing features is very bad.

Properties raises

ppx raise

Improving Parser errors

Maybe we can improve ParseError and display the error with the expected next values?

Property errors

Type-check errors

Render error messages with the value ppx payload

E9yxbcbXMAE7Nlc.jpeg

Wrong value

display: blocki;
         ^^^^^^

Not a valid value for `display`.
display defintion expects one of `'block' | 'contents' | 'flex' | 'flow' | 'flow-root' | 'grid' | 'inline' | 'inline-block' | 'inline-flex' | 'inline-grid' | 'inline-list-item' | 'inline-table' | 'list-item' | 'none' | 'ruby' | 'ruby-base' | 'ruby-base-container' | 'ruby-text' | 'ruby-text-container' | 'run-in' | 'table' | 'table-caption' | 'table-cell' | 'table-column' | 'table-column-group' | 'table-footer-group' | 'table-header-group' | 'table-row' | 'table-row-group' | '-ms-flexbox' | '-ms-inline-flexbox' | '-ms-grid' | '-ms-inline-grid' | '-webkit-flex' | '-webkit-inline-flex' | '-webkit-box' | '-webkit-inline-box' | '-moz-inline-stack' | '-moz-box' | '-moz-inline-box'`
(optional) Maybe you mean `block`?

Wrong value format

Detect when partial matching happens and render the closest as an error message

border: 1px solid;
^^^^^^^^^^^^^^^^^

Missing value for `border`.
border defintion is `<line-width> || <line-style> || <color>`
Missing `<color>`

// ----
// TODO: More examples

Wrong type

border-width: 1%;
              ^^

Wrong value type for `border-width`
border-width definition is `[ <line-width> ]{1,4}`. (For example: `2px`)

Missing property

When a not valid property is passed to our parser (we should differentiate when the property is a valid CSS but we don't support vs a invalid property)

border-width-left: 1%;
^^^^^^^^^^^^^^^^^

Invalid property `border-width-left`.
(optional) Maybe you mean `border-left-width`?

Unsupported interpolation in property

resize: $(lola);
        ^^^^^^^

`resize` property doesn't support interpolation `$(lola)`. 

Interpolation broken format

  // Empty
  margin-left: $();

  // NotClosed
margin-left: $(aasdf;

  // NotClosedAtEof
  margin-left: $(aasdf

  // InvalidName
  margin-left: $(λ);
  margin-left: $(🐪);

  // Non-valid syntaxes
  ???  

  // Unscaped
  margin-left: $name;

  // NotStarted
  margin-left: $);

  // OnlyIdentifiersAreValid
  // Inline calling functions aren't supported.
  // Move it into a let assignment above
  margin-left: $(`lola(value));
  margin-left: $(lola(value));

How?

Remove parsing reduce/shifts

Currently our css_parser.mly generates a ton of warnings. This causes menhir to do a decent job on reducing those, based on the order of tokens, but when you are refactoring the parser this breaks into a lot of pieces.

It’s currently a little unreliable:

Use the BNF syntax to parse CSS

Consider using the Incremental API

Consider rewriting with a handmade parser

Like rescript/syntax: https://github.com/rescript-lang/rescript-compiler/tree/master/res_syntax/src

davesnx commented 5 months ago
File "xxx/PasswordStrength_Css.ml", line 16, characters 8-9:
Error: Parse error while reading token '['

Actual issue is on line 170, incorrect selector:

  hover [
    opacity: 0.7;
  ];

CleanShot 2024-03-08 at 13 32 06@2x

davesnx commented 5 months ago
File "frontend/packages/ahkit/src/bindings/PasswordStrength_Css.ml", line 79, characters 25-26:
Error: Parse error while reading token ';'
mask-image: $("url(" ^ eyeCrossedIcon ^ ")");

CleanShot 2024-03-08 at 13 23 22@2x