Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": ["--profile=jails_dev", "--extensionDevelopmentPath=${workspaceFolder}/vscode_extension"],
"outFiles": ["${workspaceFolder}/vscode_extension/out/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Attach to Native Server (LLDB)",
"type": "lldb",
"request": "attach",
"name": "Debug",
"program": "${workspaceFolder}/<executable file>",
"pid": "${command:pickProcess}",
"initCommands": [
"command script import ${workspaceFolder}/.vscode/jaitype.py"
]
"program": "jails-darwin-arm64",
"waitFor": true
},
{
"type": "cppvsdbg",
Expand All @@ -21,5 +26,14 @@
"processId": "${command:pickProcess}",
"visualizerFile": "${workspaceFolder}/jai.natvis",
}
],
"compounds": [
{
"name": "Debug Extension and Server",
"configurations": [
"Attach to Native Server (LLDB)",
"Run Extension"
]
}
]
}
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"label": "build",
"type": "shell",
"command": "jai ${workspaceFolder}/build.jai - -vscode",
"command": "/Users/john/Downloads/jai/bin/jai-macos ${workspaceFolder}/build.jai - -replace-vscode-ext-bin",
"presentation": {
"echo": true,
"reveal": "silent",
Expand Down
30 changes: 21 additions & 9 deletions build.jai
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
array_add(*import_path, "./modules");

profile_server := array_find(args, "-profile_server");
replace_vscode_extension_binary := array_find(args, "-replace-vscode-ext-bin");
launch_vscode := array_find(args, "-vscode");
if launch_vscode replace_vscode_extension_binary = true;
release := array_find(args, "-release");
release_very := array_find(args, "-very-release");
arm := array_find(args, "-arm");
Expand All @@ -28,7 +30,8 @@
options.import_path = import_path;

if release set_optimization(*options, .OPTIMIZED);
if release_very set_optimization(*options, .VERY_OPTIMIZED);
else if release_very set_optimization(*options, .VERY_OPTIMIZED);
else set_optimization(*options, .DEBUG);

if arm options.cpu_target = .ARM64;

Expand Down Expand Up @@ -59,19 +62,29 @@
if tracy && tracy.shutdown tracy.shutdown(tracy);
}

