Allow querying values without combining values from parent configs.

This commit is contained in:
Tom van Dijck 2015-08-24 08:44:09 -07:00
parent 1de083849a
commit 3afc21546f
2 changed files with 88 additions and 56 deletions

View File

@ -63,23 +63,31 @@
-- the context filtering case-insensitive. -- the context filtering case-insensitive.
-- @param ctx -- @param ctx
-- The context that will be used for detoken.expand -- The context that will be used for detoken.expand
-- @param origin
-- The originating configset if set.
-- @return -- @return
-- The requested value. -- The requested value.
--- ---
function configset.fetch(cset, field, filter, ctx) function configset.fetch(cset, field, filter, ctx, origin)
filter = filter or {} filter = filter or {}
ctx = ctx or {} ctx = ctx or {}
if p.field.merges(field) then if p.field.merges(field) then
return configset._fetchMerged(cset, field, filter, ctx) return configset._fetchMerged(cset, field, filter, ctx, origin)
else else
return configset._fetchDirect(cset, field, filter, ctx) return configset._fetchDirect(cset, field, filter, ctx, origin)
end end
end end
function configset._fetchDirect(cset, field, filter, ctx) function configset._fetchDirect(cset, field, filter, ctx, origin)
-- If the originating configset hasn't been compiled, then the value will still
-- be on that configset.
if origin and origin ~= cset and not origin.compiled then
return configset._fetchDirect(origin, field, filter, ctx, origin)
end
local abspath = filter.files local abspath = filter.files
local basedir local basedir
@ -88,40 +96,48 @@
local n = #blocks local n = #blocks
for i = n, 1, -1 do for i = n, 1, -1 do
local block = blocks[i] local block = blocks[i]
local value = block[key]
-- If the filter contains a file path, make it relative to if not origin or block._origin == origin then
-- this block's basedir local value = block[key]
if value ~= nil and abspath and not cset.compiled and block._basedir and block._basedir ~= basedir then
basedir = block._basedir
filter.files = path.getrelative(basedir, abspath)
end
if value ~= nil and (cset.compiled or criteria.matches(block._criteria, filter)) then -- If the filter contains a file path, make it relative to
-- If value is an object, return a copy of it so that any -- this block's basedir
-- changes later made to it by the caller won't alter the if value ~= nil and abspath and not cset.compiled and block._basedir and block._basedir ~= basedir then
-- original value (that was a tough bug to find) basedir = block._basedir
if type(value) == "table" then filter.files = path.getrelative(basedir, abspath)
value = table.deepcopy(value)
end
-- Detoken
if field.tokens and ctx.environ then
value = p.detoken.expand(value, ctx.environ, field, ctx._basedir)
end end
return value if value ~= nil and (cset.compiled or criteria.matches(block._criteria, filter)) then
-- If value is an object, return a copy of it so that any
-- changes later made to it by the caller won't alter the
-- original value (that was a tough bug to find)
if type(value) == "table" then
value = table.deepcopy(value)
end
-- Detoken
if field.tokens and ctx.environ then
value = p.detoken.expand(value, ctx.environ, field, ctx._basedir)
end
return value
end
end end
end end
filter.files = abspath filter.files = abspath
if cset.parent then if cset.parent then
return configset._fetchDirect(cset.parent, field, filter, ctx) return configset._fetchDirect(cset.parent, field, filter, ctx, origin)
end end
end end
function configset._fetchMerged(cset, field, filter, ctx) function configset._fetchMerged(cset, field, filter, ctx, origin)
-- If the originating configset hasn't been compiled, then the value will still
-- be on that configset.
if origin and origin ~= cset and not origin.compiled then
return configset._fetchMerged(origin, field, filter, ctx, origin)
end
local result = {} local result = {}
local function remove(patterns) local function remove(patterns)
@ -146,7 +162,7 @@
end end
if cset.parent then if cset.parent then
result = configset._fetchMerged(cset.parent, field, filter, ctx) result = configset._fetchMerged(cset.parent, field, filter, ctx, origin)
end end
local abspath = filter.files local abspath = filter.files
@ -157,38 +173,39 @@
local n = #blocks local n = #blocks
for i = 1, n do for i = 1, n do
local block = blocks[i] local block = blocks[i]
if not origin or block._origin == origin then
-- If the filter contains a file path, make it relative to -- If the filter contains a file path, make it relative to
-- this block's basedir -- this block's basedir
if abspath and block._basedir and block._basedir ~= basedir and not cset.compiled then if abspath and block._basedir and block._basedir ~= basedir and not cset.compiled then
basedir = block._basedir basedir = block._basedir
filter.files = path.getrelative(basedir, abspath) filter.files = path.getrelative(basedir, abspath)
end
if cset.compiled or criteria.matches(block._criteria, filter) then
if block._removes and block._removes[key] then
remove(block._removes[key])
end end
local value = block[key] if cset.compiled or criteria.matches(block._criteria, filter) then
-- If value is an object, return a copy of it so that any if block._removes and block._removes[key] then
-- changes later made to it by the caller won't alter the remove(block._removes[key])
-- original value (that was a tough bug to find)
if type(value) == "table" then
value = table.deepcopy(value)
end
if value then
-- Detoken
if field.tokens and ctx.environ then
value = p.detoken.expand(value, ctx.environ, field, ctx._basedir)
end
-- Translate
if field and p.field.translates(field) then
value = p.field.translate(field, value)
end end
result = p.field.merge(field, result, value) local value = block[key]
-- If value is an object, return a copy of it so that any
-- changes later made to it by the caller won't alter the
-- original value (that was a tough bug to find)
if type(value) == "table" then
value = table.deepcopy(value)
end
if value then
-- Detoken
if field.tokens and ctx.environ then
value = p.detoken.expand(value, ctx.environ, field, ctx._basedir)
end
-- Translate
if field and p.field.translates(field) then
value = p.field.translate(field, value)
end
result = p.field.merge(field, result, value)
end
end end
end end
end end
@ -283,6 +300,7 @@
local block = {} local block = {}
block._criteria = crit block._criteria = crit
block._origin = cset
if basedir then if basedir then
block._basedir = basedir:lower() block._basedir = basedir:lower()
@ -309,6 +327,7 @@
local block = {} local block = {}
block._criteria = filter._criteria block._criteria = filter._criteria
block._basedir = filter._basedir block._basedir = filter._basedir
block._origin = cset
table.insert(cset.blocks, block) table.insert(cset.blocks, block)
cset.current = block; cset.current = block;
end end
@ -373,6 +392,7 @@
local block = {} local block = {}
block._basedir = cset.current._basedir block._basedir = cset.current._basedir
block._criteria = cset.current._criteria block._criteria = cset.current._criteria
block._origin = cset
table.insert(cset.blocks, block) table.insert(cset.blocks, block)
cset.current = block cset.current = block
@ -447,6 +467,9 @@
for i = 1, n do for i = 1, n do
local block = blocks[i] local block = blocks[i]
if block._origin == cset then
block._origin = result
end
-- If the filter contains a file path, make it relative to -- If the filter contains a file path, make it relative to
-- this block's basedir -- this block's basedir

