feat: implement relative import resolution with normalized paths and update all test modules

Replace the flat module name-to-path mapping with a proper relative import resolver that handles "./" and "../" prefixes relative to the importer's directory. This is a breaking change: existing imports in user code that assume paths are relative to the entrypoint file will now fail. Stack trace output and host API calls now use the resolved module string instead of the short import name. Update all test fixtures to use "./" relative imports and adjust C test files to pass the full resolved module path to wrenGetVariable.
This commit is contained in:
Bob Nystrom
2018-03-24 18:10:36 +00:00
parent c4532102e8
commit 80bb3ebad7
41 changed files with 152 additions and 107 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
void callRunTests(WrenVM* vm)
{
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "Call", 0);
wrenGetVariable(vm, "test/api/call", "Call", 0);
WrenHandle* callClass = wrenGetSlotHandle(vm, 0);
WrenHandle* noParams = wrenMakeCallHandle(vm, "noParams");
+5 -5
View File
@@ -4,23 +4,23 @@
static void beforeDefined(WrenVM* vm)
{
wrenGetVariable(vm, "main", "A", 0);
wrenGetVariable(vm, "test/api/get_variable", "A", 0);
}
static void afterDefined(WrenVM* vm)
{
wrenGetVariable(vm, "main", "A", 0);
wrenGetVariable(vm, "test/api/get_variable", "A", 0);
}
static void afterAssigned(WrenVM* vm)
{
wrenGetVariable(vm, "main", "A", 0);
wrenGetVariable(vm, "test/api/get_variable", "A", 0);
}
static void otherSlot(WrenVM* vm)
{
wrenEnsureSlots(vm, 3);
wrenGetVariable(vm, "main", "B", 2);
wrenGetVariable(vm, "test/api/get_variable", "B", 2);
// Move it into return position.
const char* string = wrenGetSlotString(vm, 2);
@@ -29,7 +29,7 @@ static void otherSlot(WrenVM* vm)
static void otherModule(WrenVM* vm)
{
wrenGetVariable(vm, "get_variable_module", "Variable", 0);
wrenGetVariable(vm, "test/api/get_variable_module", "Variable", 0);
}
WrenForeignMethodFn getVariableBindMethod(const char* signature)
+1 -1
View File
@@ -1,4 +1,4 @@
import "get_variable_module"
import "./get_variable_module"
class GetVariable {
foreign static beforeDefined()
+3 -3
View File
@@ -24,8 +24,8 @@ const char* testName;
static WrenForeignMethodFn bindForeignMethod(
WrenVM* vm, const char* module, const char* className,
bool isStatic, const char* signature)
{
if (strcmp(module, "main") != 0) return NULL;
{
if (strncmp(module, "test/", 5) != 0) return NULL;
// For convenience, concatenate all of the method qualifiers into a single
// signature string.
@@ -78,7 +78,7 @@ static WrenForeignClassMethods bindForeignClass(
WrenVM* vm, const char* module, const char* className)
{
WrenForeignClassMethods methods = { NULL, NULL };
if (strcmp(module, "main") != 0) return methods;
if (strncmp(module, "test/", 5) != 0) return methods;
foreignClassBindClass(className, &methods);
if (methods.allocate != NULL) return methods;
+2 -2
View File
@@ -6,7 +6,7 @@
void resetStackAfterCallAbortRunTests(WrenVM* vm)
{
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "Test", 0);
wrenGetVariable(vm, "test/api/reset_stack_after_call_abort", "Test", 0);
WrenHandle* testClass = wrenGetSlotHandle(vm, 0);
WrenHandle* abortFiber = wrenMakeCallHandle(vm, "abortFiber()");
@@ -25,4 +25,4 @@ void resetStackAfterCallAbortRunTests(WrenVM* vm)
wrenReleaseHandle(vm, testClass);
wrenReleaseHandle(vm, abortFiber);
wrenReleaseHandle(vm, afterConstruct);
}
}
@@ -22,7 +22,7 @@ void resetStackAfterForeignConstructBindClass(
void resetStackAfterForeignConstructRunTests(WrenVM* vm)
{
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "Test", 0);
wrenGetVariable(vm, "test/api/reset_stack_after_foreign_construct", "Test", 0);
WrenHandle* testClass = wrenGetSlotHandle(vm, 0);
WrenHandle* callConstruct = wrenMakeCallHandle(vm, "callConstruct()");
@@ -41,4 +41,4 @@ void resetStackAfterForeignConstructRunTests(WrenVM* vm)
wrenReleaseHandle(vm, testClass);
wrenReleaseHandle(vm, callConstruct);
wrenReleaseHandle(vm, afterConstruct);
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
var fiber = Fiber.new {
System.print("fiber 1")
import "yield_from_import_module"
import "./yield_from_import_module"
System.print("fiber 2")
}
+1 -1
View File
@@ -1,3 +1,3 @@
class Foo {
foreign someUnknownMethod // expect runtime error: Could not find foreign method 'someUnknownMethod' for class Foo in module 'main'.
foreign someUnknownMethod // expect runtime error: Could not find foreign method 'someUnknownMethod' for class Foo in module 'test/language/foreign/unknown_method'.
}
@@ -1,4 +1,4 @@
import "module" for Module, Other
import "./module" for Module, Other
System.print(Module) // expect: before
@@ -1,2 +1,2 @@
System.print("before") // expect: before
import "module" for Module // expect runtime error: Could not compile module 'module'.
import "./module" for Module // expect runtime error: Could not compile module 'test/language/module/compile_error/module'.
+1 -1
View File
@@ -3,7 +3,7 @@ System.print("start a")
var A = "a value"
System.print("a defined %(A)")
import "b" for B
import "./b" for B
System.print("a imported %(B)")
System.print("end a")
+1 -1
View File
@@ -3,7 +3,7 @@ System.print("start b")
var B = "b value"
System.print("b defined %(B)")
import "a" for A
import "./a" for A
System.print("b imported %(A)")
System.print("end b")
@@ -1,4 +1,4 @@
import "a"
import "./a"
// Shared module should only run once:
// expect: start a
@@ -1,4 +1,4 @@
import "module"
import "./module"
// expect: Bool
// expect: Class
// expect: Fiber
@@ -1,7 +1,7 @@
var Module = "outer"
if (true) {
import "module" for Module
import "./module" for Module
// expect: ran module
System.print(Module) // expect: from module
+1 -1
View File
@@ -1 +1 @@
import "module" NoString // expect error
import "./module" NoString // expect error
@@ -1,3 +1,3 @@
import "something" for Index
import "./something/module" for Index
System.print(Index) // expect: index
@@ -1,4 +1,4 @@
import "module" for Module1, Module2, Module3, Module4, Module5
import "./module" for Module1, Module2, Module3, Module4, Module5
// Only execute module body once:
// expect: ran module
+1 -1
View File
@@ -1,2 +1,2 @@
var Collides
import "module" for Collides // expect error
import "./module" for Collides // expect error
+2 -2
View File
@@ -1,9 +1,9 @@
import
"module"
"./module"
import "module" for
import "./module" for
A,
@@ -1,2 +1,2 @@
import "module"
import "./module"
// expect: ran module
@@ -0,0 +1,2 @@
// nontest
System.print("module_3")
@@ -0,0 +1,8 @@
import "./sub/module"
import "./sub/././///dir/module"
// expect: sub/module
// expect: sub/module_2
// expect: sub/dir/module
// expect: sub/dir/module_2
// expect: sub/module_3
// expect: module_3
@@ -0,0 +1,3 @@
// nontest
System.print("sub/dir/module")
import "./module_2"
@@ -0,0 +1,4 @@
// nontest
System.print("sub/dir/module_2")
import "../module_3"
import "../../module_3"
@@ -0,0 +1,3 @@
// nontest
System.print("sub/module")
import "./module_2"
@@ -0,0 +1,2 @@
// nontest
System.print("sub/module_2")
@@ -0,0 +1,2 @@
// nontest
System.print("sub/module_3")
+1 -1
View File
@@ -1,5 +1,5 @@
// nontest
System.print("a")
import "shared" for Shared
import "./shared" for Shared
var A = "a %(Shared)"
System.print("a done")
+1 -1
View File
@@ -1,5 +1,5 @@
// nontest
System.print("b")
import "shared" for Shared
import "./shared" for Shared
var B = "b %(Shared)"
System.print("b done")
@@ -1,5 +1,5 @@
import "a" for A
import "b" for B
import "./a" for A
import "./b" for B
// Shared module should only run once:
// expect: a
@@ -1,4 +1,4 @@
import "module" for Module
import "./module" for Module
// expect: ran module
System.print(Module) // expect: from module
+1 -1
View File
@@ -1 +1 @@
import "does_not_exist" for DoesNotExist // expect runtime error: Could not load module 'does_not_exist'.
import "./does_not_exist" for DoesNotExist // expect runtime error: Could not load module 'test/language/module/does_not_exist'.
@@ -1,3 +1,3 @@
// Should execute the module:
// expect: ran module
import "module" for DoesNotExist // expect runtime error: Could not find a variable named 'DoesNotExist' in module 'module'.
import "./module" for DoesNotExist // expect runtime error: Could not find a variable named 'DoesNotExist' in module 'test/language/module/unknown_variable/module'.
+1 -1
View File
@@ -1,6 +1,6 @@
import "meta" for Meta
var variables = Meta.getModuleVariables("main")
var variables = Meta.getModuleVariables("test/meta/get_module_variables")
// Includes implicitly imported core stuff.
System.print(variables.contains("Object")) // expect: true