text: // @flow
  
  import { serializeStyles } from '@emotion/serialize'
  import minify from './minify'
  import { getLabelFromPath } from './label'
  import { getSourceMap } from './source-maps'
  import { simplifyObject } from './object-to-string'
  import {
    appendStringReturningExpressionToArguments,
    joinStringLiterals
  } from './strings'
  import createNodeEnvConditional from './create-node-env-conditional'
  
  const CSS_OBJECT_STRINGIFIED_ERROR =
    "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."
  
  export let transformExpressionWithStyles = ({
    babel,
    state,
    path,
    shouldLabel,
    sourceMap = ''
  }: {
    babel: *,
    state: *,
    path: *,
    shouldLabel: boolean,
    sourceMap?: string
  }): * => {
    const autoLabel = state.opts.autoLabel || 'dev-only'
    let t = babel.types
    if (t.isTaggedTemplateExpression(path)) {
      if (
        !sourceMap &&
        state.emotionSourceMap &&
        path.node.quasi.loc !== undefined
      ) {
        sourceMap = getSourceMap(path.node.quasi.loc.start, state)
      }
      minify(path, t)
    }
  
    if (t.isCallExpression(path)) {
      const canAppendStrings = path.node.arguments.every(
        arg => arg.type !== 'SpreadElement'
      )
  
      path.get('arguments').forEach(node => {
        if (t.isObjectExpression(node)) {
          node.replaceWith(simplifyObject(node.node, t))
        }
      })
  
      path.node.arguments = joinStringLiterals(path.node.arguments, t)
  
      if (
        !sourceMap &&
        canAppendStrings &&
        state.emotionSourceMap &&
        path.node.loc !== undefined
      ) {
        sourceMap = getSourceMap(path.node.loc.start, state)
      }
  
      const label =
        shouldLabel && autoLabel !== 'never'
          ? getLabelFromPath(path, state, t)
          : null
  
      if (
        path.node.arguments.length === 1 &&
        t.isStringLiteral(path.node.arguments[0])
      ) {
        let cssString = path.node.arguments[0].value.replace(/;$/, '')
        let res = serializeStyles([
          `${cssString}${
            label && autoLabel === 'always' ? `;label:${label};` : ''
          }`
        ])
        let prodNode = t.objectExpression([
          t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)),
          t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles))
        ])
  
        if (!state.emotionStringifiedCssId) {
          const uid = state.file.scope.generateUidIdentifier(
            '__EMOTION_STRINGIFIED_CSS_ERROR__'
          )
          state.emotionStringifiedCssId = uid
          const cssObjectToString = t.functionDeclaration(
            uid,
            [],
            t.blockStatement([
              t.returnStatement(t.stringLiteral(CSS_OBJECT_STRINGIFIED_ERROR))
            ])
          )
          cssObjectToString._compact = true
          state.file.path.unshiftContainer('body', [cssObjectToString])
        }
  
        if (label && autoLabel === 'dev-only') {
          res = serializeStyles([`${cssString};label:${label};`])
        }
  
        let devNode = t.objectExpression(
          [
            t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)),
            t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles)),
            sourceMap &&
              t.objectProperty(t.identifier('map'), t.stringLiteral(sourceMap)),
            t.objectProperty(
              t.identifier('toString'),
              t.cloneNode(state.emotionStringifiedCssId)
            )
          ].filter(Boolean)
        )
  
        return createNodeEnvConditional(t, prodNode, devNode)
      }
  
      if (canAppendStrings && label) {
        const labelString = `;label:${label};`
  
        switch (autoLabel) {
          case 'dev-only': {
            const labelConditional = createNodeEnvConditional(
              t,
              t.stringLiteral(''),
              t.stringLiteral(labelString)
            )
            appendStringReturningExpressionToArguments(t, path, labelConditional)
            break
          }
          case 'always':
            appendStringReturningExpressionToArguments(t, path, labelString)
            break
        }
      }
  
      if (sourceMap) {
        let sourceMapConditional = createNodeEnvConditional(
          t,
          t.stringLiteral(''),
          t.stringLiteral(sourceMap)
        )
        appendStringReturningExpressionToArguments(t, path, sourceMapConditional)
      }
    }
  }
  