Skip to content

Commit

Permalink
feat: run VLS in dev mode
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Jun 10, 2021
1 parent b96204a commit cf16f1b
Show file tree
Hide file tree
Showing 12 changed files with 1,284 additions and 55 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ module.exports = {
```ts
export interface PluginOptions {
/**
* Use `"tsc"` or `"vue-tsc"` or Checker
* Use `"tsc"` or `"vue-tsc"` or custom checker instance
* @defaultValue `"tcs"`
*/
checker: 'tsc' | 'vue-tsc'
checker: 'tsc' | 'vue-tsc' | Checker
/**
* Throw in build mode if has error
* @defaultValue `true`
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"dependencies": {
"@babel/code-frame": "^7.12.13",
"npm-run-path": "^4.0.1",
"strip-ansi": "^6.0.0"
"strip-ansi": "^6.0.0",
"vscode-languageclient": "^7.0.0"
},
"peerDependencies": {
"vite": "^2.0.0"
Expand Down
6 changes: 2 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 29 additions & 26 deletions presets/vls/src/commands/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import fs from 'fs'
import glob from 'glob'
import path from 'path'
import { Duplex } from 'stream'
import { range2Location } from 'vite-plugin-ts-checker'
import { VLS } from 'vls'
import { Range } from 'vscode-languageclient'
import { PublishDiagnosticsParams } from 'vscode-languageclient/node'
import {
createConnection,
createProtocolConnection,
Diagnostic,
DiagnosticSeverity,
DidOpenTextDocumentNotification,
DidChangeTextDocumentNotification,
DidOpenTextDocumentNotification,
InitializeParams,
InitializeRequest,
InitializeResult,
Expand All @@ -23,7 +24,7 @@ import {
} from 'vscode-languageserver/node'
import { URI } from 'vscode-uri'

import { codeFrameColumns, SourceLocation } from '@babel/code-frame'
import { codeFrameColumns } from '@babel/code-frame'

import { getInitParams } from '../initParams'

Expand All @@ -36,7 +37,17 @@ const logLevel2Severity = {
HINT: DiagnosticSeverity.Hint,
}

export async function diagnostics(workspace: string | null, logLevel: LogLevel, watch = false) {
export interface DiagnosticOptions {
watch: boolean
errorCallback?: (diagnostic: PublishDiagnosticsParams) => void
}

export async function diagnostics(
workspace: string | null,
logLevel: LogLevel,
options: DiagnosticOptions = { watch: false }
) {
const { watch, errorCallback } = options
console.log('====================================')
console.log('Getting Vetur diagnostics')
let workspaceUri
Expand All @@ -50,7 +61,7 @@ export async function diagnostics(workspace: string | null, logLevel: LogLevel,
workspaceUri = URI.file(process.cwd())
}

const errCount = await getDiagnostics(workspaceUri, logLevel2Severity[logLevel], watch)
const errCount = await getDiagnostics(workspaceUri, logLevel2Severity[logLevel], options)
console.log('====================================')

if (errCount === 0) {
Expand Down Expand Up @@ -82,7 +93,7 @@ class TestStream extends Duplex {
public _read(_size: number) {}
}

async function prepareClientConnection(workspaceUri: URI) {
async function prepareClientConnection(workspaceUri: URI, options: DiagnosticOptions) {
const up = new TestStream()
const down = new TestStream()
const logger = new NullLogger()
Expand All @@ -100,8 +111,7 @@ async function prepareClientConnection(workspaceUri: URI) {

// NOTE: hijack sendDiagnostics
serverConnection.sendDiagnostics = (diagnostic) => {
if (!diagnostic.diagnostics.length) return
console.log(chalk.red(JSON.stringify(diagnostic, null, 2)))
options.errorCallback?.(diagnostic)
}

const vls = new VLS(serverConnection as any)
Expand All @@ -127,21 +137,12 @@ async function prepareClientConnection(workspaceUri: URI) {
return clientConnection
}

function range2Location(range: Range): SourceLocation {
return {
start: {
line: range.start.line + 1,
column: range.start.character + 1,
},
end: {
line: range.end.line + 1,
column: range.end.character + 1,
},
}
}

async function getDiagnostics(workspaceUri: URI, severity: DiagnosticSeverity, watch: boolean) {
const clientConnection = await prepareClientConnection(workspaceUri)
async function getDiagnostics(
workspaceUri: URI,
severity: DiagnosticSeverity,
options: DiagnosticOptions
) {
const clientConnection = await prepareClientConnection(workspaceUri, options)

const files = glob.sync('**/*.vue', { cwd: workspaceUri.fsPath, ignore: ['node_modules/**'] })

Expand All @@ -150,14 +151,15 @@ async function getDiagnostics(workspaceUri: URI, severity: DiagnosticSeverity, w
return 0
}

console.log('')
console.log('Getting diagnostics from: ', files, '\n')
// console.log('')
// console.log('Getting diagnostics from: ', files, '\n')

const absFilePaths = files.map((f) => path.resolve(workspaceUri.fsPath, f))

let errCount = 0

if (watch) {
// watched diagnostics
if (options.watch) {
chokidar
.watch(workspaceUri.fsPath, {
ignored: (path: string) => path.includes('node_modules'),
Expand All @@ -175,6 +177,7 @@ async function getDiagnostics(workspaceUri: URI, severity: DiagnosticSeverity, w
})
}

// initial diagnostics
for (const absFilePath of absFilePaths) {
const fileText = fs.readFileSync(absFilePath, 'utf-8')
clientConnection.sendNotification(DidOpenTextDocumentNotification.type, {
Expand Down
25 changes: 22 additions & 3 deletions presets/vls/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { UserConfig, ViteDevServer } from 'vite'
import { CheckerFactory, CreateDiagnostic, PluginOptions } from 'vite-plugin-ts-checker'
import { diagnostics, logLevels } from './commands/diagnostics'
import { CheckerFactory, CreateDiagnostic, lspDiagnosticToViteError } from 'vite-plugin-ts-checker'

import { codeFrameColumns } from '@babel/code-frame'

import { DiagnosticOptions, diagnostics } from './commands/diagnostics'

export const createDiagnostic: CreateDiagnostic = (userOptions = {}) => {
let overlay = true // Vite defaults to true
Expand All @@ -16,7 +19,23 @@ export const createDiagnostic: CreateDiagnostic = (userOptions = {}) => {
},
async configureServer(server: ViteDevServer) {
const workDir: string = userOptions.root ?? server.config.root
await diagnostics(workDir, 'WARN', true)
const errorCallback: DiagnosticOptions['errorCallback'] = (d) => {
if (!d.diagnostics.length) return
const firstDiagnostic = d.diagnostics[0]

codeFrameColumns(firstDiagnostic.source || 'no code', {
start: { line: 1, column: 1 },
end: { line: 1, column: 1 },
})

const overlayErr = lspDiagnosticToViteError(d)
if (!overlayErr) return
server.ws.send({
type: 'error',
err: overlayErr,
})
}
await diagnostics(workDir, 'WARN', { watch: true, errorCallback })
},
}
}
Expand Down

0 comments on commit cf16f1b

Please sign in to comment.