63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
import type { TextDocument, Range } from 'vscode-languageserver'
|
|
import moo from 'moo'
|
|
|
|
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 getJsWithoutComments(text)
|
|
}
|
|
|
|
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' : ' '))
|
|
}
|
|
|
|
let jsLexer: moo.Lexer
|
|
|
|
function getJsWithoutComments(text: string): string {
|
|
if (!jsLexer) {
|
|
jsLexer = moo.states({
|
|
main: {
|
|
commentLine: /\/\/.*?$/,
|
|
commentBlock: { match: /\/\*[^]*?\*\//, lineBreaks: true },
|
|
stringDouble: /"(?:[^"\\]|\\.)*"/,
|
|
stringSingle: /'(?:[^'\\]|\\.)*'/,
|
|
stringBacktick: /`(?:[^`\\]|\\.)*`/,
|
|
other: { match: /[^]/, lineBreaks: true },
|
|
},
|
|
})
|
|
}
|
|
|
|
let str = ''
|
|
jsLexer.reset(text)
|
|
|
|
for (let token of jsLexer) {
|
|
if (token.type === 'commentLine') {
|
|
str += ' '.repeat(token.value.length)
|
|
} else if (token.type === 'commentBlock') {
|
|
str += token.value.replace(/./g, ' ')
|
|
} else {
|
|
str += token.value
|
|
}
|
|
}
|
|
|
|
return str
|
|
}
|