Merge improved field scoping for usages

This commit is contained in:
Jason Perkins 2014-12-13 17:39:58 -05:00
commit 7b44ef842d
3 changed files with 60 additions and 23 deletions

View File

@ -35,12 +35,17 @@
-- @param parentContainer (optional)
-- The container that can contain this one. For a project, this would be
-- the solution container class.
-- @param extraScopes (optional)
-- Each container can hold fields scoped to itself (by putting the container's
-- class name into its scope attribute), or any of the container's children.
-- If a container can hold scopes other than these (i.e. "config"), it can
-- provide a list of those scopes in this argument.
-- @returns
-- The newly defined container class.
---
function api.container(containerName, parentContainer)
local class, err = p.container.newClass(containerName, parentContainer)
function api.container(containerName, parentContainer, extraScopes)
local class, err = p.container.newClass(containerName, parentContainer, extraScopes)
if not class then
error(err, 2)
end
@ -451,26 +456,9 @@
---
function api.target(field)
local scopes = field.scopes
for i = 1, #scopes do
local scope = scopes[i]
-- TODO: rules should be able to contain filter blocks too, but
-- to all the existing code expects the "config" scope to mean
-- project settings. Will revisit.
if scope == "config" then
scope = "project"
end
-- If anything in the currently active container's hierarchy is
-- compatibile with this scope, then I can use it.
local currentClass = api.scope.current.class
local targetClass = p.container.getClass(scope)
if p.container.classIsA(targetClass, currentClass.name) then
return api.scope.current
end
if p.container.classCanContain(api.scope.current.class, field.scope) then
return api.scope.current
end
return nil
end

View File

@ -30,16 +30,22 @@
-- @param parent (optional)
-- If this class of container is intended to be contained within another,
-- the containing class object.
-- @param extraScopes (optional)
-- Each container can hold fields scoped to itself (by putting the container's
-- class name into its scope attribute), or any of the container's children.
-- If a container can hold scopes other than these (i.e. "config"), it can
-- provide a list of those scopes in this argument.
-- @return
-- If successful, the new class descriptor object (a table). Otherwise,
-- returns nil and an error message.
---
function container.newClass(name, parent)
function container.newClass(name, parent, extraScopes)
local class = p.configset.new(parent)
class.name = name
class.pluralName = name:plural()
class.containedClasses = {}
class.extraScopes = extraScopes
if parent then
table.insert(parent.containedClasses, class)
@ -153,6 +159,49 @@
---
-- Returns true if the container can hold any of the specified field scopes.
--
-- @param class
-- The container class to test.
-- @param scope
-- A scope string (e.g. "project", "config") or an array of scope strings.
-- @return
-- True if this container can hold any of the specified scopes.
---
function container.classCanContain(class, scope)
if type(scope) == "table" then
for i = 1, #scope do
if container.classCanContain(class, scope[i]) then
return true
end
end
return false
end
-- if I have child classes, check with them first, since scopes
-- are usually specified for leaf nodes in the hierarchy
for child in container.eachChildClass(class) do
if (container.classCanContain(child, scope)) then
return true
end
end
if class.name == scope then
return true
end
-- is it in my extra scopes list?
if class.extraScopes and table.contains(class.extraScopes, scope) then
return true
end
return false
end
---
-- Enumerate all of the registered child classes of a specific container class.
--

View File

@ -5,7 +5,7 @@
---
local p = premake
p.project = p.api.container("project", p.solution)
p.project = p.api.container("project", p.solution, { "config" })
local project = p.project
local tree = p.tree