// When we provide -vscode argument automatically launch vscode with our extension installed.
if ok && launch_vscode {
vscode_extension_directory := join(get_working_directory(), "/vscode_extension");
vscode_extension_development_path := join("--extensionDevelopmentPath=", vscode_extension_directory);
vscode_extension_directory := join(get_working_directory(), "/vscode_extension");
vscode_extension_development_path := join("--extensionDevelopmentPath=", vscode_extension_directory);

// When we provide `-replace-vscode-ext-bin` argument we patch in our binary to
// the already built extension. Also runs for `-vscode`
if ok && replace_vscode_extension_binary {
assert(OS == .WINDOWS || OS == .MACOS, "Replacing vscode extension binary on Linux is not supported at the time.");

print("%\n", vscode_extension_development_path);
if OS == .WINDOWS {
copy_file("bin/jails.exe", "vscode_extension/out/jails-win32-x64.exe");
}
if OS == .MACOS {
copy_file("bin/jails", "vscode_extension/out/jails-darwin-arm64");
}
}

assert(OS == .WINDOWS || OS == .MACOS, "Opening vscode on Linux is not supported at the time.");
// When we provide `-vscode` argument automatically launch vscode with our extension installed.
if ok && launch_vscode {
assert(OS == .WINDOWS || OS == .MACOS, "Launching vscode on Linux is not supported at the time.");

vscode_path: string;

if OS == .WINDOWS {
copy_file("bin/jails.exe", "vscode_extension/out/jails-win32-x64.exe");
username, ok := get_username();
if !ok {
log_error("Cannot resolve Windows username. Cannot launch vscode.");
Expand All @@ -85,7 +98,6 @@
}

if OS == .MACOS {
copy_file("bin/jails", "vscode_extension/out/jails-darwin-arm64");
vscode_path = "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code";
}

Expand Down
3 changes: 2 additions & 1 deletion jails.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"build.jai"
],
"build_root": "build.jai",
"auto_insert_parentheses": true
"auto_insert_parentheses": true,
"jai_path": "/Users/john/Downloads/jai"
}
2 changes: 1 addition & 1 deletion modules/jai_parser
95 changes: 37 additions & 58 deletions server/completition.jai
Original file line number Diff line number Diff line change
@@ -1,59 +1,43 @@


handle_completitions :: (request: LSP_Request_Message_Completion) {
push_allocator(temp);
handle_completitions :: (request: LSP_Request_Message_Completion) -> []LSP_Completion_Item {

file_path := normalize_path(request.params.textDocument.uri);

_exit :: () #expand {
`lsp_respond(request.id, null);
`return;
}

file := get_file(file_path);
if !file {
_exit();
return .[];
}

cursor_location := lsp_location_to_node_location(request.params.position, file_path);
cursor_block := cast(*Block) get_node_by_location(file, cursor_location, .BLOCK);
cursor_node := get_node_by_location(file, cursor_location);

if !cursor_node {
return;
return .[];
}

// We don't wanna to give completions inside strings and comments...
if cursor_node.kind == Node.Kind.LITERAL || cursor_node.kind == Node.Kind.COMMENT _exit();
if cursor_node.kind == Node.Kind.LITERAL || cursor_node.kind == Node.Kind.COMMENT return .[];

if cursor_node.kind == .DIRECTIVE_IMPORT {
handle_completitions_import(request, xx cursor_node);
return;
return handle_completitions_import(xx cursor_node);
}

if cursor_node.kind == .DIRECTIVE_LOAD {
handle_completitions_load(request, file, xx cursor_node);
return;
return handle_completitions_load(file, xx cursor_node);
}

decls: []*Declaration;
defer array_free(decls);
items := handle_dot_completitions(cursor_node, cursor_location);
if items.count > 0 return items;

if handle_dot_completitions(request, cursor_node, cursor_location) {
return;
}

if handle_assignment_completitions(request, cursor_node) {
return;
}
items = handle_assignment_completitions(cursor_node);
if items.count > 0 return items;

// General
decls = get_declarations(file, cursor_block, *cursor_location);

send_completions_decls(request, decls);
decls := get_declarations(file, cursor_block, *cursor_location);
return get_completions_decls(decls);
}

handle_completitions_load :: (request: LSP_Request_Message_Completion, file: *Program_File, directive_load: *Directive_Load) {
handle_completitions_load :: (file: *Program_File, directive_load: *Directive_Load) -> []LSP_Completion_Item {
completions: [..]LSP_Completion_Item;
current_file_dir := path_strip_filename(file.path);

Expand All @@ -76,19 +60,18 @@ handle_completitions_load :: (request: LSP_Request_Message_Completion, file: *Pr

is_dir, ok := is_directory(path_to_visit);
if !is_dir || !ok {
lsp_respond(request.id, null);
return;
return .[];
}

visit_files(path_to_visit, false, *completions, visit_file, true, true);

lsp_respond(request.id, completions);
return completions;
}

handle_completitions_import :: (request: LSP_Request_Message_Completion, directive_import: *Directive_Import) {
handle_completitions_import :: (directive_import: *Directive_Import) -> []LSP_Completion_Item {
completions: [..]LSP_Completion_Item;

modules_dir := sprint("%/modules", server.args.jai_path);
modules_dir := sprint("%/modules", server.jai_path);

visit_modules :: (info: *File_Visit_Info, completions: *[..]LSP_Completion_Item) {
if !info.is_directory && !contains(info.short_name, ".jai") return;
Expand Down Expand Up @@ -118,12 +101,12 @@ handle_completitions_import :: (request: LSP_Request_Message_Completion, directi
visit_files(local_modules_dir, false, *completions, visit_modules, true, true);
}

lsp_respond(request.id, completions);
return completions;
}

handle_dot_completitions :: (request: LSP_Request_Message_Completion, cursor_node: *Node, cursor_location: Node.Location) -> bool {
handle_dot_completitions :: (cursor_node: *Node, cursor_location: Node.Location) -> []LSP_Completion_Item {
if !cursor_node {
return false;
return .[];
}

op: *Binary_Operation;
Expand All @@ -132,11 +115,11 @@ handle_dot_completitions :: (request: LSP_Request_Message_Completion, cursor_nod
} else if cursor_node.parent && cursor_node.parent.kind == .BINARY_OPERATION {
op = cast(*Binary_Operation, cursor_node.parent);
} else {
return false;
return .[];
}

if op.operation != .DOT {
return false;
return .[];
}

path := get_dot_path(op, null);
Expand All @@ -155,41 +138,40 @@ handle_dot_completitions :: (request: LSP_Request_Message_Completion, cursor_nod

type := get_path_type(path);
if !type {
// log_error("type is invalid! (null)");
return false;
return .[];
}

return handle_completitions_for_node(request, type);
return handle_completitions_for_node(type);
}

handle_assignment_completitions :: (request: LSP_Request_Message_Completion, cursor_node: *Node) -> bool {
handle_assignment_completitions :: (cursor_node: *Node) -> []LSP_Completion_Item {
op: *Binary_Operation;
if cursor_node.kind == .BINARY_OPERATION {
op = cast(*Binary_Operation, cursor_node);
} else if cursor_node.parent && cursor_node.parent.kind == .BINARY_OPERATION {
op = cast(*Binary_Operation, cursor_node.parent);
} else {
return false;
return .[];
}

if op.operation != .ASSIGN && op.operation != .IS_EQUAL && op.operation != .IS_NOT_EQUAL {
return false;
return .[];
}

// @TODO: support more types!
if cursor_node.kind != .UNARY_OPERATION {
return false;
return .[];
}

left_type := get_node_type(op, true);
if !left_type {
return false;
return .[];
}

return handle_completitions_for_node(request, left_type);
return handle_completitions_for_node(left_type);
}

handle_completitions_for_node :: (request: LSP_Request_Message_Completion, node: *Node) -> bool {
handle_completitions_for_node :: (node: *Node) -> []LSP_Completion_Item {
// log("type kind: %", node.kind);
// log_node(node);

Expand Down Expand Up @@ -254,7 +236,7 @@ handle_completitions_for_node :: (request: LSP_Request_Message_Completion, node:
module_file := get_file(module_file_path);

if !module_file {
return false;
return .[];
}

for get_declarations(module_file, only_loaded=true) {
Expand All @@ -263,17 +245,14 @@ handle_completitions_for_node :: (request: LSP_Request_Message_Completion, node:
}

if decls.count == 0 {
return false;
return .[];
}

send_completions_decls(request, decls);

return true;
return get_completions_decls(decls);
}

send_completions_decls :: (request: LSP_Request_Message_Completion, decls: []*Declaration) {
get_completions_decls :: (decls: []*Declaration) -> []LSP_Completion_Item {
completions: [..]LSP_Completion_Item;
defer array_free(completions);

for decl: decls {
if !decl.expression && !decl.type_inst continue;
Expand Down Expand Up @@ -331,5 +310,5 @@ send_completions_decls :: (request: LSP_Request_Message_Completion, decls: []*De
});
}

lsp_respond(request.id, completions);
}
return completions;
}
10 changes: 8 additions & 2 deletions server/diagnostics.jai
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ run_diagnostics :: () {
defer array_free(command);

jai_exe_path := jai_exe_name;
if server.args.jai_path.count > 0 {
jai_exe_path = join(server.args.jai_path, "bin", jai_exe_name, separator="/",, temp);
if server.jai_path.count > 0 {
jai_exe_path = join(server.jai_path, "bin", jai_exe_name, separator="/",, temp);
}

array_add(*command, jai_exe_path);
Expand All @@ -54,11 +54,15 @@ run_diagnostics :: () {

reset_diagnostics();

log("diagnostics command: %", command);

result, _, error := run_command(..command, working_directory=server.project_root, capture_and_return_output=true, timeout_ms=2500);
if result.exit_code == 0 {
return;
}

log("error: %", error);

lines := split(error, "\n");
defer array_free(lines);

Expand Down Expand Up @@ -117,6 +121,8 @@ run_diagnostics :: () {

file = path_to_lsp_path(normalize_path(file,, temp)); // split_from_right and slice don't allocate memory so copy the file in case the string with compiler output is freed

log("sending %", diagnostics);

lsp_send(LSP_Client_Message(LSP_Publish_Diagnostics).{
method="textDocument/publishDiagnostics",
params = .{
Expand Down
Loading