/// <summary> /// Parses a Condition element for Bundles. /// </summary> /// <param name="node">The element to parse.</param> private void ParseConditionElement(XElement node) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string condition = CompilerCore.GetConditionInnerText(node); // condition is the inner text of the element. string message = null; foreach (XAttribute attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Message": message = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } this.Core.ParseForExtensionElements(node); // Error check the values. if (String.IsNullOrEmpty(condition)) { this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, node.Name.LocalName)); } if (null == message) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message")); } if (!this.Core.EncounteredError) { Row row = this.Core.CreateRow(sourceLineNumbers, "WixBalCondition"); row[0] = condition; row[1] = message; if (null == this.addedConditionLineNumber) { this.addedConditionLineNumber = sourceLineNumbers; } } }
/// <summary> /// Parses a Condition element for Bundles. /// </summary> /// <param name="node">The element to parse.</param> private void ParseConditionElement(XmlNode node) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string condition = CompilerCore.GetConditionInnerText(node); // condition is the inner text of the element. string message = null; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "Message": message = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib); } } foreach (XmlNode child in node.ChildNodes) { if (XmlNodeType.Element == child.NodeType) { if (child.NamespaceURI == this.schema.TargetNamespace) { this.Core.UnexpectedElement(node, child); } else { this.Core.UnsupportedExtensionElement(node, child); } } } // Error check the values. if (String.IsNullOrEmpty(condition)) { this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, node.Name)); } if (null == message) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Message")); } if (!this.Core.EncounteredError) { Row row = this.Core.CreateRow(sourceLineNumbers, "WixBalCondition"); row[0] = condition; row[1] = message; if (null == this.addedConditionLineNumber) { this.addedConditionLineNumber = sourceLineNumbers; } } }
/// <summary> /// Parses a UnitTest element to create Lux unit tests. /// </summary> /// <param name="node">The element to parse.</param> /// <param name="args">Used while parsing multi-value property tests to pass values from the parent element.</param> private void ParseUnitTestElement(XmlNode node, string mutation, params string[] args) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); bool multiValue = 0 < args.Length; string id = null; string action = multiValue ? args[0] : null; string property = multiValue ? args[1] : null; string op = null; Operator oper = Operator.NotSet; string value = null; string expression = null; string valueSep = multiValue ? args[2] : null; string nameValueSep = multiValue ? args[3] : null; string condition = null; string index = null; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "CustomAction": case "Property": case "Expression": case "ValueSeparator": case "NameValueSeparator": if (multiValue) { this.Core.OnMessage(LuxErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.LocalName, attrib.LocalName)); } break; } switch (attrib.LocalName) { case "Id": id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "CustomAction": action = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "Property": property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "Operator": op = this.Core.GetAttributeValue(sourceLineNumbers, attrib); if (0 < op.Length) { switch (op) { case "equal": oper = Operator.Equal; break; case "notEqual": oper = Operator.NotEqual; break; case "caseInsensitiveEqual": oper = Operator.CaseInsensitiveEqual; break; case "caseInsensitiveNotEqual": oper = Operator.CaseInsensitiveNotEqual; break; default: this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.LocalName, attrib.LocalName, op, "equal", "notEqual", "caseInsensitiveEqual", "caseInsensitiveNotEqual")); break; } } break; case "Value": value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "ValueSeparator": valueSep = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "NameValueSeparator": nameValueSep = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Index": if (!multiValue) { this.Core.OnMessage(LuxErrors.IllegalAttributeWhenNotNested(sourceLineNumbers, node.LocalName, attrib.LocalName)); } index = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib); } } bool isParent = false; foreach (XmlNode child in node.ChildNodes) { if (XmlNodeType.Element == child.NodeType) { if (child.NamespaceURI == this.schema.TargetNamespace) { switch (child.LocalName) { case "Condition": // the condition should not be empty condition = CompilerCore.GetConditionInnerText(child); if (null == condition || 0 == condition.Length) { condition = null; this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, child.Name)); } break; case "Expression": // the expression should not be empty expression = CompilerCore.GetConditionInnerText(child); if (null == expression || 0 == expression.Length) { expression = null; this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, child.Name)); } break; case "UnitTest": if (multiValue) { SourceLineNumberCollection childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); this.Core.OnMessage(LuxErrors.ElementTooDeep(childSourceLineNumbers, child.LocalName, node.LocalName)); } this.ParseUnitTestElement(child, mutation, action, property, valueSep, nameValueSep); isParent = true; break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.UnsupportedExtensionElement(node, child); } } } if (isParent) { if (!String.IsNullOrEmpty(value)) { this.Core.OnMessage(LuxErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.LocalName, "Value")); } } else { // the children generate multi-value unit test rows; the parent doesn't generate anything if (!String.IsNullOrEmpty(property) && String.IsNullOrEmpty(value)) { this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.LocalName, "Property", "Value")); } if (!String.IsNullOrEmpty(property) && !String.IsNullOrEmpty(expression)) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.LocalName, "Property", "Expression")); } if (multiValue && String.IsNullOrEmpty(valueSep) && String.IsNullOrEmpty(nameValueSep)) { this.Core.OnMessage(LuxErrors.MissingRequiredParentAttribute(sourceLineNumbers, node.LocalName, "ValueSeparator", "NameValueSeparator")); } if (!String.IsNullOrEmpty(valueSep) && !String.IsNullOrEmpty(nameValueSep)) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.LocalName, "ValueSeparator", "NameValueSeparator")); } if (!this.Core.EncounteredError) { if (String.IsNullOrEmpty(id)) { id = this.Core.GenerateIdentifier("lux", action, property, index, condition, mutation); } if (Operator.NotSet == oper) { oper = Operator.Equal; } Row row = this.Core.CreateRow(sourceLineNumbers, "WixUnitTest"); row[0] = id; row[1] = action; row[2] = property; row[3] = (int)oper; row[4] = value; row[5] = expression; row[6] = condition; row[7] = valueSep; row[8] = nameValueSep; row[9] = index; if (!string.IsNullOrEmpty(mutation)) { row[10] = mutation; } this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", action); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixRunImmediateUnitTests"); } } }