gucong3000 / postcss-syntax

Automatically switch PostCSS syntax based on file extensions
MIT License
45 stars 7 forks source link

Incorrect parsing/stringifying for nested tagged template literals #44

Closed hudochenkov closed 5 years ago

hudochenkov commented 5 years ago

Syntax incorrectly parse, and then stringify complicated CSS-in-JS, where tagged template literal has css`` template literal inside.

Input:

import styled, { css } from 'styled-components';
const Message = styled.p`
    padding: 10px;
    ${(props) => css`
        color: #b02d00;
    `}
    ${(props2) => css`
        border-color: red;
    `}
`;

Output:

import styled, { css } from 'styled-components';
const Message = styled.p`
    padding: 10px;
    ${(props) => css`
        color: #b02d00;
    `}
    ${(props2) => css`
        border-color: red;
    `}

        color: #b02d00;
    `}
    ${(props2) => css`
        border-color: red;
    `}
`;

The problem is in multiple places: in this package and in postcss-syntax .

Code parsed acceptable for running linter over the resulting AST, but not to stringify it back. After parsing there are three Root nodes:

First root is styled.p template literal:

Second root is the first css template literal:

Third root is the second css template literal:

This part is correct, but the problem in details.

Stringifying is initiated in postcss-syntax. All roots are “concatenated” together.

  1. Nodes with type “literal” in the first node are preserved and then other two roots, which are parsed literals from the first root, are glued. That's why duplication happens. When PostCSS plugin is runned over input like above, type: "literal" nodes are not being processed by plugins and copied as is. While the following roots are processed.
  2. For some reasons second root has empty raws.beforeStart, when the third root has correct raws.beforeStart. Second root should have not-empty raws.beforeStart.

Screenshots above made in debugger in VS Code, I put breakpoint on this line and printed document.nodes. It's right before stringifying.

hudochenkov commented 5 years ago

Wrong repository. Opened in https://github.com/gucong3000/postcss-jsx/issues/53