public async Task <CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken) { var documentHash = Hash.StringHash(request.TextDocument.Uri.GetFileSystemPath()); var pos = request.Position; var namesPtr = TreeSitter.GetCompletionItems(documentHash, pos.Line, pos.Character, (int)request.Context.TriggerKind); var names = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(namesPtr); if (names == null) { return(new CompletionList()); } var nameList = names.Split(","); List <CompletionItem> items = new List <CompletionItem>(nameList.Length); int sortValue = 0; foreach (var name in nameList) { if (name == "") { continue; } var completion = new CompletionItem(); completion.Label = name; completion.SortText = sortValue.ToString("D8"); completion.FilterText = name.ToLower(); items.Add(completion); sortValue++; } return(new CompletionList(items)); }
public Task <Unit> Handle(DidOpenTextDocumentParams notification, CancellationToken token) { var path = notification.TextDocument.Uri.GetFileSystemPath(); var hash = Hash.StringHash(path); hashNamer.hashToName[hash] = path; TreeSitter.CreateTree(path, notification.TextDocument.Text, notification.TextDocument.Text.Length); return(Unit.Task); }
public Task <Hover> Handle(HoverParams request, CancellationToken cancellationToken) { var hash = Hash.StringHash(request.TextDocument.Uri.GetFileSystemPath()); var ptr = TreeSitter.Hover(hash, request.Position.Line, request.Position.Character); var str = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr); var hover = new Hover(); if (str != null) { hover.Contents = new MarkedStringsOrMarkupContent(str); } return(Task.FromResult(hover)); }
public Task <Unit> Handle(DidChangeTextDocumentParams request, CancellationToken token) { var documentPath = request.TextDocument.Uri.GetFileSystemPath(); var hash = Hash.StringHash(documentPath); foreach (var change in request.ContentChanges) { var range = change.Range; var start = range.Start; var end = range.End; TreeSitter.EditTree(hash, change.Text, start.Line, start.Character, end.Line, end.Character, change.Text.Length, change.RangeLength); } TreeSitter.UpdateTree(hash); return(Unit.Task); }
public Task <LocationOrLocationLinks> Handle(DefinitionParams request, CancellationToken cancellationToken) { var hash = Hash.StringHash(request.TextDocument.Uri.GetFileSystemPath()); TreeSitter.FindDefinition(hash, request.Position.Line, request.Position.Character, out var defHash, out var origin, out var target, out var selection); if (defHash != 0) { LocationLink link = new LocationLink(); link.TargetUri = DocumentUri.FromFileSystemPath(hashNamer.hashToName[defHash]); link.OriginSelectionRange = ConvertRange(origin); link.TargetRange = ConvertRange(target); link.TargetSelectionRange = ConvertRange(selection); LocationOrLocationLinks ll = new LocationOrLocationLinks(link); return(Task.FromResult(ll)); } return(Task.FromResult(new LocationOrLocationLinks())); }
protected override async Task Tokenize( SemanticTokensBuilder builder, ITextDocumentIdentifierParams identifier, CancellationToken cancellationToken ) { var hash = Hash.StringHash(identifier.TextDocument.Uri.GetFileSystemPath()); var now = DateTime.Now; IntPtr tokensPtr = IntPtr.Zero; int count = 0; long internalMicros = TreeSitter.GetTokens(hash, out tokensPtr, out count); // this can be async because it actually does work. var then = DateTime.Now; var elapsed = then - now; _logger.LogInformation("Elapsed time for C++ tokens: " + elapsed.TotalMilliseconds + " native time: " + internalMicros); List <Diagnostic> diagnostics = new List <Diagnostic>(); unsafe { SemanticToken *ptr = (SemanticToken *)tokensPtr; for (int i = 0; i < count; i++) { if ((int)ptr[i].type == 255) { Diagnostic diag = new Diagnostic(); diag.Severity = DiagnosticSeverity.Error; diag.Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range(); diag.Range.Start = new Position(ptr[i].line, ptr[i].col); diag.Range.End = new Position(ptr[i].line, ptr[i].col + ptr[i].length); diag.Message = "undeclared identifer"; diagnostics.Add(diag); continue; } builder.Push(ptr[i].line, ptr[i].col, ptr[i].length, (int)ptr[i].type, (int)ptr[i].modifier); } } diagnoser.Add(identifier.TextDocument.Uri, 0, diagnostics); diagnoser.Publish(identifier.TextDocument.Uri); }
static async Task MainAsync(string[] args) { #if DEBUG System.Diagnostics.Debugger.Launch(); #endif TreeSitter.Init(); var server = await LanguageServer.From(options => options .WithInput(Console.OpenStandardInput()) .WithOutput(Console.OpenStandardOutput()) .ConfigureLogging(x => x .AddSerilog() .AddLanguageProtocolLogging() #if DEBUG .SetMinimumLevel(LogLevel.Error)) #else .SetMinimumLevel(LogLevel.Error)) #endif .WithHandler <SignatureHelper>() .WithHandler <Definer>() .WithHandler <Hoverer>() .WithHandler <TextDocumentHandler>() .WithHandler <CompletionHandler>() // .WithHandler<WorkspaceFolderChangeHandler>() // handlers added after here dont work i think! .WithHandler <SemanticTokensHandler>() .WithServices(ConfigureServices) .WithServices(x => x.AddLogging(b => b.SetMinimumLevel(LogLevel.Error))) .WithServices(services => { services.AddSingleton(provider => { var loggerFactory = provider.GetService <ILoggerFactory>(); var logger = loggerFactory.CreateLogger <Logjam>(); logger.LogInformation("Configuring"); return(new Logjam(logger)); }) .AddSingleton <HashNamer>() .AddSingleton <Diagnoser>(); }) .OnInitialized(async(server, request, response, cancellationToken) => { var path = Path.Combine(request.RootUri.GetFileSystemPath(), "modules"); TreeSitter.AddModuleDirectory(path); }) .OnStarted(async(languageServer, token) => { //using var manager = await languageServer.WorkDoneManager.Create(new WorkDoneProgressBegin() { Title = "Parsing Modules", Percentage = 0, Cancellable = true }); var logger = languageServer.Services.GetService <ILogger <Logjam> >(); var namer = languageServer.Services.GetService <HashNamer>(); var diagnoser = languageServer.Services.GetService <Diagnoser>(); diagnoser.server = languageServer; WorkspaceFolderParams wsf = new WorkspaceFolderParams(); var wsfresults = await languageServer.Client.SendRequest(wsf, token); foreach (var folder in wsfresults) { // find all the jai files and hash their paths string[] files = Directory.GetFiles(folder.Uri.GetFileSystemPath(), "*.jai", SearchOption.AllDirectories); foreach (var f in files) { namer.hashToName[Hash.StringHash(f)] = f; } } /* * * var path = Path.Combine(folder.Uri.GetFileSystemPath(), "modules"); * var moduleDirectories = Directory.EnumerateDirectories(path); * var count = moduleDirectories.Count(); * int current = 0; * List<Task<string>> tasks = new List<Task<string>>(); * long totalTime = 0; * * foreach (var moduleDirectory in moduleDirectories) * { * var moduleFilePath = Path.Combine(moduleDirectory, "module.jai"); * * // chop off path and get module name; * var separatorIndex = moduleDirectory.LastIndexOf(Path.DirectorySeparatorChar); * var moduleName = moduleDirectory.Substring(separatorIndex + 1); * var exists = File.Exists(moduleFilePath); * * if (exists) * { * modules.Add(new Tuple<string,string>(moduleFilePath, moduleName) ); * * * //totalTime += TreeSitter.CreateTreeFromPath(moduleFilePath, moduleName); * //current++; * } * * } * * foreach(var module in modules) * { * TreeSitter.RegisterModule(module.Item1, module.Item2); * } * * foreach (var module in modules) * { * var task = Task.Run(() => * { * TreeSitter.CreateTreeFromPath(module.Item1, module.Item2); * return module.Item1; * }); * tasks.Add(task); * } * * * while (current < tasks.Count) * { * var task = await Task.WhenAny(tasks); * current++; * manager.OnNext(new WorkDoneProgressReport() { Message = task.Result, Percentage = (double)current / count }); * } * * logger.LogInformation("Total time for serial module parsing: " + totalTime + " micros"); * * } * manager.OnCompleted(); */ }) ); // lmao i have no idea await server.WaitForExit; }
public override Task <SignatureHelp> Handle(SignatureHelpParams request, CancellationToken cancellationToken) { var currentHash = Hash.StringHash(request.TextDocument.Uri.GetFileSystemPath()); var pos = request.Position; TreeSitter.GetSignature(currentHash, pos.Line, pos.Character, out var signatureArrayPtr, out var parameterCount, out var activeParameter, out var errorCount, out var errorRanges); if (signatureArrayPtr.ToInt64() == 0) { return(Task.FromResult(new SignatureHelp())); } var signaturePtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(signatureArrayPtr); var signature = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(signaturePtr); SignatureInformation info = new SignatureInformation(); info.Label = signature; var paramList = new List <ParameterInformation>(); if (parameterCount > 0) { for (int i = 0; i < parameterCount; i++) { var paramInfo = new ParameterInformation(); var paramPtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(signatureArrayPtr + 8 * (i + 1));; paramInfo.Label = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(paramPtr); paramList.Add(paramInfo); } } info.Parameters = new Container <ParameterInformation>(paramList); SignatureHelp help = new SignatureHelp(); help.Signatures = new Container <SignatureInformation>(info); help.ActiveParameter = activeParameter; help.ActiveSignature = 0; if (errorCount > 0) { List <Diagnostic> diagnostics = new List <Diagnostic>(); PublishDiagnosticsParams diagnosticsParams = new PublishDiagnosticsParams(); diagnosticsParams.Uri = request.TextDocument.Uri; unsafe { for (int i = 0; i < errorCount; i++) { Range * errors = (Range *)errorRanges; var error = errors[i]; Diagnostic diagnostic = new Diagnostic(); diagnostic.Message = "Extra argument"; diagnostic.Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range( new Position(error.startLine, error.startCol), new Position(error.endLine, error.endCol)); diagnostics.Add(diagnostic); } } diagnoser.Add(request.TextDocument.Uri, 1, diagnostics); } else { diagnoser.Add(request.TextDocument.Uri, 1, new List <Diagnostic>()); } return(Task.FromResult(help)); }