diff options
Diffstat (limited to 'xmake/core/base/interpreter.lua')
| -rw-r--r-- | xmake/core/base/interpreter.lua | 95 |
1 files changed, 39 insertions, 56 deletions
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index 01b689fe6..8dc0e4880 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -30,7 +30,6 @@ local string = require("base/string") local hashset = require("base/hashset") local scopeinfo = require("base/scopeinfo") local deprecated = require("base/deprecated") -local addon = require("package/addon") local sandbox = require("sandbox/sandbox") -- the rules to reword the raw lua error messages into friendly ones, {pattern, replacement} @@ -880,40 +879,37 @@ function interpreter:scriptdir() return path.directory(self._PRIVATE._CURFILE) end --- set root scope kind --- --- the root api will affect these scopes +-- add a resolver for the references of includes(), e.g. includes("@addon/esp32/check") -- --- get the root file name of the included directories, e.g. includes("subdir") -> subdir/xmake.lua -function interpreter:includes_rootfilename() - return self._PRIVATE._INCLUDES_ROOTFILENAME or "xmake.lua" -end - --- set the root file name of the included directories +-- @param resolver function (interp, reference), it returns the files, or nil and errors -- --- e.g. interp:includes_rootfilename_set("xmake-addons.lua") -> includes("subdir") -> subdir/xmake-addons.lua +-- @note the interpreter knows nothing about the references, the callers register the +-- resolvers which they support, e.g. @see project._interpreter() -- -function interpreter:includes_rootfilename_set(filename) - self._PRIVATE._INCLUDES_ROOTFILENAME = filename +function interpreter:includes_resolver_add(resolver) + local resolvers = self._PRIVATE._INCLUDES_RESOLVERS or {} + table.insert(resolvers, resolver) + self._PRIVATE._INCLUDES_RESOLVERS = resolvers end --- can we include the referenced files? e.g. includes("@builtin/check"), includes("@addon/esp32/board") -function interpreter:includes_references() - return self._PRIVATE._INCLUDES_REFERENCES ~= false +-- do we ignore the unresolvable references of includes()? e.g. includes("@addon/esp32/board") +function interpreter:includes_unresolved() + return self._PRIVATE._INCLUDES_UNRESOLVED end --- enable/disable the referenced files of includes() --- --- @param enabled enable them or not --- @param hint the extra hint of the error message +-- ignore the unresolvable references of includes() instead of raising errors -- --- @note the addons file is loaded before the addons are installed, so it cannot reference them +-- @note the project file may reference the resources which have not been installed yet, +-- so the caller can load it, install them and load it again, @see project._load() -- -function interpreter:includes_references_set(enabled, hint) - self._PRIVATE._INCLUDES_REFERENCES = enabled - self._PRIVATE._INCLUDES_REFERENCES_HINT = hint +function interpreter:includes_unresolved_set(enabled) + self._PRIVATE._INCLUDES_UNRESOLVED = enabled end +-- set root scope kind +-- +-- the root api will affect these scopes +-- function interpreter:rootscope_set(scope_kind) assert(self and self._PRIVATE) self._PRIVATE._ROOTSCOPE = scope_kind @@ -1826,26 +1822,6 @@ function interpreter:_find_builtin_includes(subpath) return os.files(path.join(os.programdir(), "includes", builtin_path, "xmake.lua")) end --- find the include files of the addons, e.g. includes("@addon/esp32/check"), includes("@self/check") -function interpreter:_find_addon_includes(subpath) - local referenceinfo, errors = addon.resolve_reference(subpath, "/", "includes", {scriptdir = self:scriptdir()}) - if not referenceinfo then - os.raise(errors) - end - local addon_path = referenceinfo.name - local files - if addon_path:endswith(".lua") then - files = os.files(path.join(referenceinfo.dir, addon_path)) - else - files = os.files(path.join(referenceinfo.dir, addon_path, "xmake.lua")) - end - -- the addon is installed, but it does not provide this file, we cannot ignore it - if not files or #files == 0 then - os.raise("includes(%s) not found!", subpath) - end - return files -end - function interpreter:api_builtin_includes(...) assert(self and self._PRIVATE and self._PRIVATE._ROOTDIR and self._PRIVATE._MTIMES) local curfile = self._PRIVATE._CURFILE @@ -1856,12 +1832,6 @@ function interpreter:api_builtin_includes(...) local subpaths_matched = {} for _, subpath in ipairs(subpaths) do local found = false - -- the referenced files are not always available, e.g. the addons file - if subpath:startswith("@") and not self:includes_references() then - local hint = self._PRIVATE._INCLUDES_REFERENCES_HINT - os.raise("includes(%s): the referenced files are not supported in %s!%s", - subpath, path.filename(curfile), hint and ("\n" .. hint) or "") - end -- attempt to find files from programdir/includes/*.lua -- e.g. includes("@builtin/check") if subpath:startswith("@builtin/") then @@ -1871,11 +1841,24 @@ function interpreter:api_builtin_includes(...) found = true end end - -- attempt to find files from the includes of the addons - -- e.g. includes("@addon/esp32/check"), includes("@self/check") - if not found and addon.is_reference(subpath, "/") then - table.join2(subpaths_matched, self:_find_addon_includes(subpath)) - found = true + -- attempt to find files from the registered resolvers of the references + -- e.g. includes("@addon/esp32/check"), @see interpreter:includes_resolver_add() + if not found and subpath:startswith("@") then + for _, resolver in ipairs(self._PRIVATE._INCLUDES_RESOLVERS or {}) do + local files, errors = resolver(self, subpath) + if files then + table.join2(subpaths_matched, files) + found = true + break + elseif errors then + -- it has not been resolved yet? the caller may load this file again + if self:includes_unresolved() then + found = true + break + end + os.raise(errors) + end + end end -- find the given files from the project directory if not found then @@ -1884,7 +1867,7 @@ function interpreter:api_builtin_includes(...) files = os.files(subpath) else -- @see https://github.com/xmake-io/xmake/issues/6026 - files = os.files(path.join(subpath, self:includes_rootfilename())) + files = os.files(path.join(subpath, "xmake.lua")) end if files and #files > 0 then table.join2(subpaths_matched, files) |
