-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add reference and definition provider #145
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,20 @@ | ||
import type { ParseError } from 'dt-sql-parser'; | ||
import { EntityContext } from 'dt-sql-parser/dist/parser/common/entityCollector'; | ||
import { WordPosition } from 'dt-sql-parser/dist/parser/common/textAndWord'; | ||
import * as monaco from 'monaco-editor'; | ||
|
||
import { BaseSQLWorker } from './baseSQLWorker'; | ||
import { debounce } from './common/utils'; | ||
import { | ||
CancellationToken, | ||
editor, | ||
Uri, | ||
IDisposable, | ||
MarkerSeverity, | ||
Range, | ||
languages, | ||
MarkerSeverity, | ||
Position, | ||
CancellationToken | ||
Range, | ||
Uri | ||
} from './fillers/monaco-editor-core'; | ||
import { debounce } from './common/utils'; | ||
import { BaseSQLWorker } from './baseSQLWorker'; | ||
import type { ParseError } from 'dt-sql-parser'; | ||
import type { LanguageServiceDefaults } from './monaco.contribution'; | ||
|
||
export interface WorkerAccessor<T extends BaseSQLWorker> { | ||
|
@@ -197,3 +201,102 @@ export class CompletionAdapter<T extends BaseSQLWorker> | |
}); | ||
} | ||
} | ||
|
||
export class DefinitionAdapter<T extends BaseSQLWorker> implements languages.DefinitionProvider { | ||
constructor( | ||
private readonly _worker: WorkerAccessor<T>, | ||
private readonly _defaults: LanguageServiceDefaults | ||
) {} | ||
provideDefinition( | ||
model: editor.IReadOnlyModel, | ||
position: Position, | ||
_token: CancellationToken | ||
): languages.ProviderResult<languages.Definition | languages.LocationLink[]> { | ||
const resource = model.uri; | ||
const lineContent = model.getLineContent(position.lineNumber); | ||
if (lineContent.startsWith('--')) return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里是否还要考虑块级注释 /* DROP TABLE IF EXISTS aabb; */
-- DROP TABLE IF EXISTS aabb;
DROP TABLE IF EXISTS aabb; |
||
return this._worker(resource) | ||
.then((worker) => { | ||
let code = model?.getValue() || ''; | ||
if (typeof this._defaults.preprocessCode === 'function') { | ||
code = this._defaults.preprocessCode(code); | ||
} | ||
return worker.getAllEntities(code); | ||
}) | ||
.then((entities) => { | ||
const word = model.getWordAtPosition(position); | ||
let pos: WordPosition = { | ||
line: -1, | ||
startIndex: -1, | ||
endIndex: -1, | ||
startColumn: -1, | ||
endColumn: -1 | ||
}; | ||
entities?.forEach((entity: EntityContext) => { | ||
if ( | ||
entity.entityContextType.includes('Create') && | ||
word?.word && | ||
entity.text === word?.word | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 如果字段实体和表实体重名了,那也会被跳转到定义 |
||
) { | ||
pos = entity.position; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 找到后可以终端循环 |
||
} | ||
}); | ||
if (pos && pos.line !== -1) { | ||
return { | ||
uri: model.uri, | ||
range: new monaco.Range( | ||
pos?.line, | ||
pos?.startColumn, | ||
pos?.line, | ||
pos?.endColumn | ||
) | ||
}; | ||
} | ||
}); | ||
} | ||
} | ||
|
||
export class ReferenceAdapter<T extends BaseSQLWorker> implements languages.ReferenceProvider { | ||
constructor( | ||
private readonly _worker: WorkerAccessor<T>, | ||
private readonly _defaults: LanguageServiceDefaults | ||
) {} | ||
provideReferences( | ||
model: editor.IReadOnlyModel, | ||
position: Position, | ||
_context: languages.ReferenceContext, | ||
_token: CancellationToken | ||
): languages.ProviderResult<languages.Location[]> { | ||
const resource = model.uri; | ||
const lineContent = model.getLineContent(position.lineNumber); | ||
if (!lineContent.startsWith('CREATE')) return; | ||
return this._worker(resource) | ||
.then((worker) => { | ||
let code = model?.getValue() || ''; | ||
if (typeof this._defaults.preprocessCode === 'function') { | ||
code = this._defaults.preprocessCode(code); | ||
} | ||
return worker.getAllEntities(model?.getValue()); | ||
}) | ||
.then((entities) => { | ||
const word = model.getWordAtPosition(position); | ||
const arr: languages.Location[] = []; | ||
entities?.forEach((entity) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 考虑是否支持外部自定义跳转位置,另一个provider同 |
||
if (word?.word && entity.text === word?.word) { | ||
let pos: WordPosition | null = null; | ||
pos = entity.position; | ||
arr.push({ | ||
uri: model.uri, | ||
range: new monaco.Range( | ||
pos?.line, | ||
pos?.startColumn, | ||
pos?.line, | ||
pos?.endColumn | ||
) | ||
}); | ||
} | ||
}); | ||
return arr; | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
看下两个 Provider 要不要加下注释