diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index 1d8990f..0183041 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -174,6 +174,8 @@ import std.algorithm : remove, sort; import std.range : repeat; + auto roottarget = &targets[rootPackage.name]; + // 0. do shallow configuration (not including dependencies) of all packages TargetType determineTargetType(const ref TargetInfo ti) { @@ -234,7 +236,7 @@ // add main source files to root executable { - auto bs = &targets[rootPackage.name].buildSettings; + auto bs = &roottarget.buildSettings; if (bs.targetType == TargetType.executable) bs.addSourceFiles(mainSourceFiles); } @@ -302,7 +304,7 @@ "Package with target type \"none\" must have dependencies to build."); } - collectDependencies(rootPackage, targets[rootPackage.name], targets); + collectDependencies(rootPackage, *roottarget, targets); static if (__VERSION__ > 2070) visited.clear(); else @@ -322,7 +324,7 @@ } } - configureDependencies(targets[rootPackage.name], targets); + configureDependencies(*roottarget, targets); // 2. add Have_dependency_xyz for all direct dependencies of a target // (includes incorporated non-target dependencies and their dependencies) @@ -357,7 +359,7 @@ } } - configureDependents(targets[rootPackage.name], targets); + configureDependents(*roottarget, targets); static if (__VERSION__ > 2070) visited.clear(); else @@ -383,36 +385,55 @@ } // 5. override string import files in dependencies - static void overrideStringImports(ref TargetInfo ti, TargetInfo[string] targets, string[] overrides) + static void overrideStringImports(ref TargetInfo target, + ref TargetInfo parent, TargetInfo[string] targets, string[] overrides) { + // Since string import paths are inherited from dependencies in the + // inheritance step above (step 3), it is guaranteed that all + // following dependencies will not have string import paths either, + // so we can skip the recursion here + if (!target.buildSettings.stringImportPaths.length) + return; + // do not use visited here as string imports can be overridden by *any* parent // // special support for overriding string imports in parent packages // this is a candidate for deprecation, once an alternative approach // has been found - if (ti.buildSettings.stringImportPaths.length) { - // override string import files (used for up to date checking) - foreach (ref f; ti.buildSettings.stringImportFiles) + bool any_override = false; + + // override string import files (used for up to date checking) + foreach (ref f; target.buildSettings.stringImportFiles) + { + foreach (o; overrides) { - foreach (o; overrides) - { - NativePath op; - if (f != o && NativePath(f).head == (op = NativePath(o)).head) { - logDebug("string import %s overridden by %s", f, o); - f = o; - ti.buildSettings.prependStringImportPaths(op.parentPath.toNativeString); - } + NativePath op; + if (f != o && NativePath(f).head == (op = NativePath(o)).head) { + logDebug("string import %s overridden by %s", f, o); + f = o; + any_override = true; } } } - // add to overrides for recursion - overrides ~= ti.buildSettings.stringImportFiles; - // override dependencies - foreach (depname; ti.dependencies) - overrideStringImports(targets[depname], targets, overrides); + + // override string import paths by prepending to the list, in + // case there is any overlapping file + if (any_override) + target.buildSettings.prependStringImportPaths(parent.buildSettings.stringImportPaths); + + // add all files to overrides for recursion + overrides ~= target.buildSettings.stringImportFiles; + + // recursively override all dependencies with the accumulated files/paths + foreach (depname; target.dependencies) + overrideStringImports(targets[depname], target, targets, overrides); } - overrideStringImports(targets[rootPackage.name], targets, null); + // push string import paths/files down to all direct and indirect + // dependencies, overriding their own + foreach (depname; roottarget.dependencies) + overrideStringImports(targets[depname], *roottarget, targets, + roottarget.buildSettings.stringImportFiles); // remove targets without output foreach (name; targets.keys) diff --git a/test/issue1788-incomplete-string-import-override/b/dub.sdl b/test/issue1788-incomplete-string-import-override/b/dub.sdl new file mode 100644 index 0000000..ad65ed5 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/b/dub.sdl @@ -0,0 +1 @@ +name "b" diff --git a/test/issue1788-incomplete-string-import-override/b/source/b/foo.d b/test/issue1788-incomplete-string-import-override/b/source/b/foo.d new file mode 100644 index 0000000..e63ab6d --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/b/source/b/foo.d @@ -0,0 +1,9 @@ +module b.foo; + +string bar() +{ + static immutable l = import("layout.diet"); + pragma(msg, l); + static assert(l == "fancylayout.diet"); + return import(l); +} diff --git a/test/issue1788-incomplete-string-import-override/b/views/layout.diet b/test/issue1788-incomplete-string-import-override/b/views/layout.diet new file mode 100644 index 0000000..9d82715 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/b/views/layout.diet @@ -0,0 +1 @@ +not fancy \ No newline at end of file diff --git a/test/issue1788-incomplete-string-import-override/c/dub.sdl b/test/issue1788-incomplete-string-import-override/c/dub.sdl new file mode 100644 index 0000000..1ed791a --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/c/dub.sdl @@ -0,0 +1 @@ +name "c" diff --git a/test/issue1788-incomplete-string-import-override/c/source/dummy.d b/test/issue1788-incomplete-string-import-override/c/source/dummy.d new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/c/source/dummy.d diff --git a/test/issue1788-incomplete-string-import-override/c/views/fancylayout.diet b/test/issue1788-incomplete-string-import-override/c/views/fancylayout.diet new file mode 100644 index 0000000..e0e439d --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/c/views/fancylayout.diet @@ -0,0 +1 @@ +fancy \ No newline at end of file diff --git a/test/issue1788-incomplete-string-import-override/dub.sdl b/test/issue1788-incomplete-string-import-override/dub.sdl new file mode 100644 index 0000000..4199971 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/dub.sdl @@ -0,0 +1,4 @@ +name "a" + +dependency "b" path="b" +dependency "c" path="c" diff --git a/test/issue1788-incomplete-string-import-override/source/app.d b/test/issue1788-incomplete-string-import-override/source/app.d new file mode 100644 index 0000000..e9672cc --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/source/app.d @@ -0,0 +1,7 @@ +import b.foo; + +void main() +{ + static assert(import("layout.diet") == "fancylayout.diet"); + assert(bar() == "fancy"); +} diff --git a/test/issue1788-incomplete-string-import-override/views/layout.diet b/test/issue1788-incomplete-string-import-override/views/layout.diet new file mode 100644 index 0000000..0762db7 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/views/layout.diet @@ -0,0 +1 @@ +fancylayout.diet \ No newline at end of file