singrdk/base/Windows/BuildToolsLibrary/TokenDefinition.cs

364 lines
13 KiB
C#

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: TokenDefinition.cs
//
// Note: Declares a class describing MetaData tokens, so that the
// metadata parser's consts can all be easily identified.
using System;
using System.Diagnostics;
using System.Xml;
using Bartok.MSIL;
public class TokenDefinition
{
// name of the metadata attribute to match
public readonly string attribute;
// name of the xml tag to output
public readonly string xmlTagName;
// labels for constructor fields during output
public readonly string [] constructorFields;
// labels for properties to be renamed during output
// each property uses two addresses [default, new name]
public readonly string [] propertyReplacements;
// fields to be added with default values, if not named
public readonly string [] defaultFields;
// basic constructor; everything is public, but now it's all very easy to
// keep track of.
public TokenDefinition(string xmlTagName,
string attribute,
string [] constructorFields,
string [] propertyReplacements,
string [] defaultFields)
{
this.xmlTagName = xmlTagName;
this.attribute = attribute;
this.constructorFields = constructorFields;
if (propertyReplacements != null && (propertyReplacements.Length % 2) != 0) {
Console.WriteLine("{0} has bad propertyReplacements", xmlTagName);
}
this.propertyReplacements = propertyReplacements;
if (defaultFields != null && (defaultFields.Length % 2) != 0) {
Console.WriteLine("{0} has bad defaultFields", xmlTagName);
}
this.defaultFields = defaultFields;
}
public TokenDefinition(string xmlTagName,
string attribute,
string [] constructorFields,
string [] propertyReplacements)
: this(xmlTagName, attribute, constructorFields, propertyReplacements, new string[0])
{
}
public TokenDefinition(string xmlTagName,
string attribute,
string [] constructorFields)
: this(xmlTagName, attribute, constructorFields, new string[0], new string[0])
{
}
public TokenDefinition(string xmlTagName,
string attribute)
: this(xmlTagName, attribute, new string[0], new string[0], new string[0])
{
}
public string FindPropertyReplacement(string name)
{
if (propertyReplacements != null) {
for (int pair = 0; pair < propertyReplacements.Length; pair += 2) {
if (propertyReplacements[pair] == name) {
return propertyReplacements[pair + 1];
}
}
}
return name;
}
}
public class TriggerDefinition : TokenDefinition
{
// name of the category
public readonly string categoryName;
// name of the class that the decorated class must directly inherit from
public readonly string derivesFromClass;
public TriggerDefinition(string xmlTagName,
string categoryName,
string attribute,
string derivesFromClass,
string [] constructorFields,
string [] propertyReplacements,
string [] defaultFields)
: base(xmlTagName,
attribute,
constructorFields,
propertyReplacements,
defaultFields)
{
this.derivesFromClass = derivesFromClass;
this.categoryName = categoryName;
}
public TriggerDefinition(string xmlTagName,
string categoryName,
string attribute,
string derivesFromClass,
string [] constructorFields,
string [] propertyReplacements)
: base(xmlTagName, attribute, constructorFields, propertyReplacements, new string[0])
{
this.derivesFromClass = derivesFromClass;
this.categoryName = categoryName;
}
public TriggerDefinition(string xmlTagName,
string categoryName,
string attribute,
string derivesFromClass,
string [] constructorFields)
: base(xmlTagName, attribute, constructorFields, new string[0], new string[0])
{
this.derivesFromClass = derivesFromClass;
this.categoryName = categoryName;
}
public TriggerDefinition(string xmlTagName,
string categoryName,
string attribute,
string derivesFromClass)
: base(xmlTagName, attribute, new string[0], new string[0], new string[0])
{
this.derivesFromClass = derivesFromClass;
this.categoryName = categoryName;
}
}
public class ClassDefinition : TokenDefinition
{
public ClassDefinition(string xmlTagName,
string attribute,
string [] constructorFields,
string [] propertyReplacements,
string [] defaultFields)
: base(xmlTagName,
attribute,
constructorFields,
propertyReplacements,
defaultFields)
{
}
public ClassDefinition(string xmlTagName,
string attribute,
string [] constructorFields,
string [] propertyReplacements)
: base(xmlTagName, attribute, constructorFields, propertyReplacements, new string[0])
{
}
public ClassDefinition(string xmlTagName,
string attribute,
string [] constructorFields)
: base(xmlTagName, attribute, constructorFields, new string[0], new string[0])
{
}
public ClassDefinition(string xmlTagName,
string attribute)
: base(xmlTagName, attribute, new string[0], new string[0], new string[0])
{
}
}
public class ParameterDefinition : FieldDefinition
{
public ParameterDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType,
string [] constructorFields)
: base(xmlGroup,
xmlTagName,
attribute,
matchClassType,
constructorFields)
{
}
}
public class FieldDefinition : TokenDefinition
{
// name of the group to put the field into.
public readonly string xmlGroup;
// name of the class that the decorated class must be (fields only)
public readonly string matchClassType;
public FieldDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType,
string [] constructorFields,
string [] propertyReplacements,
string [] defaultFields)
: base(xmlTagName,
attribute,
constructorFields,
propertyReplacements,
defaultFields)
{
this.xmlGroup = xmlGroup;
this.matchClassType = matchClassType;
}
public FieldDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType,
string [] constructorFields,
string [] propertyReplacements)
: base(xmlTagName,
attribute,
constructorFields,
propertyReplacements,
new string[0])
{
this.xmlGroup = xmlGroup;
this.matchClassType = matchClassType;
}
public FieldDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType,
string [] constructorFields)
: base(xmlTagName,
attribute,
constructorFields,
new string[0],
new string[0])
{
this.xmlGroup = xmlGroup;
this.matchClassType = matchClassType;
}
public FieldDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType)
: base(xmlTagName,
attribute,
new string[0],
new string[0],
new string[0])
{
this.xmlGroup = xmlGroup;
this.matchClassType = matchClassType;
}
}
public class EndpointDefinition : FieldDefinition
{
public EndpointDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType)
: base(xmlGroup,
xmlTagName,
attribute,
matchClassType,
new string[0],
new string[0],
new string[0])
{
}
public EndpointDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType,
string[] constructorFields)
: base(xmlGroup,
xmlTagName,
attribute,
matchClassType,
constructorFields,
new string[0],
new string[0])
{
}
public virtual void AddContractNameAttribute(ManifestBuilder mfb,
XmlNode node,
MetaDataCustomAttribute data,
string contractName)
{
mfb.AddAttribute(node, "contractName", contractName);
}
}
public class ServiceEndpointDefinition : EndpointDefinition
{
public ServiceEndpointDefinition(string xmlGroup,
string xmlTagName,
string attribute,
string matchClassType)
: base(xmlGroup, xmlTagName, attribute, matchClassType)
{
}
public override void AddContractNameAttribute(ManifestBuilder mfb,
XmlNode node,
MetaDataCustomAttribute data,
string contractName)
{
// takes endpoint type as argument
if (data.FixedArgs == null || data.FixedArgs.Length != 1) {
mfb.Error("ServiceEndpoint attribute must have 1 type argument");
return;
}
// now make it easy to split into name=value pairs by doing some
// string replacing
string ctorArgument = "contractName=" + data.FixedArgs[0];
ctorArgument = ctorArgument.Replace("+", " endpointEnd=");
ctorArgument = ctorArgument.Replace(", V", " v");
ctorArgument = ctorArgument.Replace(", C", " c");
ctorArgument = ctorArgument.Replace(", P", " p");
ctorArgument = ctorArgument.Replace(",", " assembly=");
// now we can split on ' ' and '=' to get name/value pairs
string [] endpointConfig = ctorArgument.Split(' ');
// grab only the contractName, ignore the rest
#if false
foreach (string attrib in endpointConfig) {
string [] pair = attrib.Split('=');
if (pair.Length == 2) {
string name = pair[0];
string value = pair[1];
AddAttribute(node, name, value);
}
}
#else
string [] pair = endpointConfig[0].Split('=');
Debug.Assert(pair.Length == 2);
string name = pair[0];
Debug.Assert(name == "contractName");
string value = pair[1];
base.AddContractNameAttribute(mfb, node, data, value);
#endif
}
}