aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/ExtensibilityServices
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-04-05 12:55:26 -0700
committerRob Mensching <rob@firegiant.com>2021-04-06 16:10:05 -0700
commit860f77f7c9d522074dc7e44cfe11281efd20687f (patch)
tree49527e82264f2dac88247885e937f935ae2ac658 /src/WixToolset.Core/ExtensibilityServices
parent94db5671e85ce63487e3a415251cad0eb6abe3d1 (diff)
downloadwix-860f77f7c9d522074dc7e44cfe11281efd20687f.tar.gz
wix-860f77f7c9d522074dc7e44cfe11281efd20687f.tar.bz2
wix-860f77f7c9d522074dc7e44cfe11281efd20687f.zip
Introduce "Subdirectory" which simplifies inline directory syntax
Completes wixtoolset/issues#4727
Diffstat (limited to 'src/WixToolset.Core/ExtensibilityServices')
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs126
1 files changed, 23 insertions, 103 deletions
diff --git a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
index a9a0fa9d..4b7b5ca4 100644
--- a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+++ b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
@@ -18,8 +18,6 @@ namespace WixToolset.Core.ExtensibilityServices
18 18
19 internal class ParseHelper : IParseHelper 19 internal class ParseHelper : IParseHelper
20 { 20 {
21 private static readonly char[] InlineDirectorySeparators = new char[] { ':', '\\', '/' };
22
23 public ParseHelper(IServiceProvider serviceProvider) 21 public ParseHelper(IServiceProvider serviceProvider)
24 { 22 {
25 this.ServiceProvider = serviceProvider; 23 this.ServiceProvider = serviceProvider;
@@ -56,12 +54,9 @@ namespace WixToolset.Core.ExtensibilityServices
56 54
57 public Identifier CreateDirectorySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null) 55 public Identifier CreateDirectorySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null)
58 { 56 {
59 // For anonymous directories, create the identifier. If this identifier already exists in the
60 // active section, bail so we don't add duplicate anonymous directory symbols (which are legal
61 // but bloat the intermediate and ultimately make the linker do "busy work").
62 if (null == id) 57 if (null == id)
63 { 58 {
64 id = this.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName); 59 id = this.CreateIdentifier("d", parentId, name, shortName, sourceName, shortSourceName);
65 } 60 }
66 61
67 var symbol = section.AddSymbol(new DirectorySymbol(sourceLineNumbers, id) 62 var symbol = section.AddSymbol(new DirectorySymbol(sourceLineNumbers, id)
@@ -78,28 +73,37 @@ namespace WixToolset.Core.ExtensibilityServices
78 73
79 public string CreateDirectoryReferenceFromInlineSyntax(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId, string inlineSyntax, IDictionary<string, string> sectionCachedInlinedDirectoryIds) 74 public string CreateDirectoryReferenceFromInlineSyntax(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId, string inlineSyntax, IDictionary<string, string> sectionCachedInlinedDirectoryIds)
80 { 75 {
81 if (String.IsNullOrEmpty(inlineSyntax)) 76 if (String.IsNullOrEmpty(parentId))
82 { 77 {
83 inlineSyntax = attribute.Value; 78 throw new ArgumentNullException(nameof(parentId));
84 } 79 }
85 80
86 // If no separator is found, the string is a simple reference. 81 if (String.IsNullOrEmpty(inlineSyntax))
87 var separatorFound = inlineSyntax.IndexOfAny(InlineDirectorySeparators);
88 if (separatorFound == -1)
89 { 82 {
90 this.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, inlineSyntax); 83 inlineSyntax = this.GetAttributeLongFilename(sourceLineNumbers, attribute, false, true);
91 return inlineSyntax;
92 } 84 }
93 85
94 // If a parent id was provided and the inline syntax does not start with a directory reference, prepend the parent id. 86 if (String.IsNullOrEmpty(inlineSyntax))
95 if (!String.IsNullOrEmpty(parentId) && inlineSyntax[separatorFound] != ':')
96 { 87 {
97 inlineSyntax = String.Concat(parentId, ":", inlineSyntax); 88 return parentId;
98 } 89 }
99 90
100 inlineSyntax = inlineSyntax.TrimEnd('\\', '/'); 91 inlineSyntax = inlineSyntax.Trim('\\', '/');
92
93 var cacheKey = String.Concat(parentId, ":", inlineSyntax);
94
95 if (!sectionCachedInlinedDirectoryIds.TryGetValue(cacheKey, out var id))
96 {
97 var identifier = this.CreateDirectorySymbol(section, sourceLineNumbers, id: null, parentId, inlineSyntax);
98
99 id = identifier.Id;
100 }
101 else
102 {
103 this.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, id);
104 }
101 105
102 return this.ParseInlineSyntax(section, sourceLineNumbers, attribute, inlineSyntax, sectionCachedInlinedDirectoryIds); 106 return id; //this.ParseInlineSyntax(section, sourceLineNumbers, attribute, inlineSyntax, sectionCachedInlinedDirectoryIds);
103 } 107 }
104 108
105 public string CreateGuid(Guid namespaceGuid, string value) 109 public string CreateGuid(Guid namespaceGuid, string value)
@@ -444,7 +448,7 @@ namespace WixToolset.Core.ExtensibilityServices
444 448
445 var value = this.GetAttributeValue(sourceLineNumbers, attribute); 449 var value = this.GetAttributeValue(sourceLineNumbers, attribute);
446 450
447 if (0 < value.Length) 451 if (!String.IsNullOrEmpty(value))
448 { 452 {
449 if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value)) 453 if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value))
450 { 454 {
@@ -840,90 +844,6 @@ namespace WixToolset.Core.ExtensibilityServices
840 this.Creator = this.ServiceProvider.GetService<ISymbolDefinitionCreator>(); 844 this.Creator = this.ServiceProvider.GetService<ISymbolDefinitionCreator>();
841 } 845 }
842 846
843 private string ParseInlineSyntax(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string inlineSyntax, IDictionary<string, string> sectionCachedInlinedDirectoryIds)
844 {
845 if (!sectionCachedInlinedDirectoryIds.TryGetValue(inlineSyntax, out var id))
846 {
847 string parentId;
848 int nameIndex;
849
850 var separatorIndex = inlineSyntax.LastIndexOfAny(InlineDirectorySeparators);
851 if (separatorIndex == -1)
852 {
853 nameIndex = 0;
854 parentId = "TARGETDIR";
855 }
856 else if (inlineSyntax[separatorIndex] == '\\' || inlineSyntax[separatorIndex] == '/')
857 {
858 nameIndex = separatorIndex + 1;
859
860 if (separatorIndex == 0)
861 {
862 parentId = "TARGETDIR";
863 }
864 else if (inlineSyntax[separatorIndex - 1] == ':')
865 {
866 parentId = this.ParseParentReference(section, sourceLineNumbers, attribute, inlineSyntax, separatorIndex - 1);
867 }
868 else
869 {
870 var parentInlineDirectory = inlineSyntax.Substring(0, separatorIndex);
871 parentId = this.ParseInlineSyntax(section, sourceLineNumbers, attribute, parentInlineDirectory.TrimEnd('\\', '/'), sectionCachedInlinedDirectoryIds);
872 }
873 }
874 else
875 {
876 nameIndex = separatorIndex + 1;
877 parentId = this.ParseParentReference(section, sourceLineNumbers, attribute, inlineSyntax, separatorIndex);
878 }
879
880 if (nameIndex == inlineSyntax.Length)
881 {
882 id = parentId;
883 }
884 else
885 {
886 var name = nameIndex != -1 ? inlineSyntax.Substring(nameIndex) : null;
887
888 if (!this.IsValidLongFilename(name, false, false))
889 {
890 this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, attribute.Value, name));
891 return null;
892 }
893
894 var identifier = this.CreateDirectorySymbol(section, sourceLineNumbers, null, parentId, name);
895
896 id = identifier.Id;
897 }
898
899 sectionCachedInlinedDirectoryIds.Add(inlineSyntax, id);
900 }
901
902 return id;
903 }
904
905 private string ParseParentReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string reference, int colonIndex)
906 {
907 if (colonIndex == 0)
908 {
909 this.Messaging.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, attribute.Value, String.Empty));
910 return null;
911 }
912 else
913 {
914 var parentId = reference.Substring(0, colonIndex);
915
916 if (!Common.IsIdentifier(parentId))
917 {
918 this.Messaging.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, attribute.Value, parentId));
919 return null;
920 }
921
922 this.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, parentId);
923 return parentId;
924 }
925 }
926
927 private static bool TryFindExtension(IEnumerable<ICompilerExtension> extensions, XNamespace ns, out ICompilerExtension extension) 847 private static bool TryFindExtension(IEnumerable<ICompilerExtension> extensions, XNamespace ns, out ICompilerExtension extension)
928 { 848 {
929 extension = null; 849 extension = null;