Ignore commented out code (#599)

master
Brad Cornes 2022-09-01 15:06:47 +01:00 committed by GitHub
parent 92410c1bf8
commit 86d93aaa18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 64 additions and 19 deletions

View File

@ -17,6 +17,7 @@ import { cssObjToAst } from '../util/cssObjToAst'
import { dset } from 'dset' import { dset } from 'dset'
import selectorParser from 'postcss-selector-parser' import selectorParser from 'postcss-selector-parser'
import { flatten } from '../util/array' import { flatten } from '../util/array'
import { getTextWithoutComments } from '../util/doc'
export async function provideInvalidApplyCodeActions( export async function provideInvalidApplyCodeActions(
state: State, state: State,
@ -24,7 +25,7 @@ export async function provideInvalidApplyCodeActions(
diagnostic: InvalidApplyDiagnostic diagnostic: InvalidApplyDiagnostic
): Promise<CodeAction[]> { ): Promise<CodeAction[]> {
let document = state.editor.documents.get(params.textDocument.uri) let document = state.editor.documents.get(params.textDocument.uri)
let documentText = document.getText() let documentText = getTextWithoutComments(document, 'css')
let cssRange: Range let cssRange: Range
let cssText = documentText let cssText = documentText
const { postcss } = state.modules const { postcss } = state.modules
@ -47,7 +48,7 @@ export async function provideInvalidApplyCodeActions(
.filter((b) => b.type === 'css') .filter((b) => b.type === 'css')
.find(({ range }) => isWithinRange(diagnostic.range.start, range))?.range .find(({ range }) => isWithinRange(diagnostic.range.start, range))?.range
if (!cssRange) return [] if (!cssRange) return []
cssText = document.getText(cssRange) cssText = getTextWithoutComments(document, 'css', cssRange)
} }
try { try {

View File

@ -10,6 +10,7 @@ import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange' import { absoluteRange } from '../util/absoluteRange'
import { combinations } from '../util/combinations' import { combinations } from '../util/combinations'
import dlv from 'dlv' import dlv from 'dlv'
import { getTextWithoutComments } from '../util/doc'
function pathToString(path: string | string[]): string { function pathToString(path: string | string[]): string {
if (typeof path === 'string') return path if (typeof path === 'string') return path
@ -177,7 +178,7 @@ export function getInvalidConfigPathDiagnostics(
} }
ranges.forEach((range) => { ranges.forEach((range) => {
let text = document.getText(range) let text = getTextWithoutComments(document, 'css', range)
let matches = findAll( let matches = findAll(
/(?<prefix>\s|^)(?<helper>config|theme)\((?<quote>['"])(?<key>[^)]+)\k<quote>[^)]*\)/g, /(?<prefix>\s|^)(?<helper>config|theme)\((?<quote>['"])(?<key>[^)]+)\k<quote>[^)]*\)/g,
text text

View File

@ -7,6 +7,7 @@ import { findAll, indexToPosition } from '../util/find'
import { closest } from '../util/closest' import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange' import { absoluteRange } from '../util/absoluteRange'
import dlv from 'dlv' import dlv from 'dlv'
import { getTextWithoutComments } from '../util/doc'
export function getInvalidScreenDiagnostics( export function getInvalidScreenDiagnostics(
state: State, state: State,
@ -28,7 +29,7 @@ export function getInvalidScreenDiagnostics(
} }
ranges.forEach((range) => { ranges.forEach((range) => {
let text = document.getText(range) let text = getTextWithoutComments(document, 'css', range)
let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text) let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text)
matches.forEach((match) => { matches.forEach((match) => {

View File

@ -7,6 +7,7 @@ import { findAll, indexToPosition } from '../util/find'
import * as semver from '../util/semver' import * as semver from '../util/semver'
import { closest } from '../util/closest' import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange' import { absoluteRange } from '../util/absoluteRange'
import { getTextWithoutComments } from '../util/doc'
export function getInvalidTailwindDirectiveDiagnostics( export function getInvalidTailwindDirectiveDiagnostics(
state: State, state: State,
@ -42,7 +43,7 @@ export function getInvalidTailwindDirectiveDiagnostics(
let hasVariantsDirective = state.jit && semver.gte(state.version, '2.1.99') let hasVariantsDirective = state.jit && semver.gte(state.version, '2.1.99')
ranges.forEach((range) => { ranges.forEach((range) => {
let text = document.getText(range) let text = getTextWithoutComments(document, 'css', range)
let matches = findAll(regex, text) let matches = findAll(regex, text)
let valid = [ let valid = [

View File

@ -7,6 +7,7 @@ import { findAll, indexToPosition } from '../util/find'
import { closest } from '../util/closest' import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange' import { absoluteRange } from '../util/absoluteRange'
import * as semver from '../util/semver' import * as semver from '../util/semver'
import { getTextWithoutComments } from '../util/doc'
export function getInvalidVariantDiagnostics( export function getInvalidVariantDiagnostics(
state: State, state: State,
@ -38,7 +39,7 @@ export function getInvalidVariantDiagnostics(
} }
ranges.forEach((range) => { ranges.forEach((range) => {
let text = document.getText(range) let text = getTextWithoutComments(document, 'css', range)
let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text) let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text)
matches.forEach((match) => { matches.forEach((match) => {

View File

@ -8,6 +8,7 @@ import { validateApply } from './util/validateApply'
import { getClassNameParts } from './util/getClassNameAtPosition' import { getClassNameParts } from './util/getClassNameAtPosition'
import * as jit from './util/jit' import * as jit from './util/jit'
import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics' import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics'
import { getTextWithoutComments } from './util/doc'
export async function doHover( export async function doHover(
state: State, state: State,
@ -23,10 +24,7 @@ export async function doHover(
function provideCssHelperHover(state: State, document: TextDocument, position: Position): Hover { function provideCssHelperHover(state: State, document: TextDocument, position: Position): Hover {
if (!isCssContext(state, document, position)) return null if (!isCssContext(state, document, position)) return null
const line = document.getText({ const line = getTextWithoutComments(document, 'css').split('\n')[position.line]
start: { line: position.line, character: 0 },
end: { line: position.line + 1, character: 0 },
})
const match = line.match(/(?<helper>theme|config)\((?<quote>['"])(?<key>[^)]+)\k<quote>[^)]*\)/) const match = line.match(/(?<helper>theme|config)\((?<quote>['"])(?<key>[^)]+)\k<quote>[^)]*\)/)

View File

@ -0,0 +1,29 @@
import type { TextDocument, Range } from 'vscode-languageserver'
export function getTextWithoutComments(
doc: TextDocument,
type: 'html' | 'js' | 'jsx' | 'css',
range?: Range
): string
export function getTextWithoutComments(text: string, type: 'html' | 'js' | 'jsx' | 'css'): string
export function getTextWithoutComments(
docOrText: TextDocument | string,
type: 'html' | 'js' | 'jsx' | 'css',
range?: Range
): string {
let text = typeof docOrText === 'string' ? docOrText : docOrText.getText(range)
if (type === 'js' || type === 'jsx') {
return text.replace(/\/\*.*?\*\//gs, replace).replace(/\/\/.*?$/gms, replace)
}
if (type === 'css') {
return text.replace(/\/\*.*?\*\//gs, replace)
}
return text.replace(/<!--.*?-->/gs, replace)
}
function replace(match: string): string {
return match.replace(/./gs, (char) => (char === '\n' ? '\n' : ' '))
}

View File

@ -12,6 +12,7 @@ import { resolveRange } from './resolveRange'
import dlv from 'dlv' import dlv from 'dlv'
import { rangesEqual } from './rangesEqual' import { rangesEqual } from './rangesEqual'
import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib' import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib'
import { getTextWithoutComments } from './doc'
export function findAll(re: RegExp, str: string): RegExpMatchArray[] { export function findAll(re: RegExp, str: string): RegExpMatchArray[] {
let match: RegExpMatchArray let match: RegExpMatchArray
@ -74,7 +75,7 @@ export async function findClassNamesInRange(
state: State, state: State,
doc: TextDocument, doc: TextDocument,
range?: Range, range?: Range,
mode?: 'html' | 'css', mode?: 'html' | 'css' | 'jsx',
includeCustom: boolean = true includeCustom: boolean = true
): Promise<DocumentClassName[]> { ): Promise<DocumentClassName[]> {
const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom) const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom)
@ -90,7 +91,7 @@ export async function findClassNamesInDocument(
} }
export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] { export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] {
const text = doc.getText(range) const text = getTextWithoutComments(doc, 'css', range)
const matches = findAll( const matches = findAll(
/(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g, /(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g,
text text
@ -184,9 +185,10 @@ export function matchClassAttributes(text: string, attributes: string[]): RegExp
export async function findClassListsInHtmlRange( export async function findClassListsInHtmlRange(
state: State, state: State,
doc: TextDocument, doc: TextDocument,
type: 'html' | 'js' | 'jsx',
range?: Range range?: Range
): Promise<DocumentClassList[]> { ): Promise<DocumentClassList[]> {
const text = doc.getText(range) const text = getTextWithoutComments(doc, type, range)
const matches = matchClassAttributes( const matches = matchClassAttributes(
text, text,
@ -291,14 +293,14 @@ export async function findClassListsInRange(
state: State, state: State,
doc: TextDocument, doc: TextDocument,
range?: Range, range?: Range,
mode?: 'html' | 'css', mode?: 'html' | 'css' | 'jsx',
includeCustom: boolean = true includeCustom: boolean = true
): Promise<DocumentClassList[]> { ): Promise<DocumentClassList[]> {
let classLists: DocumentClassList[] let classLists: DocumentClassList[]
if (mode === 'css') { if (mode === 'css') {
classLists = findClassListsInCssRange(doc, range) classLists = findClassListsInCssRange(doc, range)
} else { } else {
classLists = await findClassListsInHtmlRange(state, doc, range) classLists = await findClassListsInHtmlRange(state, doc, mode, range)
} }
return dedupeClassLists([ return dedupeClassLists([
...classLists, ...classLists,
@ -322,7 +324,9 @@ export async function findClassListsInDocument(
...(await Promise.all( ...(await Promise.all(
boundaries boundaries
.filter((b) => b.type === 'html' || b.type === 'jsx') .filter((b) => b.type === 'html' || b.type === 'jsx')
.map(({ range }) => findClassListsInHtmlRange(state, doc, range)) .map(({ type, range }) =>
findClassListsInHtmlRange(state, doc, type === 'html' ? 'html' : 'jsx', range)
)
)), )),
...boundaries ...boundaries
.filter((b) => b.type === 'css') .filter((b) => b.type === 'css')
@ -354,7 +358,7 @@ export function findHelperFunctionsInRange(
doc: TextDocument, doc: TextDocument,
range?: Range range?: Range
): DocumentHelperFunction[] { ): DocumentHelperFunction[] {
const text = doc.getText(range) const text = getTextWithoutComments(doc, 'css', range)
const matches = findAll( const matches = findAll(
/(?<before>^|\s)(?<helper>theme|config)\((?:(?<single>')([^']+)'|(?<double>")([^"]+)")[^)]*\)/gm, /(?<before>^|\s)(?<helper>theme|config)\((?:(?<single>')([^']+)'|(?<double>")([^"]+)")[^)]*\)/gm,
text text
@ -408,8 +412,10 @@ export async function findClassNameAtPosition(
if (isCssContext(state, doc, position)) { if (isCssContext(state, doc, position)) {
classNames = await findClassNamesInRange(state, doc, searchRange, 'css') classNames = await findClassNamesInRange(state, doc, searchRange, 'css')
} else if (isHtmlContext(state, doc, position) || isJsxContext(state, doc, position)) { } else if (isHtmlContext(state, doc, position)) {
classNames = await findClassNamesInRange(state, doc, searchRange, 'html') classNames = await findClassNamesInRange(state, doc, searchRange, 'html')
} else if (isJsxContext(state, doc, position)) {
classNames = await findClassNamesInRange(state, doc, searchRange, 'jsx')
} }
if (classNames.length === 0) { if (classNames.length === 0) {

View File

@ -5,6 +5,7 @@ import { indexToPosition } from './find'
import { isJsDoc } from './js' import { isJsDoc } from './js'
import moo from 'moo' import moo from 'moo'
import Cache from 'tmp-cache' import Cache from 'tmp-cache'
import { getTextWithoutComments } from './doc'
export type LanguageBoundary = { type: 'html' | 'js' | 'css' | string; range: Range } export type LanguageBoundary = { type: 'html' | 'js' | 'css' | string; range: Range }
@ -113,10 +114,14 @@ export function getLanguageBoundaries(
return cachedBoundaries return cachedBoundaries
} }
let isJs = isJsDoc(state, doc)
let defaultType = isVueDoc(doc) let defaultType = isVueDoc(doc)
? 'none' ? 'none'
: isHtmlDoc(state, doc) || isJsDoc(state, doc) || isSvelteDoc(doc) : isHtmlDoc(state, doc) || isSvelteDoc(doc)
? 'html' ? 'html'
: isJs
? 'jsx'
: null : null
if (defaultType === null) { if (defaultType === null) {
@ -124,6 +129,8 @@ export function getLanguageBoundaries(
return null return null
} }
text = getTextWithoutComments(text, isJs ? 'js' : 'html')
let lexer = defaultType === 'none' ? vueLexer : defaultLexer let lexer = defaultType === 'none' ? vueLexer : defaultLexer
lexer.reset(text) lexer.reset(text)