premake/modules/vstudio/vs2010_rules_xml.lua
WorldofBay ea984e9c1c Enable property categories in VS projects
Don't allow adding to "Command Line" though.
2018-10-18 12:01:15 +02:00

429 lines
8.9 KiB
Lua

---
-- vs2010_rules_xml.lua
-- Generate a Visual Studio 201x custom rules XML file.
-- Copyright (c) Jason Perkins and the Premake project
--
local p = premake
p.vstudio.vs2010.rules.xml = {}
local m = p.vstudio.vs2010.rules.xml
m.elements = {}
---
-- Entry point; generate the root <ProjectSchemaDefinitions> element.
---
m.elements.project = function(r)
return {
m.projectSchemaDefinitions,
m.rule,
m.ruleItem,
m.fileExtension,
m.contentType,
}
end
function m.generate(r)
p.xmlUtf8()
p.callArray(m.elements.project, r)
p.out('</ProjectSchemaDefinitions>')
end
---
-- Generate the main <Rule> element.
---
m.elements.rule = function(r)
return {
m.dataSource,
m.categories,
m.inputs,
m.properties,
m.commandLineTemplate,
m.beforeTargets,
m.afterTargets,
m.outputs,
m.executionDescription,
m.additionalDependencies,
m.additionalOptions,
}
end
function m.rule(r)
p.push('<Rule')
p.w('Name="%s"', r.name)
p.w('PageTemplate="tool"')
p.w('DisplayName="%s"', r.display or r.name)
p.w('Order="200">')
p.callArray(m.elements.rule, r)
p.pop('</Rule>')
end
---
-- Generate the list of categories.
---
function m.categories(r)
local categories = {
[1] = { name="General" },
}
local propCategory = {}
local defs = r.propertydefinition
for i = 1, #defs do
local def = defs[i]
local cat = def.category
if cat then
if type(cat) == "string" and cat ~= "Command Line" and cat ~= "General" then
if not propCategory[cat] then
table.insert(categories, { name=cat })
propCategory[cat] = true
end
else
def.category = nil
end
end
end
table.insert(categories, { name="Command Line", subtype="CommandLine" })
p.push('<Rule.Categories>')
for i = 1, #categories do
m.category(categories[i])
end
p.pop('</Rule.Categories>')
end
function m.category(cat)
local attribs = p.capture(function()
p.push()
p.w('Name="%s"', cat.name)
if cat.subtype then
p.w('Subtype="%s"', cat.subtype)
end
p.pop()
end)
p.push('<Category')
p.outln(attribs .. '>')
p.push('<Category.DisplayName>')
p.w('<sys:String>%s</sys:String>', cat.name)
p.pop('</Category.DisplayName>')
p.pop('</Category>')
end
---
-- Generate the list of property definitions.
---
function m.properties(r)
local defs = r.propertydefinition
for i = 1, #defs do
local def = defs[i]
if def.kind == "boolean" then
m.boolProperty(def)
elseif def.kind == "list" then
m.stringListProperty(def)
elseif type(def.values) == "table" then
m.enumProperty(def)
elseif def.kind and def.kind:startswith("list:") then
m.stringListProperty(def)
else
m.stringProperty(def)
end
end
end
function m.baseProperty(def, suffix)
local c = p.capture(function ()
p.w('Name="%s"', def.name)
p.w('HelpContext="0"')
p.w('DisplayName="%s"', def.display or def.name)
if def.description then
p.w('Description="%s"', def.description)
end
if def.category then
p.w('Category="%s"', def.category)
end
end)
if suffix then
c = c .. suffix
end
p.outln(c)
end
function m.boolProperty(def)
p.push('<BoolProperty')
m.baseProperty(def)
if def.switch then
p.w('Switch="%s"', def.switch)
end
p.w('/>')
p.pop()
end
function m.enumProperty(def)
p.push('<EnumProperty')
m.baseProperty(def, '>')
local values = def.values
local switches = def.switch or {}
local keys = table.keys(def.values)
table.sort(keys)
for _, key in pairs(keys) do
p.push('<EnumValue')
p.w('Name="%d"', key)
if switches[key] then
p.w('DisplayName="%s"', values[key])
if switches[key] then
p.w('Switch="%s"', switches[key])
end
else
p.w('DisplayName="%s"', values[key])
end
p.w('/>')
p.pop()
end
p.pop('</EnumProperty>')
end
function m.stringProperty(def)
p.push('<StringProperty')
m.baseProperty(def)
if def.switch then
p.w('Switch="%s"', def.switch)
end
p.w('/>')
p.pop()
end
function m.stringListProperty(def)
p.push('<StringListProperty')
m.baseProperty(def)
if def.separator then
p.w('Separator="%s"', def.separator)
end
if def.switch then
p.w('Switch="%s"', def.switch)
end
p.w('/>')
p.pop()
end
---
-- Implementations of individual elements.
---
function m.additionalDependencies(r)
p.push('<StringListProperty')
p.w('Name="AdditionalDependencies"')
p.w('DisplayName="Additional Dependencies"')
p.w('IncludeInCommandLine="False"')
p.w('Visible="false" />')
p.pop()
end
function m.additionalOptions(r)
p.push('<StringProperty')
p.w('Subtype="AdditionalOptions"')
p.w('Name="AdditionalOptions"')
p.w('Category="Command Line">')
p.push('<StringProperty.DisplayName>')
p.w('<sys:String>Additional Options</sys:String>')
p.pop('</StringProperty.DisplayName>')
p.push('<StringProperty.Description>')
p.w('<sys:String>Additional Options</sys:String>')
p.pop('</StringProperty.Description>')
p.pop('</StringProperty>')
end
function m.afterTargets(r)
p.push('<DynamicEnumProperty')
p.w('Name="%sAfterTargets"', r.name)
p.w('Category="General"')
p.w('EnumProvider="Targets"')
p.w('IncludeInCommandLine="False">')
p.push('<DynamicEnumProperty.DisplayName>')
p.w('<sys:String>Execute After</sys:String>')
p.pop('</DynamicEnumProperty.DisplayName>')
p.push('<DynamicEnumProperty.Description>')
p.w('<sys:String>Specifies the targets for the build customization to run after.</sys:String>')
p.pop('</DynamicEnumProperty.Description>')
p.push('<DynamicEnumProperty.ProviderSettings>')
p.push('<NameValuePair')
p.w('Name="Exclude"')
p.w('Value="^%sAfterTargets|^Compute" />', r.name)
p.pop()
p.pop('</DynamicEnumProperty.ProviderSettings>')
p.push('<DynamicEnumProperty.DataSource>')
p.push('<DataSource')
p.w('Persistence="ProjectFile"')
p.w('ItemType=""')
p.w('HasConfigurationCondition="true" />')
p.pop()
p.pop('</DynamicEnumProperty.DataSource>')
p.pop('</DynamicEnumProperty>')
end
function m.beforeTargets(r)
p.push('<DynamicEnumProperty')
p.w('Name="%sBeforeTargets"', r.name)
p.w('Category="General"')
p.w('EnumProvider="Targets"')
p.w('IncludeInCommandLine="False">')
p.push('<DynamicEnumProperty.DisplayName>')
p.w('<sys:String>Execute Before</sys:String>')
p.pop('</DynamicEnumProperty.DisplayName>')
p.push('<DynamicEnumProperty.Description>')
p.w('<sys:String>Specifies the targets for the build customization to run before.</sys:String>')
p.pop('</DynamicEnumProperty.Description>')
p.push('<DynamicEnumProperty.ProviderSettings>')
p.push('<NameValuePair')
p.w('Name="Exclude"')
p.w('Value="^%sBeforeTargets|^Compute" />', r.name)
p.pop()
p.pop('</DynamicEnumProperty.ProviderSettings>')
p.push('<DynamicEnumProperty.DataSource>')
p.push('<DataSource')
p.w('Persistence="ProjectFile"')
p.w('HasConfigurationCondition="true" />')
p.pop()
p.pop('</DynamicEnumProperty.DataSource>')
p.pop('</DynamicEnumProperty>')
end
function m.commandLineTemplate(r)
p.push('<StringProperty')
p.w('Name="CommandLineTemplate"')
p.w('DisplayName="Command Line"')
p.w('Visible="False"')
p.w('IncludeInCommandLine="False" />')
p.pop()
end
function m.contentType(r)
p.push('<ContentType')
p.w('Name="%s"', r.name)
p.w('DisplayName="%s"', r.display or r.name)
p.w('ItemType="%s" />', r.name)
p.pop()
end
function m.dataSource(r)
p.push('<Rule.DataSource>')
p.push('<DataSource')
p.w('Persistence="ProjectFile"')
p.w('ItemType="%s" />', r.name)
p.pop()
p.pop('</Rule.DataSource>')
end
function m.executionDescription(r)
p.push('<StringProperty')
p.w('Name="ExecutionDescription"')
p.w('DisplayName="Execution Description"')
p.w('Visible="False"')
p.w('IncludeInCommandLine="False" />')
p.pop()
end
function m.fileExtension(r)
for _, v in ipairs(r.fileextension) do
p.push('<FileExtension')
p.w('Name="*%s"', v)
p.w('ContentType="%s" />', r.name)
p.pop()
end
end
function m.inputs(r)
p.push('<StringListProperty')
p.w('Name="Inputs"')
p.w('Category="Command Line"')
p.w('IsRequired="true"')
p.w('Switch=" ">')
p.push('<StringListProperty.DataSource>')
p.push('<DataSource')
p.w('Persistence="ProjectFile"')
p.w('ItemType="%s"', r.name)
p.w('SourceType="Item" />')
p.pop()
p.pop('</StringListProperty.DataSource>')
p.pop('</StringListProperty>')
end
function m.outputs(r)
p.push('<StringListProperty')
p.w('Name="Outputs"')
p.w('DisplayName="Outputs"')
p.w('Visible="False"')
p.w('IncludeInCommandLine="False" />')
p.pop()
end
function m.ruleItem(r)
p.push('<ItemType')
p.w('Name="%s"', r.name)
p.w('DisplayName="%s" />', r.display or r.name)
p.pop()
end
function m.projectSchemaDefinitions(r)
p.push('<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">')
end