aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2026-02-12 15:08:43 +1100
committerGitHub <noreply@github.com>2026-02-12 15:08:43 +1100
commit4f309f96acc53f788dabf7a9d0cb7319dbe16ebd (patch)
treee8ad7fd5fd209adca67d6f4a9304da44116f99a1 /src/server
parent92b8c767d233c6556ebf46072f32a02d06277363 (diff)
parentb32550a87edcbd71d1084eec76c316161066bb06 (diff)
Merge pull request #1295 from BradLewis/feat/update-os-filepath
Update ols to use the new os and filepath packages
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin2
-rw-r--r--src/server/build.odin60
-rw-r--r--src/server/caches.odin17
-rw-r--r--src/server/check.odin15
-rw-r--r--src/server/collector.odin6
-rw-r--r--src/server/completion.odin6
-rw-r--r--src/server/format.odin2
-rw-r--r--src/server/references.odin34
-rw-r--r--src/server/requests.odin38
-rw-r--r--src/server/workspace_symbols.odin40
10 files changed, 114 insertions, 106 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 024c2c3..1a85708 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -3409,7 +3409,7 @@ get_package_from_node :: proc(node: ast.Node) -> string {
}
get_package_from_filepath :: proc(file_path: string) -> string {
- slashed, _ := filepath.to_slash(file_path, context.temp_allocator)
+ slashed, _ := filepath.replace_path_separators(file_path, '/', context.temp_allocator)
ret := path.dir(slashed, context.temp_allocator)
return ret
}
diff --git a/src/server/build.odin b/src/server/build.odin
index 59dc63d..3f8b04f 100644
--- a/src/server/build.odin
+++ b/src/server/build.odin
@@ -2,6 +2,7 @@
package server
import "base:runtime"
+import "core:slice"
import "core:fmt"
import "core:log"
@@ -126,6 +127,24 @@ skip_file :: proc(filename: string) -> bool {
return false
}
+// Finds all packages under the provided path by walking the file system
+// and appends them to the provided dynamic array
+append_packages :: proc(
+ path: string,
+ pkgs: ^[dynamic]string,
+ allocator := context.temp_allocator,
+) {
+ w := os.walker_create(path)
+ for info in os.walker_walk(&w) {
+ if info.type != .Directory && filepath.ext(info.name) == ".odin" {
+ dir := filepath.dir(info.fullpath, allocator)
+ if !slice.contains(pkgs[:], dir) {
+ append(pkgs, dir)
+ }
+ }
+ }
+}
+
should_collect_file :: proc(file_tags: parser.File_Tags) -> bool {
if file_tags.ignore {
return false
@@ -165,8 +184,8 @@ try_build_package :: proc(pkg_name: string) {
matches, err := filepath.glob(fmt.tprintf("%v/*.odin", pkg_name), context.temp_allocator)
- if err != .None {
- log.errorf("Failed to glob %v for indexing package", pkg_name)
+ if err != nil && err != .Not_Exist {
+ log.errorf("Failed to glob %v for indexing package: %v", pkg_name, err)
return
}
@@ -182,10 +201,10 @@ try_build_package :: proc(pkg_name: string) {
continue
}
- data, ok := os.read_entire_file(fullpath, context.allocator)
+ data, err := os.read_entire_file(fullpath, context.allocator)
- if !ok {
- log.errorf("failed to read entire file for indexing %v", fullpath)
+ if err != nil {
+ log.errorf("failed to read entire file for indexing %v: %v", fullpath, err)
continue
}
@@ -212,10 +231,11 @@ try_build_package :: proc(pkg_name: string) {
pkg = pkg,
}
- ok = parser.parse_file(&p, &file)
+ ok := parser.parse_file(&p, &file)
if !ok {
- if !strings.contains(fullpath, "builtin.odin") && !strings.contains(fullpath, "intrinsics.odin") {
+ if !strings.contains(fullpath, "builtin.odin") &&
+ !strings.contains(fullpath, "intrinsics.odin") {
log.errorf("error in parse file for indexing %v", fullpath)
}
continue
@@ -229,9 +249,10 @@ try_build_package :: proc(pkg_name: string) {
}
}
- build_cache.loaded_pkgs[strings.clone(pkg_name, indexer.index.collection.allocator)] = PackageCacheInfo {
- timestamp = time.now(),
- }
+ build_cache.loaded_pkgs[strings.clone(pkg_name, indexer.index.collection.allocator)] =
+ PackageCacheInfo {
+ timestamp = time.now(),
+ }
}
@@ -273,10 +294,10 @@ index_file :: proc(uri: common.Uri, text: string) -> common.Error {
fullpath := uri.path
p := parser.Parser {
- err = log_error_handler,
- warn = log_warning_handler,
- flags = {.Optional_Semicolons},
- }
+ err = log_error_handler,
+ warn = log_warning_handler,
+ flags = {.Optional_Semicolons},
+ }
when ODIN_OS == .Windows {
correct := common.get_case_sensitive_path(fullpath, context.temp_allocator)
@@ -295,10 +316,10 @@ index_file :: proc(uri: common.Uri, text: string) -> common.Error {
}
file := ast.File {
- fullpath = fullpath,
- src = text,
- pkg = pkg,
- }
+ fullpath = fullpath,
+ src = text,
+ pkg = pkg,
+ }
{
allocator := context.allocator
@@ -308,7 +329,8 @@ index_file :: proc(uri: common.Uri, text: string) -> common.Error {
ok = parser.parse_file(&p, &file)
if !ok {
- if !strings.contains(fullpath, "builtin.odin") && !strings.contains(fullpath, "intrinsics.odin") {
+ if !strings.contains(fullpath, "builtin.odin") &&
+ !strings.contains(fullpath, "intrinsics.odin") {
log.errorf("error in parse file for indexing %v", fullpath)
}
}
diff --git a/src/server/caches.odin b/src/server/caches.odin
index ff7a422..519ce6c 100644
--- a/src/server/caches.odin
+++ b/src/server/caches.odin
@@ -76,26 +76,13 @@ clear_all_package_aliases :: proc() {
//Go through all the collections to find all the possible packages that exists
find_all_package_aliases :: proc() {
- walk_proc :: proc(info: os.File_Info, in_err: os.Errno, user_data: rawptr) -> (err: os.Errno, skip_dir: bool) {
- data := cast(^[dynamic]string)user_data
-
- if !info.is_dir && filepath.ext(info.name) == ".odin" {
- dir := filepath.dir(info.fullpath, context.temp_allocator)
- if !slice.contains(data[:], dir) {
- append(data, dir)
- }
- }
-
- return in_err, false
- }
-
for k, v in common.config.collections {
pkgs := make([dynamic]string, context.temp_allocator)
- filepath.walk(v, walk_proc, &pkgs)
+ append_packages(v, &pkgs, context.temp_allocator)
for pkg in pkgs {
if pkg, err := filepath.rel(v, pkg, context.temp_allocator); err == .None {
- forward_pkg, _ := filepath.to_slash(pkg, context.temp_allocator)
+ forward_pkg, _ := filepath.replace_path_separators(pkg, '/', context.temp_allocator)
if k not_in build_cache.pkg_aliases {
build_cache.pkg_aliases[k] = make([dynamic]string)
}
diff --git a/src/server/check.odin b/src/server/check.odin
index 78eb25f..1280b76 100644
--- a/src/server/check.odin
+++ b/src/server/check.odin
@@ -36,24 +36,11 @@ Json_Errors :: struct {
//If the user does not specify where to call odin check, it'll just find all directory with odin, and call them seperately.
fallback_find_odin_directories :: proc(config: ^common.Config) -> []string {
- walk_proc :: proc(info: os.File_Info, in_err: os.Errno, user_data: rawptr) -> (err: os.Errno, skip_dir: bool) {
- data := cast(^[dynamic]string)user_data
-
- if !info.is_dir && filepath.ext(info.name) == ".odin" {
- dir := filepath.dir(info.fullpath, context.temp_allocator)
- if !slice.contains(data[:], dir) {
- append(data, dir)
- }
- }
-
- return in_err, false
- }
-
data := make([dynamic]string, context.temp_allocator)
if len(config.workspace_folders) > 0 {
if uri, ok := common.parse_uri(config.workspace_folders[0].uri, context.temp_allocator); ok {
- filepath.walk(uri.path, walk_proc, &data)
+ append_packages(uri.path, &data, context.temp_allocator)
}
}
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 24fd0fa..0f85774 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -679,11 +679,11 @@ get_symbol_package_name :: proc(
}
if strings.contains(uri, "intrinsics.odin") {
- intrinsics_path := filepath.join(
+ intrinsics_path, _ := filepath.join(
elems = {common.config.collections["base"], "/intrinsics"},
allocator = context.temp_allocator,
)
- intrinsics_path, _ = filepath.to_slash(intrinsics_path, context.temp_allocator)
+ intrinsics_path, _ = filepath.replace_path_separators(intrinsics_path, '/', context.temp_allocator)
return get_index_unique_string(collection, intrinsics_path)
}
@@ -712,7 +712,7 @@ write_doc_string :: proc(sb: ^strings.Builder, doc: string) {
}
collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error {
- forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator)
+ forward, _ := filepath.replace_path_separators(file.fullpath, '/', context.temp_allocator)
directory := path.dir(forward, context.temp_allocator)
package_map := get_package_mapping(file, collection.config, directory)
exprs := collect_globals(file)
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 072d21b..31d75ca 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1878,7 +1878,7 @@ get_package_completion :: proc(
c := without_quotes[0:colon_index]
if colon_index + 1 < len(without_quotes) {
- absolute_path = filepath.join(
+ absolute_path, _ = filepath.join(
elems = {
config.collections[c],
filepath.dir(without_quotes[colon_index + 1:], context.temp_allocator),
@@ -1891,7 +1891,7 @@ get_package_completion :: proc(
} else {
import_file_dir := filepath.dir(position_context.import_stmt.pos.file, context.temp_allocator)
import_dir := filepath.dir(without_quotes, context.temp_allocator)
- absolute_path = filepath.join(elems = {import_file_dir, import_dir}, allocator = context.temp_allocator)
+ absolute_path, _ = filepath.join(elems = {import_file_dir, import_dir}, allocator = context.temp_allocator)
}
if !strings.contains(position_context.import_stmt.fullpath, "/") &&
@@ -1941,7 +1941,7 @@ search_for_packages :: proc(fullpath: string) -> []string {
if files, err := os.read_dir(fh, 0, context.temp_allocator); err == 0 {
for file in files {
- if file.is_dir {
+ if file.type == .Directory {
append(&packages, file.fullpath)
}
}
diff --git a/src/server/format.odin b/src/server/format.odin
index 9f30c49..6a95bed 100644
--- a/src/server/format.odin
+++ b/src/server/format.odin
@@ -5,8 +5,6 @@ import "src:common"
import "src:odin/format"
import "src:odin/printer"
-import "core:log"
-
FormattingOptions :: struct {
tabSize: uint,
insertSpaces: bool, //tabs or spaces
diff --git a/src/server/references.odin b/src/server/references.odin
index ee49c4e..6645289 100644
--- a/src/server/references.odin
+++ b/src/server/references.odin
@@ -16,10 +16,10 @@ import "src:common"
fullpaths: [dynamic]string
-walk_directories :: proc(info: os.File_Info, in_err: os.Errno, user_data: rawptr) -> (err: os.Error, skip_dir: bool) {
+walk_directories :: proc(info: os.File_Info, in_err: os.Error, user_data: rawptr) -> (err: os.Error, skip_dir: bool) {
document := cast(^Document)user_data
- if info.is_dir {
+ if info.type == .Directory {
return nil, false
}
@@ -28,7 +28,7 @@ walk_directories :: proc(info: os.File_Info, in_err: os.Errno, user_data: rawptr
}
if strings.contains(info.name, ".odin") {
- slash_path, _ := filepath.to_slash(info.fullpath, context.temp_allocator)
+ slash_path, _ := filepath.replace_path_separators(info.fullpath, '/', context.temp_allocator)
if slash_path != document.fullpath {
append(&fullpaths, strings.clone(info.fullpath, context.temp_allocator))
}
@@ -277,7 +277,23 @@ resolve_references :: proc(
when !ODIN_TEST {
for workspace in common.config.workspace_folders {
uri, _ := common.parse_uri(workspace.uri, context.temp_allocator)
- filepath.walk(uri.path, walk_directories, document)
+ w := os.walker_create(uri.path)
+ for info in os.walker_walk(&w) {
+ if info.type == .Directory {
+ continue
+ }
+
+ if info.fullpath == "" {
+ continue
+ }
+
+ if strings.contains(info.name, ".odin") {
+ slash_path, _ := filepath.replace_path_separators(info.fullpath, '/', context.temp_allocator)
+ if slash_path != document.fullpath {
+ append(&fullpaths, strings.clone(info.fullpath, context.temp_allocator))
+ }
+ }
+ }
}
}
@@ -297,12 +313,12 @@ resolve_references :: proc(
for fullpath in fullpaths {
dir := filepath.dir(fullpath)
base := filepath.base(dir)
- forward_dir, _ := filepath.to_slash(dir)
+ forward_dir, _ := filepath.replace_path_separators(dir, '/', context.allocator)
- data, ok := os.read_entire_file(fullpath, context.allocator)
+ data, err := os.read_entire_file(fullpath, context.allocator)
- if !ok {
- log.errorf("failed to read entire file for indexing %v", fullpath)
+ if err != nil {
+ log.errorf("failed to read entire file for indexing %v: %v", fullpath, err)
continue
}
@@ -328,7 +344,7 @@ resolve_references :: proc(
pkg = pkg,
}
- ok = parser.parse_file(&p, &file)
+ ok := parser.parse_file(&p, &file)
if !ok {
if !strings.contains(fullpath, "builtin.odin") && !strings.contains(fullpath, "intrinsics.odin") {
diff --git a/src/server/requests.odin b/src/server/requests.odin
index f24c59b..573c82d 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -472,7 +472,7 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
// Apply custom collections.
for it in ols_config.collections {
- forward_path, _ := filepath.to_slash(it.path, context.temp_allocator)
+ forward_path, _ := filepath.replace_path_separators(it.path, '/', context.temp_allocator)
forward_path = common.resolve_home_dir(forward_path, context.temp_allocator)
@@ -503,13 +503,14 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
}
}
- if abs_final_path, ok := filepath.abs(final_path); ok {
- slashed_path, _ := filepath.to_slash(abs_final_path, context.temp_allocator)
+ abs_final_path, err := filepath.abs(final_path, context.temp_allocator)
+ if err != nil {
+ log.errorf("Failed to find absolute address of collection: %v", final_path, err)
+ config.collections[strings.clone(it.name)] = strings.clone(final_path)
+ } else {
+ slashed_path, _ := filepath.replace_path_separators(abs_final_path, '/', context.temp_allocator)
config.collections[strings.clone(it.name)] = strings.clone(slashed_path)
- } else {
- log.errorf("Failed to find absolute address of collection: %v", final_path)
- config.collections[strings.clone(it.name)] = strings.clone(final_path)
}
}
@@ -553,7 +554,7 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
}
if odin_core_env != "" {
- if abs_core_env, ok := filepath.abs(odin_core_env, context.temp_allocator); ok {
+ if abs_core_env, err := filepath.abs(odin_core_env, context.temp_allocator); err == nil {
odin_core_env = abs_core_env
}
}
@@ -564,7 +565,7 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
// Insert the default collections if they are not specified in the config.
if odin_core_env != "" {
- forward_path, _ := filepath.to_slash(odin_core_env, context.temp_allocator)
+ forward_path, _ := filepath.replace_path_separators(odin_core_env, '/', context.temp_allocator)
// base
if "base" not_in config.collections {
@@ -662,17 +663,18 @@ request_initialize :: proc(
config.enable_auto_import = true
read_ols_config :: proc(file: string, config: ^common.Config, uri: common.Uri) {
- if data, ok := os.read_entire_file(file, context.temp_allocator); ok {
- ols_config: OlsConfig
+ data, err := os.read_entire_file(file, context.temp_allocator)
+ if err != nil {
+ log.warnf("Failed to read/find %v: %v", file, err)
+ return
+ }
+ ols_config: OlsConfig
- err := json.unmarshal(data, &ols_config, allocator = context.temp_allocator)
- if err == nil {
- read_ols_initialize_options(config, ols_config, uri)
- } else {
- log.errorf("Failed to unmarshal %v: %v", file, err)
- }
+ json_err := json.unmarshal(data, &ols_config, allocator = context.temp_allocator)
+ if json_err == nil {
+ read_ols_initialize_options(config, ols_config, uri)
} else {
- log.warnf("Failed to read/find %v", file)
+ log.errorf("Failed to unmarshal %v: %v", file, json_err)
}
}
@@ -1625,7 +1627,7 @@ notification_did_change_watched_files :: proc(
find_all_package_aliases()
} else {
if uri, ok := common.parse_uri(change.uri, context.temp_allocator); ok {
- if data, ok := os.read_entire_file(uri.path, context.temp_allocator); ok {
+ if data, err := os.read_entire_file(uri.path, context.temp_allocator); err == nil {
index_file(uri, cast(string)data)
}
}
diff --git a/src/server/workspace_symbols.odin b/src/server/workspace_symbols.odin
index 11e7a8a..b6f42c8 100644
--- a/src/server/workspace_symbols.odin
+++ b/src/server/workspace_symbols.odin
@@ -1,7 +1,6 @@
package server
import "core:fmt"
-import "core:log"
import "core:os"
import "core:path/filepath"
import "core:strings"
@@ -19,25 +18,6 @@ WorkspaceCache :: struct {
@(thread_local, private = "file")
cache: WorkspaceCache
-@(private)
-walk_dir :: proc(info: os.File_Info, in_err: os.Errno, user_data: rawptr) -> (err: os.Error, skip_dir: bool) {
- pkgs := cast(^[dynamic]string)user_data
-
- if info.is_dir {
- dir, _ := filepath.to_slash(info.fullpath, context.temp_allocator)
- dir_name := filepath.base(dir)
-
- for blacklist in dir_blacklist {
- if blacklist == dir_name {
- return nil, true
- }
- }
- append(pkgs, dir)
- }
-
- return nil, false
-}
-
get_workspace_symbols :: proc(query: string) -> (workspace_symbols: []WorkspaceSymbol, ok: bool) {
if time.since(cache.time) > 20 * time.Second {
for pkg in cache.pkgs {
@@ -48,7 +28,23 @@ get_workspace_symbols :: proc(query: string) -> (workspace_symbols: []WorkspaceS
uri := common.parse_uri(workspace.uri, context.temp_allocator) or_return
pkgs := make([dynamic]string, 0, context.temp_allocator)
- filepath.walk(uri.path, walk_dir, &pkgs)
+ w := os.walker_create(uri.path)
+ for info in os.walker_walk(&w) {
+ if info.type == .Directory {
+ dir := filepath.dir(info.fullpath, context.temp_allocator)
+ dir_name := filepath.base(dir)
+ found := false
+ for blacklist in dir_blacklist {
+ if blacklist == dir_name {
+ found = true
+ break
+ }
+ }
+ if !found {
+ append(&pkgs, dir)
+ }
+ }
+ }
_pkg: for pkg in pkgs {
matches, err := filepath.glob(fmt.tprintf("%v/*.odin", pkg), context.temp_allocator)
@@ -58,7 +54,7 @@ get_workspace_symbols :: proc(query: string) -> (workspace_symbols: []WorkspaceS
}
for exclude_path in common.config.profile.exclude_path {
- exclude_forward, _ := filepath.to_slash(exclude_path, context.temp_allocator)
+ exclude_forward, _ := filepath.replace_path_separators(exclude_path, '/', context.temp_allocator)
if exclude_forward[len(exclude_forward) - 2:] == "**" {
lower_pkg := strings.to_lower(pkg)