✨ feat(vscode): 代码阅读认出代码里起的中文名(Annotated[…, Comment("…")]、@Comment 装饰器、行尾 # @Comment、docstring / JSDoc 的参数说明),预览里定义和用到它的各处都写中文名,悬停看原名,定义处后面淡淡写原名
This commit is contained in:
1 parent
1b1299dc1f
commit
44c221ea2b
45 files changed
+1685
-128
No files matched your search
@@ -1,9 +1,9 @@
|
||||
import type { Tree } from '@vscode/tree-sitter-wasm'
|
||||
import type { RuleLocation, RulePosition, RuleWorkspace, WorkspaceIndex } from './contract'
|
||||
import type { IndexedFile, IndexEntry, Node, RuleLocation, RulePosition, RuleWorkspace, WorkspaceIndex } from './contract'
|
||||
import * as path from 'node:path'
|
||||
|
||||
/**
|
||||
* 库规则的工作区索引(WorkspaceIndex)的宿主部分:找文件、预筛、解析、缓存,跟着文件改动只重看改了的文件。
|
||||
* 工作区索引(WorkspaceIndex:库规则的,和宿主自己认中文名的)的宿主部分:找文件、预筛、解析、缓存,跟着文件改动只重看改了的文件。
|
||||
* 规则只说要什么;这里不碰 VS Code,工作区的能力由 IndexHost 给(VS Code 里是 workspaceFiles.ts,测试里是内存里的文件)。
|
||||
*/
|
||||
|
||||
@@ -52,10 +52,18 @@ function positionAt(starts: number[], index: number): RulePosition {
|
||||
return { line: low, character: index - starts[low] }
|
||||
}
|
||||
|
||||
/** 认出的一项在哪:定义处名字的位置,连同认的时候给的这一项(宿主自己的索引在项里多带东西,例如中文名)。 */
|
||||
export interface IndexedEntry<E extends IndexEntry = IndexEntry> { location: RuleLocation, entry: E }
|
||||
|
||||
/** 认出的项是 E 的索引。 */
|
||||
export interface WorkspaceIndexOf<E extends IndexEntry> extends WorkspaceIndex {
|
||||
entries: (root: Node, file: IndexedFile) => E[]
|
||||
}
|
||||
|
||||
/** 一份看过的文件:认出的各项,和建索引时问过在不在的文件(它们新建、删掉时这份要重看)。 */
|
||||
interface Indexed {
|
||||
interface Indexed<E extends IndexEntry> {
|
||||
file: WorkspaceFile
|
||||
entries: { key: string, location: RuleLocation }[]
|
||||
entries: IndexedEntry<E>[]
|
||||
asked: Set<string>
|
||||
}
|
||||
|
||||
@@ -64,25 +72,25 @@ function compareLocations(a: RuleLocation, b: RuleLocation): number {
|
||||
}
|
||||
|
||||
/** 一个 WorkspaceIndex 建出来的索引:建好之前的查询、文件改动都排在建索引后面,一件件来。 */
|
||||
class BuiltIndex {
|
||||
class BuiltIndex<E extends IndexEntry> {
|
||||
/** include 找到的全部文件(按 keyOf),IndexedFile.exists 查的就是它 */
|
||||
private readonly files = new Map<string, WorkspaceFile>()
|
||||
/** 预筛过了、解析过的文件 */
|
||||
private readonly indexed = new Map<string, Indexed>()
|
||||
private readonly indexed = new Map<string, Indexed<E>>()
|
||||
private readonly watcher: { dispose: () => void }
|
||||
private queue: Promise<void>
|
||||
|
||||
constructor(private readonly index: WorkspaceIndex, private readonly host: IndexHost) {
|
||||
constructor(private readonly index: WorkspaceIndexOf<E>, private readonly host: IndexHost) {
|
||||
// 先盯着再找文件:找文件期间的改动排在建好之后补上
|
||||
this.watcher = host.watch(index.include, event => this.enqueue(() => this.apply(event)))
|
||||
this.queue = this.guard(() => this.build())
|
||||
}
|
||||
|
||||
async lookup(key: string): Promise<RuleLocation[]> {
|
||||
async lookup(key: string): Promise<IndexedEntry<E>[]> {
|
||||
await this.queue
|
||||
return [...this.indexed.values()]
|
||||
.flatMap(indexed => indexed.entries.filter(entry => entry.key === key).map(entry => entry.location))
|
||||
.sort(compareLocations)
|
||||
.flatMap(indexed => indexed.entries.filter(({ entry }) => entry.key === key))
|
||||
.sort((a, b) => compareLocations(a.location, b.location))
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
@@ -134,9 +142,9 @@ class BuiltIndex {
|
||||
return this.files.has(other)
|
||||
}
|
||||
const starts = lineStarts(source)
|
||||
const entries = this.index.entries(tree.rootNode, { path: file.path, source, exists }).map(({ key: entryKey, name }) => ({
|
||||
key: entryKey,
|
||||
location: { uri: file.uri, start: positionAt(starts, name.startIndex), end: positionAt(starts, name.endIndex) },
|
||||
const entries = this.index.entries(tree.rootNode, { path: file.path, source, exists }).map(entry => ({
|
||||
entry,
|
||||
location: { uri: file.uri, start: positionAt(starts, entry.name.startIndex), end: positionAt(starts, entry.name.endIndex) },
|
||||
}))
|
||||
this.indexed.set(key, { file, entries, asked })
|
||||
}
|
||||
@@ -186,12 +194,17 @@ class BuiltIndex {
|
||||
|
||||
/** 各库规则的工作区索引:第一次查某个索引时才建,同一个 id 只建一份。 */
|
||||
export class WorkspaceIndexes implements RuleWorkspace {
|
||||
private readonly built = new Map<string, BuiltIndex>()
|
||||
private readonly built = new Map<string, BuiltIndex<IndexEntry>>()
|
||||
|
||||
constructor(private readonly host: IndexHost) {}
|
||||
|
||||
lookup(index: WorkspaceIndex, key: string): Promise<RuleLocation[]> {
|
||||
let built = this.built.get(index.id)
|
||||
async lookup(index: WorkspaceIndex, key: string): Promise<RuleLocation[]> {
|
||||
return (await this.find(index, key)).map(({ location }) => location)
|
||||
}
|
||||
|
||||
/** 同 lookup,连同认出的那一项(第一次查时建,同一个 id 只建一份)。 */
|
||||
find<E extends IndexEntry>(index: WorkspaceIndexOf<E>, key: string): Promise<IndexedEntry<E>[]> {
|
||||
let built = this.built.get(index.id) as BuiltIndex<E> | undefined
|
||||
if (!built) {
|
||||
built = new BuiltIndex(index, this.host)
|
||||
this.built.set(index.id, built)
|
||||
|
||||
Reference in new issue
Block a user