Skip to content

Commit

Permalink
Separate global and workspace caches (#42)
Browse files Browse the repository at this point in the history
Also use `FilePath` throughout for paths.

Fixes #39
  • Loading branch information
chalcolith authored Nov 27, 2024
1 parent 2e27ec7 commit b593340
Show file tree
Hide file tree
Showing 24 changed files with 2,268 additions and 1,985 deletions.
4 changes: 4 additions & 0 deletions corral.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"eohippus"
],
"deps": [
{
"locator": "github.com/ponylang/appdirs.git",
"version": "0.1.5"
},
{
"locator": "github.com/chalcolith/kiuatan.git",
"version": "1.5.2"
Expand Down
104 changes: 81 additions & 23 deletions eohippus-cli/main.pony
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use "appdirs"
use "files"
use "logger"

Expand All @@ -9,8 +10,6 @@ use server = "../eohippus/server"
actor Main
let _env: Env
let _auth: FileAuth
let _context: parser.Context
let _grammar: parser.NamedRule val

new create(env: Env) =>
_env = env
Expand All @@ -31,11 +30,9 @@ actor Main
server.EohippusLogFormatter)
end

_context = parser.Context([])
_grammar = parser.Builder(_context).src_file.src_file

let pony_path = server.ServerUtils.get_pony_path(env)
let ponyc = server.ServerUtils.find_ponyc(env)
let parser_context = parser.Context([])
let parser_grammar: parser.NamedRule val =
parser.Builder(parser_context).src_file.src_file

let workspace_dir =
try
Expand All @@ -45,24 +42,85 @@ actor Main
end

let workspace_path = FilePath(_auth, workspace_dir)
env.err.print("workspace_path: " + workspace_path.path)

let workspace_cache = FilePath(
_auth, Path.join(workspace_path.path, ".eohippus"))
if not _check_cache(workspace_cache, "workspace cache") then
return
end
env.err.print("workspace_cache: " + workspace_cache.path)

let appdirs = AppDirs(env.vars, "eohippus")
let global_cache =
try
FilePath(_auth, appdirs.user_cache_dir()?)
else
env.err.print("unable to get user cache dir")
return
end
if not _check_cache(global_cache, "global_cache") then
return
end
env.err.print("global_cache: " + global_cache.path)

env.err.print("workspace_path " + workspace_path.path)
let pony_path_dirs = server.ServerUtils.get_pony_path_dirs(env)
env.err.print("pony_path_dirs:")
for path in pony_path_dirs.values() do
env.err.print(" " + path.path)
end

analyzer.EohippusAnalyzer(
logger,
_auth,
_grammar,
let ponyc = server.ServerUtils.find_ponyc(env)
match ponyc
| let ponyc_path: FilePath =>
env.err.print("ponyc_path: " + ponyc_path.path)
else
env.err.print("ponyc_path: None")
end

let pony_packages = server.ServerUtils.find_pony_packages(env, ponyc)
match pony_packages
| let pony_packages_path: FilePath =>
env.err.print("pony_packages_path: " + pony_packages_path.path)
else
env.err.print("pony_packages_path: None")
end

let analyzer_context = analyzer.AnalyzerContext(
FileAuth(env.root),
workspace_path,
None,
pony_path,
workspace_cache,
global_cache,
pony_path_dirs,
ponyc,
None,
this)
pony_packages,
parser_grammar)

let analyze = analyzer.EohippusAnalyzer(logger, analyzer_context, this)
analyze.analyze()

fun _check_cache(path: FilePath, name: String): Bool =>
try
if (not path.exists()) and (not path.mkdir()) then
_env.err.print(
"unable to create " + name + ": " + path.path)
return false
end
let info = FileInfo(path)?
if not info.directory then
_env.err.print(name + " is not a directory: " + path.path)
return false
end
else
_env.err.print("unable to access " + name + ": " + path.path)
return false
end
true

be parsed_file(
analyze: analyzer.Analyzer,
task_id: USize,
canonical_name: String,
canonical_name: FilePath,
syntax_tree: ast.Node,
line_beginnings: ReadSeq[parser.Loc] val)
=>
Expand All @@ -81,7 +139,7 @@ actor Main
be analyzed_file(
analyze: analyzer.Analyzer,
task_id: USize,
canonical_path: String,
canonical_path: FilePath,
syntax_tree: (ast.Node | None),
file_scope: (analyzer.Scope val | None),
parse_errors: ReadSeq[analyzer.AnalyzerError] val,
Expand All @@ -95,19 +153,19 @@ actor Main
be analyze_failed(
analyze: analyzer.Analyzer,
task_id: USize,
canonical_path: String,
canonical_path: FilePath,
errors: ReadSeq[analyzer.AnalyzerError] val)
=>
print_errors(errors, canonical_path)

fun print_errors(
errors: ReadSeq[analyzer.AnalyzerError] val,
path: (String | None))
path: (FilePath | None))
=>
for e in errors.values() do
match path
| let path': String =>
if e.canonical_path != path' then
| let path': FilePath =>
if e.canonical_path.path != path'.path then
continue
end
end
Expand All @@ -124,6 +182,6 @@ actor Main
"HINT"
end
_env.err.print(
e.canonical_path + ":" + (e.line + 1).string() + ":" +
e.canonical_path.path + ":" + (e.line + 1).string() + ":" +
(e.column + 1).string() + ": " + kind + ": " + e.message)
end
11 changes: 10 additions & 1 deletion eohippus-lsp/main.pony
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use "files"
use "logger"
use "net"

Expand Down Expand Up @@ -34,7 +35,15 @@ actor Main
Error, env.err, {(s: String): String => s }, ls.EohippusLogFormatter)
end

