Singularity/Assets/Plugins/ImaginationOverflow/UniversalDeepLinking/Editor/Xcode/PBX/Objects.cs
2024-05-06 11:45:45 -07:00

1044 lines
39 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ImaginationOverflow.UniversalDeepLinking.Editor.Xcode.PBX
{
internal class PBXObjectData
{
public string guid;
protected PBXElementDict m_Properties = new PBXElementDict();
internal void SetPropertiesWhenSerializing(PBXElementDict props)
{
m_Properties = props;
}
internal PBXElementDict GetPropertiesWhenSerializing()
{
return m_Properties;
}
/* Returns the internal properties dictionary which the user may manipulate directly.
If any of the properties are modified, UpdateVars() must be called before any other
operation affecting the given Xcode document is executed.
*/
internal PBXElementDict GetPropertiesRaw()
{
UpdateProps();
return m_Properties;
}
// returns null if it does not exist
protected string GetPropertyString(string name)
{
var prop = m_Properties[name];
if (prop == null)
return null;
return prop.AsString();
}
protected void SetPropertyString(string name, string value)
{
if (value == null)
m_Properties.Remove(name);
else
m_Properties.SetString(name, value);
}
protected List<string> GetPropertyList(string name)
{
var prop = m_Properties[name];
if (prop == null)
return null;
var list = new List<string>();
foreach (var el in prop.AsArray().values)
list.Add(el.AsString());
return list;
}
protected void SetPropertyList(string name, List<string> value)
{
if (value == null)
m_Properties.Remove(name);
else
{
var array = m_Properties.CreateArray(name);
foreach (string val in value)
array.AddString(val);
}
}
private static PropertyCommentChecker checkerData = new PropertyCommentChecker();
internal virtual PropertyCommentChecker checker { get { return checkerData; } }
internal virtual bool shouldCompact { get { return false; } }
public virtual void UpdateProps() { } // Updates the props from cached variables
public virtual void UpdateVars() { } // Updates the cached variables from underlying props
}
internal class PBXBuildFileData : PBXObjectData
{
private static PropertyCommentChecker checkerData = new PropertyCommentChecker((IEnumerable<string>)new string[1]
{
"fileRef/*"
});
public string fileRef;
public string compileFlags;
public bool weak;
public bool codeSignOnCopy;
public bool removeHeadersOnCopy;
public List<string> assetTags;
internal override PropertyCommentChecker checker
{
get
{
return PBXBuildFileData.checkerData;
}
}
internal override bool shouldCompact
{
get
{
return true;
}
}
public static PBXBuildFileData CreateFromFile(
string fileRefGUID,
bool weak,
string compileFlags)
{
PBXBuildFileData pbxBuildFileData = new PBXBuildFileData();
pbxBuildFileData.guid = PBXGUID.Generate();
pbxBuildFileData.SetPropertyString("isa", "PBXBuildFile");
pbxBuildFileData.fileRef = fileRefGUID;
pbxBuildFileData.compileFlags = compileFlags;
pbxBuildFileData.weak = weak;
pbxBuildFileData.codeSignOnCopy = false;
pbxBuildFileData.removeHeadersOnCopy = false;
pbxBuildFileData.assetTags = new List<string>();
return pbxBuildFileData;
}
private PBXElementDict UpdatePropsAttribute(
PBXElementDict settings,
bool value,
string attributeName)
{
PBXElementArray pbxElementArray = (PBXElementArray)null;
if (value && settings == null)
settings = this.m_Properties.CreateDict("settings");
if (settings != null && settings.Contains("ATTRIBUTES"))
pbxElementArray = settings["ATTRIBUTES"].AsArray();
if (value)
{
if (pbxElementArray == null)
pbxElementArray = settings.CreateArray("ATTRIBUTES");
if (!pbxElementArray.values.Any<PBXElement>((Func<PBXElement, bool>)(attr => attr is PBXElementString && attr.AsString() == attributeName)))
pbxElementArray.AddString(attributeName);
}
else if (pbxElementArray != null)
{
pbxElementArray.values.RemoveAll((Predicate<PBXElement>)(el => el is PBXElementString && el.AsString() == attributeName));
if (pbxElementArray.values.Count == 0)
settings.Remove("ATTRIBUTES");
}
return settings;
}
public override void UpdateProps()
{
this.SetPropertyString("fileRef", this.fileRef);
PBXElementDict settings = (PBXElementDict)null;
if (this.m_Properties.Contains("settings"))
settings = this.m_Properties["settings"].AsDict();
if (this.compileFlags != null && this.compileFlags != "")
{
if (settings == null)
settings = this.m_Properties.CreateDict("settings");
settings.SetString("COMPILER_FLAGS", this.compileFlags);
}
else
{
if (settings != null)
settings.Remove("COMPILER_FLAGS");
}
PBXElementDict pbxElementDict = this.UpdatePropsAttribute(this.UpdatePropsAttribute(this.UpdatePropsAttribute(settings, this.weak, "Weak"), this.codeSignOnCopy, "CodeSignOnCopy"), this.removeHeadersOnCopy, "RemoveHeadersOnCopy");
if (this.assetTags.Count > 0)
{
if (pbxElementDict == null)
pbxElementDict = this.m_Properties.CreateDict("settings");
PBXElementArray array = pbxElementDict.CreateArray("ASSET_TAGS");
foreach (string assetTag in this.assetTags)
array.AddString(assetTag);
}
else
{
if (pbxElementDict != null)
pbxElementDict.Remove("ASSET_TAGS");
}
if (pbxElementDict == null || pbxElementDict.values.Count != 0)
return;
this.m_Properties.Remove("settings");
}
public override void UpdateVars()
{
this.fileRef = this.GetPropertyString("fileRef");
this.compileFlags = (string)null;
this.weak = false;
this.assetTags = new List<string>();
if (!this.m_Properties.Contains("settings"))
return;
PBXElementDict pbxElementDict = this.m_Properties["settings"].AsDict();
if (pbxElementDict.Contains("COMPILER_FLAGS"))
this.compileFlags = pbxElementDict["COMPILER_FLAGS"].AsString();
if (pbxElementDict.Contains("ATTRIBUTES"))
{
foreach (PBXElement pbxElement in pbxElementDict["ATTRIBUTES"].AsArray().values)
{
if (pbxElement is PBXElementString && pbxElement.AsString() == "Weak")
this.weak = true;
if (pbxElement is PBXElementString && pbxElement.AsString() == "CodeSignOnCopy")
this.codeSignOnCopy = true;
if (pbxElement is PBXElementString && pbxElement.AsString() == "RemoveHeadersOnCopy")
this.removeHeadersOnCopy = true;
}
}
if (pbxElementDict.Contains("ASSET_TAGS"))
{
foreach (PBXElement pbxElement in pbxElementDict["ASSET_TAGS"].AsArray().values)
this.assetTags.Add(pbxElement.AsString());
}
}
}
internal class PBXFileReferenceData : PBXObjectData
{
string m_Path = null;
string m_ExplicitFileType = null;
string m_LastKnownFileType = null;
public string path
{
get { return m_Path; }
set { m_ExplicitFileType = null; m_LastKnownFileType = null; m_Path = value; }
}
public string name;
public PBXSourceTree tree;
public bool isFolderReference
{
get { return m_LastKnownFileType != null && m_LastKnownFileType == "folder"; }
}
internal override bool shouldCompact { get { return true; } }
public static PBXFileReferenceData CreateFromFile(string path, string projectFileName,
PBXSourceTree tree)
{
string guid = PBXGUID.Generate();
PBXFileReferenceData fileRef = new PBXFileReferenceData();
fileRef.SetPropertyString("isa", "PBXFileReference");
fileRef.guid = guid;
fileRef.path = path;
fileRef.name = projectFileName;
fileRef.tree = tree;
return fileRef;
}
public static PBXFileReferenceData CreateFromFolderReference(string path, string projectFileName,
PBXSourceTree tree)
{
var fileRef = CreateFromFile(path, projectFileName, tree);
fileRef.m_LastKnownFileType = "folder";
return fileRef;
}
public override void UpdateProps()
{
string ext = null;
if (m_ExplicitFileType != null)
SetPropertyString("explicitFileType", m_ExplicitFileType);
else if (m_LastKnownFileType != null)
SetPropertyString("lastKnownFileType", m_LastKnownFileType);
else
{
if (name != null)
ext = Path.GetExtension(name);
else if (m_Path != null)
ext = Path.GetExtension(m_Path);
if (ext != null)
{
if (FileTypeUtils.IsFileTypeExplicit(ext))
SetPropertyString("explicitFileType", FileTypeUtils.GetTypeName(ext));
else
SetPropertyString("lastKnownFileType", FileTypeUtils.GetTypeName(ext));
}
}
if (m_Path == name)
SetPropertyString("name", null);
else
SetPropertyString("name", name);
if (m_Path == null)
SetPropertyString("path", "");
else
SetPropertyString("path", m_Path);
SetPropertyString("sourceTree", FileTypeUtils.SourceTreeDesc(tree));
}
public override void UpdateVars()
{
name = GetPropertyString("name");
m_Path = GetPropertyString("path");
if (name == null)
name = m_Path;
if (m_Path == null)
m_Path = "";
tree = FileTypeUtils.ParseSourceTree(GetPropertyString("sourceTree"));
m_ExplicitFileType = GetPropertyString("explicitFileType");
m_LastKnownFileType = GetPropertyString("lastKnownFileType");
}
public void SetFileTypeByExtension(string extension)
{
if (FileTypeUtils.IsFileTypeExplicit(extension))
{
SetPropertyString("explicitFileType", FileTypeUtils.GetTypeName(extension));
}
else
{
SetPropertyString("lastKnownFileType", FileTypeUtils.GetTypeName(extension));
}
}
}
class GUIDList : IEnumerable<string>
{
private List<string> m_List = new List<string>();
public GUIDList() { }
public GUIDList(List<string> data)
{
m_List = data;
}
public static implicit operator List<string>(GUIDList list) { return list.m_List; }
public static implicit operator GUIDList(List<string> data) { return new GUIDList(data); }
public void AddGUID(string guid) { m_List.Add(guid); }
public void RemoveGUID(string guid) { m_List.RemoveAll(x => x == guid); }
public bool Contains(string guid) { return m_List.Contains(guid); }
public int Count { get { return m_List.Count; } }
public void Clear() { m_List.Clear(); }
IEnumerator<string> IEnumerable<string>.GetEnumerator() { return m_List.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return m_List.GetEnumerator(); }
}
internal class XCConfigurationListData : PBXObjectData
{
public GUIDList buildConfigs;
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"buildConfigurations/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public static XCConfigurationListData Create()
{
var res = new XCConfigurationListData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "XCConfigurationList");
res.buildConfigs = new GUIDList();
res.SetPropertyString("defaultConfigurationIsVisible", "0");
return res;
}
public override void UpdateProps()
{
SetPropertyList("buildConfigurations", buildConfigs);
}
public override void UpdateVars()
{
buildConfigs = GetPropertyList("buildConfigurations");
}
}
internal class PBXGroupData : PBXObjectData
{
public GUIDList children;
public PBXSourceTree tree;
public string name, path;
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"children/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
// name must not contain '/'
public static PBXGroupData Create(string name, string path, PBXSourceTree tree)
{
if (name.Contains("/"))
throw new Exception("Group name must not contain '/'");
PBXGroupData gr = new PBXGroupData();
gr.guid = PBXGUID.Generate();
gr.SetPropertyString("isa", "PBXGroup");
gr.name = name;
gr.path = path;
gr.tree = PBXSourceTree.Group;
gr.children = new GUIDList();
return gr;
}
public static PBXGroupData CreateRelative(string name)
{
return Create(name, name, PBXSourceTree.Group);
}
public override void UpdateProps()
{
// The name property is set only if it is different from the path property
SetPropertyList("children", children);
if (name == path)
SetPropertyString("name", null);
else
SetPropertyString("name", name);
if (path == "")
SetPropertyString("path", null);
else
SetPropertyString("path", path);
SetPropertyString("sourceTree", FileTypeUtils.SourceTreeDesc(tree));
}
public override void UpdateVars()
{
children = GetPropertyList("children");
path = GetPropertyString("path");
name = GetPropertyString("name");
if (name == null)
name = path;
if (path == null)
path = "";
tree = FileTypeUtils.ParseSourceTree(GetPropertyString("sourceTree"));
}
}
internal class PBXVariantGroupData : PBXGroupData
{
public static PBXVariantGroupData Create(string name)
{
if (name.Contains("/"))
throw new Exception("Group name must not contain '/'");
PBXVariantGroupData gr = new PBXVariantGroupData();
gr.guid = PBXGUID.Generate();
gr.SetPropertyString("isa", "PBXVariantGroup");
gr.name = name;
gr.tree = PBXSourceTree.Group;
gr.children = new GUIDList();
return gr;
}
}
internal class PBXNativeTargetData : PBXObjectData
{
public GUIDList phases;
public string buildConfigList; // guid
public string name;
public GUIDList dependencies;
public string productReference; // guid
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"buildPhases/*",
"buildRules/*",
"dependencies/*",
"productReference/*",
"buildConfigurationList/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public static PBXNativeTargetData Create(string name, string productRef,
string productType, string buildConfigList)
{
var res = new PBXNativeTargetData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXNativeTarget");
res.buildConfigList = buildConfigList;
res.phases = new GUIDList();
res.SetPropertyList("buildRules", new List<string>());
res.dependencies = new GUIDList();
res.name = name;
res.productReference = productRef;
res.SetPropertyString("productName", name);
res.SetPropertyString("productReference", productRef);
res.SetPropertyString("productType", productType);
return res;
}
public override void UpdateProps()
{
SetPropertyString("buildConfigurationList", buildConfigList);
SetPropertyString("name", name);
SetPropertyString("productReference", productReference);
SetPropertyList("buildPhases", phases);
SetPropertyList("dependencies", dependencies);
}
public override void UpdateVars()
{
buildConfigList = GetPropertyString("buildConfigurationList");
name = GetPropertyString("name");
productReference = GetPropertyString("productReference");
phases = GetPropertyList("buildPhases");
dependencies = GetPropertyList("dependencies");
}
}
internal class FileGUIDListBase : PBXObjectData
{
public GUIDList files;
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"files/*",
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public override void UpdateProps()
{
SetPropertyList("files", files);
}
public override void UpdateVars()
{
files = GetPropertyList("files");
}
}
internal class PBXSourcesBuildPhaseData : FileGUIDListBase
{
public static PBXSourcesBuildPhaseData Create()
{
var res = new PBXSourcesBuildPhaseData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXSourcesBuildPhase");
res.SetPropertyString("buildActionMask", "2147483647");
res.files = new List<string>();
res.SetPropertyString("runOnlyForDeploymentPostprocessing", "0");
return res;
}
}
internal class PBXFrameworksBuildPhaseData : FileGUIDListBase
{
public const string ISA = "PBXFrameworksBuildPhase";
public string isa
{
get { return GetPropertyString("isa"); }
}
public static PBXFrameworksBuildPhaseData Create()
{
var res = new PBXFrameworksBuildPhaseData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXFrameworksBuildPhase");
res.SetPropertyString("buildActionMask", "2147483647");
res.files = new List<string>();
res.SetPropertyString("runOnlyForDeploymentPostprocessing", "0");
return res;
}
}
internal class PBXResourcesBuildPhaseData : FileGUIDListBase
{
public static PBXResourcesBuildPhaseData Create()
{
var res = new PBXResourcesBuildPhaseData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXResourcesBuildPhase");
res.SetPropertyString("buildActionMask", "2147483647");
res.files = new List<string>();
res.SetPropertyString("runOnlyForDeploymentPostprocessing", "0");
return res;
}
}
internal class PBXCopyFilesBuildPhaseData : FileGUIDListBase
{
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"files/*",
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public string name;
// name may be null
public static PBXCopyFilesBuildPhaseData Create(string name, string dstPath, string subfolderSpec)
{
var res = new PBXCopyFilesBuildPhaseData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXCopyFilesBuildPhase");
res.SetPropertyString("buildActionMask", "2147483647");
res.SetPropertyString("dstPath", dstPath);
res.SetPropertyString("dstSubfolderSpec", subfolderSpec);
res.files = new List<string>();
res.SetPropertyString("runOnlyForDeploymentPostprocessing", "0");
res.name = name;
return res;
}
public override void UpdateProps()
{
SetPropertyList("files", files);
SetPropertyString("name", name);
}
public override void UpdateVars()
{
files = GetPropertyList("files");
name = GetPropertyString("name");
}
}
internal class PBXShellScriptBuildPhaseData : FileGUIDListBase
{
public string name;
public string shellPath;
public string shellScript;
public static PBXShellScriptBuildPhaseData Create(string name, string shellPath, string shellScript)
{
var res = new PBXShellScriptBuildPhaseData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXShellScriptBuildPhase");
res.SetPropertyString("buildActionMask", "2147483647");
res.files = new List<string>();
res.SetPropertyString("runOnlyForDeploymentPostprocessing", "0");
res.name = name;
res.shellPath = shellPath;
res.shellScript = shellScript;
return res;
}
public override void UpdateProps()
{
base.UpdateProps();
SetPropertyString("name", name);
SetPropertyString("shellPath", shellPath);
SetPropertyString("shellScript", shellScript);
}
public override void UpdateVars()
{
base.UpdateVars();
name = GetPropertyString("name");
shellPath = GetPropertyString("shellPath");
shellScript = GetPropertyString("shellScript");
}
}
internal class BuildConfigEntryData
{
public string name;
public List<string> val = new List<string>();
public static string ExtractValue(string src)
{
return PBXStream.UnquoteString(src.Trim().TrimEnd(','));
}
public void AddValue(string value)
{
if (!val.Contains(value))
val.Add(value);
}
public void RemoveValue(string value)
{
val.RemoveAll(v => v == value);
}
public void RemoveValueList(IEnumerable<string> values)
{
List<string> valueList = new List<string>(values);
if (valueList.Count == 0)
return;
for (int i = 0; i < val.Count - valueList.Count; i++)
{
bool match = true;
for (int j = 0; j < valueList.Count; j++)
{
if (val[i + j] != valueList[j])
{
match = false;
break;
}
}
if (match)
{
val.RemoveRange(i, valueList.Count);
return;
}
}
}
public static BuildConfigEntryData FromNameValue(string name, string value)
{
BuildConfigEntryData ret = new BuildConfigEntryData();
ret.name = name;
ret.AddValue(value);
return ret;
}
}
internal class XCBuildConfigurationData : PBXObjectData
{
protected SortedDictionary<string, BuildConfigEntryData> entries = new SortedDictionary<string, BuildConfigEntryData>();
public string name { get { return GetPropertyString("name"); } }
public string baseConfigurationReference; // may be null
// Note that QuoteStringIfNeeded does its own escaping. Double-escaping with quotes is
// required to please Xcode that does not handle paths with spaces if they are not
// enclosed in quotes.
static string EscapeWithQuotesIfNeeded(string name, string value)
{
if (name != "LIBRARY_SEARCH_PATHS" && name != "FRAMEWORK_SEARCH_PATHS")
return value;
if (!value.Contains(" "))
return value;
if (value.First() == '\"' && value.Last() == '\"')
return value;
return "\"" + value + "\"";
}
public void SetProperty(string name, string value)
{
entries[name] = BuildConfigEntryData.FromNameValue(name, EscapeWithQuotesIfNeeded(name, value));
}
public void AddProperty(string name, string value)
{
if (entries.ContainsKey(name))
entries[name].AddValue(EscapeWithQuotesIfNeeded(name, value));
else
SetProperty(name, value);
}
public void RemoveProperty(string name)
{
if (entries.ContainsKey(name))
entries.Remove(name);
}
public void RemovePropertyValue(string name, string value)
{
if (entries.ContainsKey(name))
entries[name].RemoveValue(EscapeWithQuotesIfNeeded(name, value));
}
public void RemovePropertyValueList(string name, IEnumerable<string> valueList)
{
if (entries.ContainsKey(name))
entries[name].RemoveValueList(valueList);
}
// name should be either release or debug
public static XCBuildConfigurationData Create(string name)
{
var res = new XCBuildConfigurationData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "XCBuildConfiguration");
res.SetPropertyString("name", name);
return res;
}
public override void UpdateProps()
{
SetPropertyString("baseConfigurationReference", baseConfigurationReference);
var dict = m_Properties.CreateDict("buildSettings");
foreach (var kv in entries)
{
if (kv.Value.val.Count == 0)
continue;
else if (kv.Value.val.Count == 1)
dict.SetString(kv.Key, kv.Value.val[0]);
else // kv.Value.val.Count > 1
{
var array = dict.CreateArray(kv.Key);
foreach (var value in kv.Value.val)
array.AddString(value);
}
}
}
public override void UpdateVars()
{
baseConfigurationReference = GetPropertyString("baseConfigurationReference");
entries = new SortedDictionary<string, BuildConfigEntryData>();
if (m_Properties.Contains("buildSettings"))
{
var dict = m_Properties["buildSettings"].AsDict();
foreach (var key in dict.values.Keys)
{
var value = dict[key];
if (value is PBXElementString)
{
if (entries.ContainsKey(key))
entries[key].val.Add(value.AsString());
else
entries.Add(key, BuildConfigEntryData.FromNameValue(key, value.AsString()));
}
else if (value is PBXElementArray)
{
foreach (var pvalue in value.AsArray().values)
{
if (pvalue is PBXElementString)
{
if (entries.ContainsKey(key))
entries[key].val.Add(pvalue.AsString());
else
entries.Add(key, BuildConfigEntryData.FromNameValue(key, pvalue.AsString()));
}
}
}
}
}
}
}
internal class PBXContainerItemProxyData : PBXObjectData
{
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"containerPortal/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public static PBXContainerItemProxyData Create(string containerRef, string proxyType,
string remoteGlobalGUID, string remoteInfo)
{
var res = new PBXContainerItemProxyData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXContainerItemProxy");
res.SetPropertyString("containerPortal", containerRef); // guid
res.SetPropertyString("proxyType", proxyType);
res.SetPropertyString("remoteGlobalIDString", remoteGlobalGUID); // guid
res.SetPropertyString("remoteInfo", remoteInfo);
return res;
}
}
internal class PBXReferenceProxyData : PBXObjectData
{
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"remoteRef/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public string path { get { return GetPropertyString("path"); } }
public static PBXReferenceProxyData Create(string path, string fileType,
string remoteRef, string sourceTree)
{
var res = new PBXReferenceProxyData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXReferenceProxy");
res.SetPropertyString("path", path);
res.SetPropertyString("fileType", fileType);
res.SetPropertyString("remoteRef", remoteRef);
res.SetPropertyString("sourceTree", sourceTree);
return res;
}
}
internal class PBXTargetDependencyData : PBXObjectData
{
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"target/*",
"targetProxy/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public static PBXTargetDependencyData Create(string target, string targetProxy)
{
var res = new PBXTargetDependencyData();
res.guid = PBXGUID.Generate();
res.SetPropertyString("isa", "PBXTargetDependency");
res.SetPropertyString("target", target);
res.SetPropertyString("targetProxy", targetProxy);
return res;
}
}
internal class ProjectReference
{
public string group; // guid
public string projectRef; // guid
public static ProjectReference Create(string group, string projectRef)
{
var res = new ProjectReference();
res.group = group;
res.projectRef = projectRef;
return res;
}
}
internal class PBXProjectObjectData : PBXObjectData
{
private static PropertyCommentChecker checkerData = new PropertyCommentChecker(new string[]{
"buildConfigurationList/*",
"mainGroup/*",
"projectReferences/*/ProductGroup/*",
"projectReferences/*/ProjectRef/*",
"targets/*"
});
internal override PropertyCommentChecker checker { get { return checkerData; } }
public List<ProjectReference> projectReferences = new List<ProjectReference>();
public string mainGroup { get { return GetPropertyString("mainGroup"); } }
public List<string> targets = new List<string>();
public List<string> knownAssetTags = new List<string>();
public List<string> knownRegions = new List<string>();
public string buildConfigList;
// the name of the entitlements file required for some capabilities.
public string entitlementsFile;
public List<PBXCapabilityType.TargetCapabilityPair> capabilities = new List<PBXCapabilityType.TargetCapabilityPair>();
public Dictionary<string, string> teamIDs = new Dictionary<string, string>();
public void AddReference(string productGroup, string projectRef)
{
projectReferences.Add(ProjectReference.Create(productGroup, projectRef));
}
public override void UpdateProps()
{
m_Properties.values.Remove("projectReferences");
if (projectReferences.Count > 0)
{
var array = m_Properties.CreateArray("projectReferences");
foreach (var value in projectReferences)
{
var dict = array.AddDict();
dict.SetString("ProductGroup", value.group);
dict.SetString("ProjectRef", value.projectRef);
}
};
SetPropertyList("targets", targets);
SetPropertyList("knownRegions", knownRegions);
SetPropertyString("buildConfigurationList", buildConfigList);
if (knownAssetTags.Count > 0)
{
PBXElementDict attrs;
if (m_Properties.Contains("attributes"))
attrs = m_Properties["attributes"].AsDict();
else
attrs = m_Properties.CreateDict("attributes");
var tags = attrs.CreateArray("knownAssetTags");
foreach (var tag in knownAssetTags)
tags.AddString(tag);
}
// Enable the capabilities.
foreach (var cap in capabilities)
{
var attrs = m_Properties.Contains("attributes") ? m_Properties["attributes"].AsDict() : m_Properties.CreateDict("attributes");
var targAttr = attrs.Contains("TargetAttributes") ? attrs["TargetAttributes"].AsDict() : attrs.CreateDict("TargetAttributes");
var target = targAttr.Contains(cap.targetGuid) ? targAttr[cap.targetGuid].AsDict() : targAttr.CreateDict(cap.targetGuid);
var sysCap = target.Contains("SystemCapabilities") ? target["SystemCapabilities"].AsDict() : target.CreateDict("SystemCapabilities");
var capabilityId = cap.capability.id;
var currentCapability = sysCap.Contains(capabilityId) ? sysCap[capabilityId].AsDict() : sysCap.CreateDict(capabilityId);
currentCapability.SetString("enabled", "1");
}
// Set the team id
foreach (KeyValuePair<string, string> teamID in teamIDs)
{
var attrs = m_Properties.Contains("attributes") ? m_Properties["attributes"].AsDict() : m_Properties.CreateDict("attributes");
var targAttr = attrs.Contains("TargetAttributes") ? attrs["TargetAttributes"].AsDict() : attrs.CreateDict("TargetAttributes");
var target = targAttr.Contains(teamID.Key) ? targAttr[teamID.Key].AsDict() : targAttr.CreateDict(teamID.Key);
target.SetString("DevelopmentTeam", teamID.Value);
}
}
public override void UpdateVars()
{
projectReferences = new List<ProjectReference>();
if (m_Properties.Contains("projectReferences"))
{
var el = m_Properties["projectReferences"].AsArray();
foreach (var value in el.values)
{
PBXElementDict dict = value.AsDict();
if (dict.Contains("ProductGroup") && dict.Contains("ProjectRef"))
{
string group = dict["ProductGroup"].AsString();
string projectRef = dict["ProjectRef"].AsString();
projectReferences.Add(ProjectReference.Create(group, projectRef));
}
}
}
targets = GetPropertyList("targets");
knownRegions = GetPropertyList("knownRegions");
buildConfigList = GetPropertyString("buildConfigurationList");
// update knownAssetTags
knownAssetTags = new List<string>();
if (m_Properties.Contains("attributes"))
{
var el = m_Properties["attributes"].AsDict();
if (el.Contains("knownAssetTags"))
{
var tags = el["knownAssetTags"].AsArray();
foreach (var tag in tags.values)
knownAssetTags.Add(tag.AsString());
}
capabilities = new List<PBXCapabilityType.TargetCapabilityPair>();
teamIDs = new Dictionary<string, string>();
if (el.Contains("TargetAttributes"))
{
var targetAttr = el["TargetAttributes"].AsDict();
foreach (var attr in targetAttr.values)
{
if (attr.Key == "DevelopmentTeam")
{
teamIDs.Add(attr.Key, attr.Value.AsString());
}
if (attr.Key == "SystemCapabilities")
{
var caps = el["SystemCapabilities"].AsDict();
foreach (var cap in caps.values)
capabilities.Add(new PBXCapabilityType.TargetCapabilityPair(attr.Key, PBXCapabilityType.StringToPBXCapabilityType(cap.Value.AsString())));
}
}
}
}
}
}
} // namespace UnityModule.iOS.Xcode