aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Compiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Compiler.cs')
-rw-r--r--src/WixToolset.Core/Compiler.cs275
1 files changed, 162 insertions, 113 deletions
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index 32e9b9d6..35a73e00 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -8,6 +8,7 @@ namespace WixToolset.Core
8 using System.Diagnostics.CodeAnalysis; 8 using System.Diagnostics.CodeAnalysis;
9 using System.Globalization; 9 using System.Globalization;
10 using System.IO; 10 using System.IO;
11 using System.Linq;
11 using System.Text.RegularExpressions; 12 using System.Text.RegularExpressions;
12 using System.Xml.Linq; 13 using System.Xml.Linq;
13 using WixToolset.Data; 14 using WixToolset.Data;
@@ -3667,20 +3668,8 @@ namespace WixToolset.Core
3667 { 3668 {
3668 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 3669 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
3669 string tableId = null; 3670 string tableId = null;
3670 3671 var unreal = false;
3671 string categories = null; 3672 var columns = new List<WixCustomTableColumnTuple>();
3672 var columnCount = 0;
3673 string columnNames = null;
3674 string columnTypes = null;
3675 string descriptions = null;
3676 string keyColumns = null;
3677 string keyTables = null;
3678 string maxValues = null;
3679 string minValues = null;
3680 string modularizations = null;
3681 string primaryKeys = null;
3682 string sets = null;
3683 var bootstrapperApplicationData = false;
3684 3673
3685 foreach (var attrib in node.Attributes()) 3674 foreach (var attrib in node.Attributes())
3686 { 3675 {
@@ -3692,7 +3681,7 @@ namespace WixToolset.Core
3692 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3681 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3693 break; 3682 break;
3694 case "Unreal": 3683 case "Unreal":
3695 bootstrapperApplicationData = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 3684 unreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3696 break; 3685 break;
3697 default: 3686 default:
3698 this.Core.UnexpectedAttribute(node, attrib); 3687 this.Core.UnexpectedAttribute(node, attrib);
@@ -3722,22 +3711,20 @@ namespace WixToolset.Core
3722 switch (child.Name.LocalName) 3711 switch (child.Name.LocalName)
3723 { 3712 {
3724 case "Column": 3713 case "Column":
3725 ++columnCount;
3726
3727 var category = String.Empty;
3728 string columnName = null; 3714 string columnName = null;
3729 string columnType = null; 3715 var category = String.Empty;
3716 IntermediateFieldType? columnType = null;
3730 var description = String.Empty; 3717 var description = String.Empty;
3731 var keyColumn = CompilerConstants.IntegerNotSet; 3718 int? keyColumn = null;
3732 var keyTable = String.Empty; 3719 var keyTable = String.Empty;
3733 var localizable = false; 3720 var localizable = false;
3734 var maxValue = CompilerConstants.LongNotSet; 3721 long? maxValue = null;
3735 var minValue = CompilerConstants.LongNotSet; 3722 long? minValue = null;
3736 var modularization = "None"; 3723 var modularization = WixCustomTableColumnModularizeType.None;
3737 var nullable = false; 3724 var nullable = false;
3738 var primaryKey = false; 3725 var primaryKey = false;
3739 var setValues = String.Empty; 3726 var setValues = String.Empty;
3740 string typeName = null; 3727 var columnUnreal = false;
3741 var width = 0; 3728 var width = 0;
3742 3729
3743 foreach (var childAttrib in child.Attributes()) 3730 foreach (var childAttrib in child.Attributes())
@@ -3769,7 +3756,43 @@ namespace WixToolset.Core
3769 minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue); 3756 minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue);
3770 break; 3757 break;
3771 case "Modularize": 3758 case "Modularize":
3772 modularization = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3759 var modularizeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3760 switch (modularizeValue)
3761 {
3762 case "column":
3763 modularization = WixCustomTableColumnModularizeType.Column;
3764 break;
3765 case "companionFile":
3766 modularization = WixCustomTableColumnModularizeType.CompanionFile;
3767 break;
3768 case "condition":
3769 modularization = WixCustomTableColumnModularizeType.Condition;
3770 break;
3771 case "controlEventArgument":
3772 modularization = WixCustomTableColumnModularizeType.ControlEventArgument;
3773 break;
3774 case "controlText":
3775 modularization = WixCustomTableColumnModularizeType.ControlText;
3776 break;
3777 case "icon":
3778 modularization = WixCustomTableColumnModularizeType.Icon;
3779 break;
3780 case "none":
3781 modularization = WixCustomTableColumnModularizeType.None;
3782 break;
3783 case "property":
3784 modularization = WixCustomTableColumnModularizeType.Property;
3785 break;
3786 case "semicolonDelimited":
3787 modularization = WixCustomTableColumnModularizeType.SemicolonDelimited;
3788 break;
3789 case "":
3790 break;
3791 default:
3792 this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Modularize", modularizeValue, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited"));
3793 columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3794 break;
3795 }
3773 break; 3796 break;
3774 case "Nullable": 3797 case "Nullable":
3775 nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3798 nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
@@ -3785,24 +3808,28 @@ namespace WixToolset.Core
3785 switch (typeValue) 3808 switch (typeValue)
3786 { 3809 {
3787 case "binary": 3810 case "binary":
3788 typeName = "OBJECT"; 3811 columnType = IntermediateFieldType.Path;
3789 break; 3812 break;
3790 case "int": 3813 case "int":
3791 typeName = "SHORT"; 3814 columnType = IntermediateFieldType.Number;
3792 break; 3815 break;
3793 case "string": 3816 case "string":
3794 typeName = "CHAR"; 3817 columnType = IntermediateFieldType.String;
3795 break; 3818 break;
3796 case "": 3819 case "":
3797 break; 3820 break;
3798 default: 3821 default:
3799 this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string")); 3822 this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string"));
3823 columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below.
3800 break; 3824 break;
3801 } 3825 }
3802 break; 3826 break;
3803 case "Width": 3827 case "Width":
3804 width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue); 3828 width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue);
3805 break; 3829 break;
3830 case "Unreal":
3831 columnUnreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3832 break;
3806 default: 3833 default:
3807 this.Core.UnexpectedAttribute(child, childAttrib); 3834 this.Core.UnexpectedAttribute(child, childAttrib);
3808 break; 3835 break;
@@ -3814,100 +3841,59 @@ namespace WixToolset.Core
3814 this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id")); 3841 this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id"));
3815 } 3842 }
3816 3843
3817 if (null == typeName) 3844 if (!columnType.HasValue)
3818 { 3845 {
3819 this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type")); 3846 this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type"));
3820 } 3847 }
3821 else if ("SHORT" == typeName) 3848 else if (columnType == IntermediateFieldType.Number)
3822 { 3849 {
3823 if (2 != width && 4 != width) 3850 if (2 != width && 4 != width)
3824 { 3851 {
3825 this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width)); 3852 this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width));
3826 } 3853 }
3827 columnType = String.Concat(nullable ? "I" : "i", width);
3828 } 3854 }
3829 else if ("CHAR" == typeName) 3855 else if (columnType == IntermediateFieldType.Path)
3830 { 3856 {
3831 var typeChar = localizable ? "l" : "s"; 3857 if (String.IsNullOrEmpty(category))
3832 columnType = String.Concat(nullable ? typeChar.ToUpper(CultureInfo.InvariantCulture) : typeChar.ToLower(CultureInfo.InvariantCulture), width);
3833 }
3834 else if ("OBJECT" == typeName)
3835 {
3836 if ("Binary" != category)
3837 { 3858 {
3838 this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers)); 3859 category = "Binary";
3839 } 3860 }
3840 columnType = String.Concat(nullable ? "V" : "v", width); 3861 else if (category != "Binary")
3841 }
3842
3843 this.Core.ParseForExtensionElements(child);
3844
3845 columnNames = String.Concat(columnNames, null == columnNames ? String.Empty : "\t", columnName);
3846 columnTypes = String.Concat(columnTypes, null == columnTypes ? String.Empty : "\t", columnType);
3847 if (primaryKey)
3848 {
3849 primaryKeys = String.Concat(primaryKeys, null == primaryKeys ? String.Empty : "\t", columnName);
3850 }
3851
3852 minValues = String.Concat(minValues, null == minValues ? String.Empty : "\t", CompilerConstants.LongNotSet != minValue ? minValue.ToString(CultureInfo.InvariantCulture) : String.Empty);
3853 maxValues = String.Concat(maxValues, null == maxValues ? String.Empty : "\t", CompilerConstants.LongNotSet != maxValue ? maxValue.ToString(CultureInfo.InvariantCulture) : String.Empty);
3854 keyTables = String.Concat(keyTables, null == keyTables ? String.Empty : "\t", keyTable);
3855 keyColumns = String.Concat(keyColumns, null == keyColumns ? String.Empty : "\t", CompilerConstants.IntegerNotSet != keyColumn ? keyColumn.ToString(CultureInfo.InvariantCulture) : String.Empty);
3856 categories = String.Concat(categories, null == categories ? String.Empty : "\t", category);
3857 sets = String.Concat(sets, null == sets ? String.Empty : "\t", setValues);
3858 descriptions = String.Concat(descriptions, null == descriptions ? String.Empty : "\t", description);
3859 modularizations = String.Concat(modularizations, null == modularizations ? String.Empty : "\t", modularization);
3860
3861 break;
3862 case "Row":
3863 string dataValue = null;
3864
3865 foreach (var childAttrib in child.Attributes())
3866 {
3867 this.Core.ParseExtensionAttribute(child, childAttrib);
3868 }
3869
3870 foreach (var data in child.Elements())
3871 {
3872 var dataSourceLineNumbers = Preprocessor.GetSourceLineNumbers(data);
3873 switch (data.Name.LocalName)
3874 { 3862 {
3875 case "Data": 3863 this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers));
3876 columnName = null;
3877 foreach (var dataAttrib in data.Attributes())
3878 {
3879 switch (dataAttrib.Name.LocalName)
3880 {
3881 case "Column":
3882 columnName = this.Core.GetAttributeValue(dataSourceLineNumbers, dataAttrib);
3883 break;
3884 default:
3885 this.Core.UnexpectedAttribute(data, dataAttrib);
3886 break;
3887 }
3888 }
3889
3890 if (null == columnName)
3891 {
3892 this.Core.Write(ErrorMessages.ExpectedAttribute(dataSourceLineNumbers, data.Name.LocalName, "Column"));
3893 }
3894
3895 dataValue = String.Concat(dataValue, null == dataValue ? String.Empty : WixCustomRowTuple.FieldSeparator.ToString(), columnName, ":", Common.GetInnerText(data));
3896 break;
3897 } 3864 }
3898 } 3865 }
3899 3866
3900 this.Core.CreateSimpleReference(sourceLineNumbers, TupleDefinitions.WixCustomTable, tableId); 3867 this.Core.ParseForExtensionElements(child);
3901 3868
3902 if (!this.Core.EncounteredError) 3869 if (!this.Core.EncounteredError)
3903 { 3870 {
3904 this.Core.AddTuple(new WixCustomRowTuple(childSourceLineNumbers) 3871 var attributes = primaryKey ? WixCustomTableColumnTupleAttributes.PrimaryKey : WixCustomTableColumnTupleAttributes.None;
3872 attributes |= localizable ? WixCustomTableColumnTupleAttributes.Localizable : WixCustomTableColumnTupleAttributes.None;
3873 attributes |= nullable ? WixCustomTableColumnTupleAttributes.Nullable : WixCustomTableColumnTupleAttributes.None;
3874 attributes |= columnUnreal ? WixCustomTableColumnTupleAttributes.Unreal : WixCustomTableColumnTupleAttributes.None;
3875
3876 columns.Add(new WixCustomTableColumnTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, columnName))
3905 { 3877 {
3906 Table = tableId, 3878 TableRef = tableId,
3907 FieldData = dataValue, 3879 Name = columnName,
3880 Type = columnType.Value,
3881 Attributes = attributes,
3882 Width = width,
3883 Category = category,
3884 Description = description,
3885 KeyColumn = keyColumn,
3886 KeyTable = keyTable,
3887 MaxValue = maxValue,
3888 MinValue = minValue,
3889 Modularize = modularization,
3890 Set = setValues,
3908 }); 3891 });
3909 } 3892 }
3910 break; 3893 break;
3894 case "Row":
3895 this.ParseRow(child, tableId);
3896 break;
3911 default: 3897 default:
3912 this.Core.UnexpectedElement(node, child); 3898 this.Core.UnexpectedElement(node, child);
3913 break; 3899 break;
@@ -3919,35 +3905,98 @@ namespace WixToolset.Core
3919 } 3905 }
3920 } 3906 }
3921 3907
3922 if (0 < columnCount) 3908 if (columns.Count > 0)
3923 { 3909 {
3924 if (null == primaryKeys || 0 == primaryKeys.Length) 3910 if (!columns.Where(c => c.PrimaryKey).Any())
3925 { 3911 {
3926 this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers)); 3912 this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers));
3927 } 3913 }
3928 3914
3929 if (!this.Core.EncounteredError) 3915 if (!this.Core.EncounteredError)
3930 { 3916 {
3917 var columnNames = String.Join(new string(WixCustomTableTuple.ColumnNamesSeparator, 1), columns.Select(c => c.Name));
3918
3931 this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId)) 3919 this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId))
3932 { 3920 {
3933 ColumnCount = columnCount,
3934 ColumnNames = columnNames, 3921 ColumnNames = columnNames,
3935 ColumnTypes = columnTypes, 3922 Unreal = unreal,
3936 PrimaryKeys = primaryKeys,
3937 MinValues = minValues,
3938 MaxValues = maxValues,
3939 KeyTables = keyTables,
3940 KeyColumns = keyColumns,
3941 Categories = categories,
3942 Sets = sets,
3943 Descriptions = descriptions,
3944 Modularizations = modularizations,
3945 Unreal = bootstrapperApplicationData,
3946 }); 3923 });
3924
3925 foreach (var column in columns)
3926 {
3927 this.Core.AddTuple(column);
3928 }
3947 } 3929 }
3948 } 3930 }
3949 } 3931 }
3950 3932
3933 private void ParseRow(XElement node, string tableId)
3934 {
3935 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
3936 var rowId = Guid.NewGuid().ToString("N").ToUpperInvariant();
3937
3938 foreach (var attrib in node.Attributes())
3939 {
3940 this.Core.ParseExtensionAttribute(node, attrib);
3941 }
3942
3943 foreach (var child in node.Elements())
3944 {
3945 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
3946 switch (child.Name.LocalName)
3947 {
3948 case "Data":
3949 string columnName = null;
3950 string data = null;
3951 foreach (var attrib in child.Attributes())
3952 {
3953 switch (attrib.Name.LocalName)
3954 {
3955 case "Column":
3956 columnName = this.Core.GetAttributeValue(childSourceLineNumbers, attrib);
3957 break;
3958 case "Value":
3959 data = this.Core.GetAttributeValue(childSourceLineNumbers, attrib);
3960 break;
3961 default:
3962 this.Core.ParseExtensionAttribute(child, attrib);
3963 break;
3964 }
3965 }
3966
3967 if (null == columnName)
3968 {
3969 this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Column"));
3970 }
3971
3972 if (String.IsNullOrEmpty(data))
3973 {
3974 data = Common.GetInnerText(child);
3975 }
3976
3977 if (!this.Core.EncounteredError)
3978 {
3979 this.Core.AddTuple(new WixCustomTableCellTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, rowId, columnName))
3980 {
3981 RowId = rowId,
3982 ColumnRef = columnName,
3983 TableRef = tableId,
3984 Data = data
3985 });
3986 }
3987 break;
3988 default:
3989 this.Core.UnexpectedElement(node, child);
3990 break;
3991 }
3992 }
3993
3994 if (!this.Core.EncounteredError)
3995 {
3996 this.Core.CreateSimpleReference(sourceLineNumbers, TupleDefinitions.WixCustomTable, tableId);
3997 }
3998 }
3999
3951 /// <summary> 4000 /// <summary>
3952 /// Parses a directory element. 4001 /// Parses a directory element.
3953 /// </summary> 4002 /// </summary>