Compare commits

...

6 Commits

6 changed files with 46 additions and 25 deletions

4
.gitignore vendored
View File

@ -34,4 +34,6 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
.DS_Store
/tmp
/docs
/docs
*.vsix

View File

@ -1,4 +0,0 @@
node_modules
client/dist
server/dist
*.vsix

View File

@ -1,12 +1,12 @@
import { TextDocument, Position } from 'vscode-languageserver-textdocument'
import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver/node'
import { parser } from '../../../src/parser/shrimp'
import { Tree } from '@lezer/common'
import { Compiler } from '../../../src/compiler/compiler'
import { CompilerError } from '../../../src/compiler/compilerError'
export const buildDiagnostics = (textDocument: TextDocument): Diagnostic[] => {
export const buildDiagnostics = (textDocument: TextDocument, tree: Tree): Diagnostic[] => {
const text = textDocument.getText()
const diagnostics = getParseErrors(textDocument)
const diagnostics = getParseErrors(textDocument, tree)
if (diagnostics.length > 0) {
return diagnostics
@ -59,9 +59,7 @@ const unknownDiagnostic = (message: string): Diagnostic => {
return diagnostic
}
const getParseErrors = (textDocument: TextDocument): Diagnostic[] => {
const tree = parser.parse(textDocument.getText())
const getParseErrors = (textDocument: TextDocument, tree: Tree): Diagnostic[] => {
const ranges: { start: Position; end: Position }[] = []
tree.iterate({
enter(n) {

View File

@ -1,6 +1,6 @@
import { parser } from '../../../src/parser/shrimp'
import * as Terms from '../../../src/parser/shrimp.terms'
import { SyntaxNode } from '@lezer/common'
import { SyntaxNode, Tree } from '@lezer/common'
import { TextDocument } from 'vscode-languageserver-textdocument'
import {
SemanticTokensBuilder,
@ -28,9 +28,7 @@ export const TOKEN_MODIFIERS = [
SemanticTokenModifiers.readonly,
]
export function buildSemanticTokens(document: TextDocument): number[] {
const text = document.getText()
const tree = parser.parse(text)
export function buildSemanticTokens(document: TextDocument, tree: Tree): number[] {
const builder = new SemanticTokensBuilder()
const scopeTracker = new EditorScopeAnalyzer(document)

View File

@ -3,6 +3,7 @@ import { buildDiagnostics } from './diagnostics'
import { buildSemanticTokens, TOKEN_MODIFIERS, TOKEN_TYPES } from './semanticTokens'
import { parser } from '../../../src/parser/shrimp'
import { Compiler } from '../../../src/compiler/compiler'
import { Tree } from '@lezer/common'
import {
InitializeResult,
TextDocuments,
@ -10,18 +11,23 @@ import {
createConnection,
ProposedFeatures,
CompletionItemKind,
TextDocumentChangeEvent,
} from 'vscode-languageserver/node'
const connection = createConnection(ProposedFeatures.all)
const documents = new TextDocuments(TextDocument)
documents.listen(connection)
const documentTrees = new Map<string, Tree>()
// Server capabilities
connection.onInitialize(handleInitialize)
// Language features
connection.languages.semanticTokens.on(handleSemanticTokens)
documents.onDidOpen(handleDocumentOpen)
documents.onDidChangeContent(handleDocumentChange)
documents.onDidClose(handleDocumentClose)
connection.onCompletion(handleCompletion)
// Debug commands
@ -31,10 +37,7 @@ connection.onRequest('shrimp/bytecode', handleBytecode)
// Start listening
connection.listen()
// ============================================================================
// Handler implementations
// ============================================================================
function handleInitialize(): InitializeResult {
connection.console.log('🦐 Server initialized with capabilities')
const result: InitializeResult = {
@ -56,21 +59,40 @@ function handleInitialize(): InitializeResult {
return result
}
function handleDocumentOpen(event: TextDocumentChangeEvent<TextDocument>) {
const document = event.document
const tree = parser.parse(document.getText())
documentTrees.set(document.uri, tree)
}
function handleSemanticTokens(params: any) {
const document = documents.get(params.textDocument.uri)
if (!document) return { data: [] }
const data = buildSemanticTokens(document)
const tree = documentTrees.get(params.textDocument.uri)
if (!tree) return { data: [] }
const data = buildSemanticTokens(document, tree)
return { data }
}
function handleDocumentChange(change: any) {
const textDocument = change.document
const diagnostics = buildDiagnostics(textDocument)
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics })
function handleDocumentChange(change: TextDocumentChangeEvent<TextDocument>) {
const document = change.document
// Parse and cache
const tree = parser.parse(document.getText())
documentTrees.set(document.uri, tree)
// Build diagnostics using cached tree
const diagnostics = buildDiagnostics(document, tree)
connection.sendDiagnostics({ uri: document.uri, diagnostics })
}
function handleCompletion(params: any) {
function handleDocumentClose(event: TextDocumentChangeEvent<TextDocument>) {
documentTrees.delete(event.document.uri)
}
function handleCompletion() {
const keywords = ['if', 'else', 'do', 'end', 'and', 'or', 'true', 'false', 'null']
return keywords.map((keyword) => ({
@ -84,8 +106,13 @@ function handleParseTree(params: { uri: string }) {
const document = documents.get(params.uri)
if (!document) return 'Document not found'
const tree = documentTrees.get(params.uri)
if (!tree) {
connection.console.error(`🦐 No cached tree for ${params.uri}`)
return 'No cached parse tree available'
}
const text = document.getText()
const tree = parser.parse(text)
const cursor = tree.cursor()
let formatted = ''

Binary file not shown.