Repository: tailwindlabs/tailwindcss
File: packages/@tailwindcss-upgrade/src/template/codemods/important.ts (TypeScript)

Code before:
        let currentLineAfterCandidate = ''
        for (let i = location.end; i < location.contents.length; i++) {
          let char = location.contents.at(i)!
          if (char === '\n') {
            break
          }
          currentLineAfterCandidate += char
        }

        // Heuristics 1: Require the candidate to be inside quotes
        let isQuoteBeforeCandidate = QUOTES.some((quote) =>
          currentLineBeforeCandidate.includes(quote),
        )
        let isQuoteAfterCandidate = QUOTES.some((quote) =>
          currentLineAfterCandidate.includes(quote),
        )
        if (!isQuoteBeforeCandidate || !isQuoteAfterCandidate) {
          continue nextCandidate
        }

        // Heuristics 2: Disallow object access immediately following the candidate
        if (currentLineAfterCandidate[0] === '.') {
          continue nextCandidate
        }

        // Heuristics 3: Disallow logical operators proceeding or following the candidate
        for (let operator of LOGICAL_OPERATORS) {
          if (
            currentLineAfterCandidate.trim().startsWith(operator) ||
            currentLineBeforeCandidate.trim().endsWith(operator)
          ) {
            continue nextCandidate
          }
        }

        // Heuristics 4: Disallow conditional template syntax
        for (let rule of CONDITIONAL_TEMPLATE_SYNTAX) {
          if (rule.test(currentLineBeforeCandidate)) {
            continue nextCandidate
          }
        }
      }

      // The printCandidate function will already put the exclamation mark in
      // the right place, so we just need to mark this candidate as requiring a
      // migration.
      return printCandidate(designSystem, candidate)
    }
  }

  return rawCandidate

Review comment (suggestion):
```suggestion
        // Heuristic 3: Disallow logical operators preceding or following the candidate
```

Code after:
        }
        let currentLineAfterCandidate = ''
        for (let i = location.end; i < location.contents.length; i++) {
          let char = location.contents.at(i)!
          if (char === '\n') {
            break
          }
          currentLineAfterCandidate += char
        }

        // Heuristic 1: Require the candidate to be inside quotes
        let isQuoteBeforeCandidate = QUOTES.some((quote) =>
          currentLineBeforeCandidate.includes(quote),
        )
        let isQuoteAfterCandidate = QUOTES.some((quote) =>
          currentLineAfterCandidate.includes(quote),
        )
        if (!isQuoteBeforeCandidate || !isQuoteAfterCandidate) {
          continue nextCandidate
        }

        // Heuristic 2: Disallow object access immediately following the candidate
        if (currentLineAfterCandidate[0] === '.') {
          continue nextCandidate
        }

        // Heuristic 3: Disallow logical operators preceding or following the candidate
        for (let operator of LOGICAL_OPERATORS) {
          if (
            currentLineAfterCandidate.trim().startsWith(operator) ||
            currentLineBeforeCandidate.trim().endsWith(operator)
          ) {
            continue nextCandidate
          }
        }

        // Heuristic 4: Disallow conditional template syntax
        for (let rule of CONDITIONAL_TEMPLATE_SYNTAX) {
          if (rule.test(currentLineBeforeCandidate)) {
            continue nextCandidate
          }
        }
      }

      // The printCandidate function will already put the exclamation mark in
      // the right place, so we just need to mark this candidate as requiring a
      // migration.
      return printCandidate(designSystem, candidate)
    }
  }