Merge pull request #184 from Blizzard/local-queries

Local queries
This commit is contained in:
starkos 2015-09-09 15:13:03 -04:00
commit 113112b721
2 changed files with 88 additions and 56 deletions

View File

@ -63,23 +63,31 @@
-- the context filtering case-insensitive.
-- @param ctx
-- The context that will be used for detoken.expand
-- @param origin
-- The originating configset if set.
-- @return
-- The requested value.
---
function configset.fetch(cset, field, filter, ctx)
function configset.fetch(cset, field, filter, ctx, origin)
filter = filter or {}
ctx = ctx or {}
if p.field.merges(field) then
return configset._fetchMerged(cset, field, filter, ctx)
return configset._fetchMerged(cset, field, filter, ctx, origin)
else
return configset._fetchDirect(cset, field, filter, ctx)
return configset._fetchDirect(cset, field, filter, ctx, origin)
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 basedir
@ -88,40 +96,48 @@
local n = #blocks
for i = n, 1, -1 do
local block = blocks[i]
local value = block[key]
-- If the filter contains a file path, make it relative to
-- this block's basedir
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 not origin or block._origin == origin then
local value = block[key]
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)
-- If the filter contains a file path, make it relative to
-- this block's basedir
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
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
filter.files = abspath
if cset.parent then
return configset._fetchDirect(cset.parent, field, filter, ctx)
return configset._fetchDirect(cset.parent, field, filter, ctx, origin)
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 function remove(patterns)
@ -146,7 +162,7 @@
end
if cset.parent then
result = configset._fetchMerged(cset.parent, field, filter, ctx)
result = configset._fetchMerged(cset.parent, field, filter, ctx, origin)
end
local abspath = filter.files
@ -157,38 +173,39 @@
local n = #blocks
for i = 1, n do
local block = blocks[i]
-- If the filter contains a file path, make it relative to
-- this block's basedir
if abspath and block._basedir and block._basedir ~= basedir and not cset.compiled then
basedir = block._basedir
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])
if not origin or block._origin == origin then
-- If the filter contains a file path, make it relative to
-- this block's basedir
if abspath and block._basedir and block._basedir ~= basedir and not cset.compiled then
basedir = block._basedir
filter.files = path.getrelative(basedir, abspath)
end
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)
if cset.compiled or criteria.matches(block._criteria, filter) then
if block._removes and block._removes[key] then
remove(block._removes[key])
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
@ -283,6 +300,7 @@
local block = {}
block._criteria = crit
block._origin = cset
if basedir then
block._basedir = basedir:lower()
@ -309,6 +327,7 @@
local block = {}
block._criteria = filter._criteria
block._basedir = filter._basedir
block._origin = cset
table.insert(cset.blocks, block)
cset.current = block;
end
@ -373,6 +392,7 @@
local block = {}
block._basedir = cset.current._basedir
block._criteria = cset.current._criteria
block._origin = cset
table.insert(cset.blocks, block)
cset.current = block
@ -447,6 +467,9 @@
for i = 1, n do
local block = blocks[i]
if block._origin == cset then
block._origin = result
end
-- If the filter contains a file path, make it relative to
-- this block's basedir

View File

@ -168,26 +168,35 @@
-- The context to query.
-- @param key
-- The property key to query.
-- @param onlylocal
-- If true, don't combine values from parent contexts.
-- @return
-- The value of the key, as determined by the configuration set. If
-- there is a corresponding Premake field, and it the field is enabled
-- 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.
-- If the requested key doesn't have a corresponding field, it is just
-- a regular value to be stored and fetched from the table.
local field = p.field.get(key)
if not field then
return rawget(ctx, key)
return nil
end
-- If there is a matching field, then go fetch the aggregated value
-- 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
-- store the result for later lookups
ctx[key] = value