View File

@ -168,26 +168,35 @@
-- The context to query. -- The context to query.
-- @param key -- @param key
-- The property key to query. -- The property key to query.
-- @param onlylocal
-- If true, don't combine values from parent contexts.
-- @return -- @return
-- The value of the key, as determined by the configuration set. If -- The value of the key, as determined by the configuration set. If
-- there is a corresponding Premake field, and it the field is enabled -- there is a corresponding Premake field, and it the field is enabled
-- for tokens, any contained tokens will be expanded. -- for tokens, any contained tokens will be expanded.
-- --
function context.fetchvalue(ctx, key) function context.fetchvalue(ctx, key, onlylocal)
if not onlylocal then
local value = rawget(ctx, key)
if value ~= nil then
return value
end
end
-- The underlying configuration set will only hold registered fields. -- The underlying configuration set will only hold registered fields.
-- If the requested key doesn't have a corresponding field, it is just -- If the requested key doesn't have a corresponding field, it is just
-- a regular value to be stored and fetched from the table. -- a regular value to be stored and fetched from the table.
local field = p.field.get(key) local field = p.field.get(key)
if not field then if not field then
return rawget(ctx, key) return nil
end end
-- If there is a matching field, then go fetch the aggregated value -- If there is a matching field, then go fetch the aggregated value
-- from my configuration set, and then cache it future lookups. -- from my configuration set, and then cache it future lookups.
local value = configset.fetch(ctx._cfgset, field, ctx.terms, ctx) local value = configset.fetch(ctx._cfgset, field, ctx.terms, ctx, onlylocal and ctx._cfgset)
if value then if value then
-- store the result for later lookups -- store the result for later lookups
ctx[key] = value ctx[key] = value