Repository: tailwindlabs/tailwindcss
File: packages/tailwindcss/src/utilities.ts (TypeScript)

Code before:

          for (let node of fn.nodes) {
            // Track literal values
            if (
              node.kind === 'word' &&
              (node.value[0] === '"' || node.value[0] === "'") &&
              node.value[0] === node.value[node.value.length - 1]
            ) {
              let value = node.value.slice(1, -1)
              storage[fn.value].literals.add(value)
            }

            // Track theme keys
            else if (node.kind === 'word' && node.value[0] === '-' && node.value[1] === '-') {
              let value = node.value.replace(/-\*.*$/g, '') as `--${string}`
              storage[fn.value].themeKeys.add(value)
            }

            // Validate bare value data types
            else if (
              node.kind === 'word' &&
              !(node.value[0] === '[' && node.value[node.value.length - 1] === ']') && // Ignore arbitrary values
              !BARE_VALUE_DATA_TYPES.includes(node.value)
            ) {
              console.warn(
                `Unsupported bare value data type: "${node.value}".\nOnly valid data types are: ${BARE_VALUE_DATA_TYPES.map((x) => `"${x}"`).join(', ')}\n`,
              )
              // TODO: Once we properly track the location of the node, we can
              //       clean this up in a better way.
              let dataType = node.value
              let copy = structuredClone(fn)
              let sentinelValue = '¶'
              ValueParser.walk(copy.nodes, (node, { replaceWith }) => {
                if (node.kind === 'word' && node.value === dataType) {
                  replaceWith({ kind: 'word', value: sentinelValue })
                }
              })
              let underline = '^'.repeat(ValueParser.toCss([node]).length)
              let offset = ValueParser.toCss([copy]).indexOf(sentinelValue)
              let output = [
                '```css',
                ValueParser.toCss([fn]),
                ' '.repeat(offset) + underline,
                '```',
              ].join('\n')
              console.warn(output)
            }
          }
        })

        child.value = ValueParser.toCss(declarationValueAst)

Review comment (suggestion):
@adamwathan do you want to make any changes to this warning?

Output looks something like this right now:
~~~
Unsupported bare value data type: "color".
Only valid data types are: "number", "integer", "ratio", "percentage"

```css
--value([color],color)
                ^^^^^
```
~~~

Code after:
          usedSpacingInteger: false,
          usedSpacingNumber: false,
          themeKeys: new Set<`--${string}`>(),
          literals: new Set<string>(),
        },
        '--modifier': {
          usedSpacingInteger: false,
          usedSpacingNumber: false,
          themeKeys: new Set<`--${string}`>(),
          literals: new Set<string>(),
        },
      }

      // Pre-process the AST to make it easier to work with.
      //
      // - Normalize theme values used in `--value(…)` and `--modifier(…)`
      //   functions.
      // - Track information for suggestions
      walk(node.nodes, (child) => {
        if (child.kind !== 'declaration') return
        if (!child.value) return
        if (!child.value.includes('--value(') && !child.value.includes('--modifier(')) return

        let declarationValueAst = ValueParser.parse(child.value)

        // Required manipulations:
        //
        // - `--value(--spacing)`                 -> `--value(--spacing-*)`
        // - `--value(--spacing- *)`              -> `--value(--spacing-*)`
        // - `--value(--text- * --line-height)`   -> `--value(--text-*--line-height)`
        // - `--value(--text --line-height)`      -> `--value(--text-*--line-height)`
        // - `--value(--text-\\* --line-height)`  -> `--value(--text-*--line-height)`
        // - `--value([ *])`                      -> `--value([*])`
        //
        // Once Prettier / Biome handle these better (e.g.: not crashing without
        // `\\*` or not inserting whitespace) then most of these can go away.
        ValueParser.walk(declarationValueAst, (fn) => {
          if (fn.kind !== 'function') return

          // Track usage of `--spacing(…)`
          if (
            fn.value === '--spacing' &&
            // Quick bail check if we already know that `--value` and `--modifier` are
            // using the full `--spacing` theme scale.
            !(storage['--modifier'].usedSpacingNumber && storage['--value'].usedSpacingNumber)
          ) {
            ValueParser.walk(fn.nodes, (node) => {
              if (node.kind !== 'function') return
              if (node.value !== '--value' && node.value !== '--modifier') return
              const key = node.value