Comments (6)
Could you please add a tiny illustration with the layout of where all these files are on your file system or provide a sample Git project that reproduces the issue? Nevermind I see now that I'm looking closely.
from wren-cli.
FYI: This is because the file imports are resolved one at a time and the path resolution of a parent file doesn't have any effects on the path resolution of files it loads. It only looks at the module name.
IE, with import "foo"
the search folder is wren_module/ (so it's looking for bar there). As soon as you change it to foo/foo
then the search folder changes to wren_module/foo
and bar can be located.
Definitely confusing.
This is tricky because both loadModuleFn
and resolveModuleFn
only take the name of the importer module (foo
in your case)... they have no idea the path that it was finally resolved to. So to fix this without changing that API the resolver would need to try all path variants of both the importer and the imported module. IE, search (in no particular order):
- foo/bar.wren
- foo/foo/bar.wren
- for/bar/bar.wren
- for/foo/bar/bar.wren
This will of course have implications for #78 as well.
from wren-cli.
I'd be happy to take this one if we could agree that the resolver code itself could be written in Wren (not C). I have a test branch already (for native-libraries) where I've done this and it's pretty minimal. I just created a tiny second VM with a single (synchronous) C foreign
function that is able to check for the existence of files. No code is loaded into this VM other than the ModuleResolver code (any tiny helpers) - no event loop is necessary, no Fibers involved.
If so it'd be pretty easy for the resolver to resolve this recursively. So when asked to resolve foo imports bar
it could re-resolve foo
and then use that information to search for bar... that may not be strictly needed, but it wouldn't be difficult.
IE just for an idea:
class Module {
construct new(importer, module, home) {
_importer = importer
_module = module
_home = home
}
static resolve(importer, module, home) {
var res = Module.new(importer, module, home)
return res.rootResolver ||
res.relativeResolver ||
res.wrenHomeResolver ||
res.standardResolver
}
rootResolver {
if (_module.startsWith("/")) return module
}
relativeResolver { // ... }
standardResolver { // ... }
wrenHomeResolver {
var locations = [
Path.join([_home,".wren/lib",_module + ".wren"]),
Path.join([_home,".wren",_module + ".wren"])
]
for (x in locations) {
if (File.existsSync(x)) return x
}
}
}
Then of course we could have test cases (also in Wren) to make sure the resolver behavior is fully tested. It probably needs to know the base/cwd directory also, but I was only working on HOME/.wren
stuff at time. Anyways I think it's enough to get the idea.
from wren-cli.
Ok, this is harder than it sounds because you need to change both the resolver and the loader to be smarter. I may have been conflating/mixing them a bit before. The resolver can't instruct the loader properly unless it knows whether you mean foo.wren
the file or foo/
(ie, foo/foo.wren
the library). It's exactly behavior is to strip the importee to it's nearest directory, then append the imported module so:
foo
=>././bar
foo/foo
=>foo/./bar
We should also possibly consider changing the import CLI requirements themself to remove the ambiguity. IE, requiring people to be explicit. IE, make foo/foo
the only way it works. Imports should always point to files, not folders. So no more:
// // If the module is a single bare name, treat it as a module with the same
// // name inside the package. So "foo" means "foo/foo".
// if (strchr(module, '/') == NULL) pathJoin(filePath, module);
import "foo/foo" for Foo // loads Foo
import "foo" // Could not load module 'foo'.
from wren-cli.
If foo/foo
is ugly we could also consider:
import "foo/" for Foo // loads Foo from foo/foo
No repeating, AND explicit. Or introduce a new syntax that has this same meaning "I am specifying a library folder, not a file".
from wren-cli.
I assume you're hacking the CLI though since this stuff doesn't work out of the box?
// TODO: This isn't currently used, but probably will be when package imports
// are supported. If not then, then delete this.
static char* rootDirectory = NULL;
static Path* wrenModulesDirectory = NULL;
from wren-cli.
Related Issues (20)
- Question: Debug or non-debug build for serious shell scripting? HOT 5
- Proposal: Modify and retrieve the local environment variables HOT 7
- Proposal: `File.basename` and `File.dirname`
- RFC: Consider using an actual Wren testing library
- Document auto-generation? Moving docs from `wren` to `wren-cli`? HOT 3
- What is the correct behavior of `Stdin.readLine`? HOT 1
- What is the correct behavior of `Stdin.readByte`?
- What is correct behavior of `Stdin.readCodepoint`?
- continue HOT 12
- ER: import from a specified location HOT 6
- [BUG] "Unhandled key-code [dec]: 8" on Backspace HOT 5
- Meta module only load in REPL HOT 1
- libuv is a problem HOT 11
- Failed to build: Error: conflicting types for โwriteโ; have โvoid(WrenVM *, const char *)โ HOT 5
- ANSI Color for gray comes up black on MacOS terminal HOT 3
- Add a dynamic link build with wren and libuv
- Does not build on FreeBSD HOT 1
- .
- Absolut import does not work. HOT 4
- Minour she bang issue (#! /bin/path/to/wrenc) not working properly
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wren-cli.