let config = recover val ls.ServerConfig(options.ponyc_executable) end
let config =
recover val
let ponyc_path =
match options.ponyc_executable
| let path_str: String =>
FilePath(FileAuth(env.root), path_str)
end
ls.ServerConfig(ponyc_path)
end

match options.command
| StdioCommand =>
Expand Down
147 changes: 147 additions & 0 deletions eohippus-vscode/test_folder/builtin_test/ini.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"""
# Ini package
The Ini package provides support for parsing
[INI file](https://en.wikipedia.org/wiki/INI_file) formatted text.
* Currently _does not_ support multi-line entries.
* Any keys not in a section will be placed in the section ""
# Example code
```pony
// Parses the file 'example.ini' in the current working directory
// Output all the content
use "ini"
use "files"
actor Main
new create(env:Env) =>
try
let ini_file = File(FilePath(FileAuth(env.root), "example.ini"))
let sections = IniParse(ini_file.lines())?
for section in sections.keys() do
env.out.print("Section name is: " + section)
for key in sections(section)?.keys() do
env.out.print(key + " = " + sections(section)?(key)?)
end
end
end
```
"""
primitive IniIncompleteSection
primitive IniNoDelimiter

type IniError is
( IniIncompleteSection
| IniNoDelimiter
)

interface IniNotify
"""
Notifications for INI parsing.
"""
fun ref apply(section: String, key: String, value: String): Bool
"""
This is called for every valid entry in the INI file. If key/value pairs
occur before a section name, the section can be an empty string. Return
false to halt processing.
"""

fun ref add_section(section: String): Bool =>
"""
This is called for every valid section in the INI file. Return false
to halt processing.
"""
true

fun ref errors(line: USize, err: IniError): Bool =>
"""
This is called for each error encountered. Return false to halt processing.
"""
true

primitive Ini
"""
A streaming parser for INI formatted lines of test.
"""
fun apply(lines: Iterator[String box], f: IniNotify): Bool =>
"""
This accepts a string iterator and calls the IniNotify for each new entry.
If any errors are encountered, this will return false. Otherwise, it
returns true.
"""
var section = ""
var lineno = USize(0)
var ok = true

for line in lines do
lineno = lineno + 1
var current = line.clone()
current.strip()

if current.size() == 0 then
continue
end

try
match current(0)?
| ';' | '#' =>
// Skip comments.
continue
| '[' =>
try
current.delete(current.find("]", 1)?, -1)
current.delete(0)
section = consume current
if not f.add_section(section) then
return ok
end
else
ok = false

if not f.errors(lineno, IniIncompleteSection) then
return false
end
end
else
try
let delim = try
current.find("=")?
else
current.find(":")?
end

let value = current.substring(delim + 1)
value.strip()

current.delete(delim, -1)
current.strip()

try
let comment = try
value.find(";")?
else
value.find("#")?
end

match value(comment.usize() - 1)?
| ' ' | '\t' =>
value.delete(comment, -1)
value.rstrip()
end
end

if not f(section, consume current, consume value) then
return ok
end
else
ok = false

if not f.errors(lineno, IniNoDelimiter) then
return false
end
end
end
end
end
ok
Loading

0 comments on commit b593340

Please sign in to comment.