diff options
| author | Rob Mensching <rob@firegiant.com> | 2021-04-05 12:55:26 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2021-04-06 16:10:05 -0700 |
| commit | 860f77f7c9d522074dc7e44cfe11281efd20687f (patch) | |
| tree | 49527e82264f2dac88247885e937f935ae2ac658 /src/WixToolset.Core/ExtensibilityServices | |
| parent | 94db5671e85ce63487e3a415251cad0eb6abe3d1 (diff) | |
| download | wix-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.cs | 126 |
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; |
