public IEnumerable<VerificationException> Verify(Library library)
		{
			// Parameters must be validated without access to parameter definitions, or expression definitions
			var initialContext = new VerificationContext(library.Models, library.Libraries, null, null, null, null, null);

			// Resolve parameter types and verify default expressions
			foreach (var parameter in library.Parameters)
			{
				try
				{
					parameter.ParameterType = initialContext.ResolveType(parameter.TypeName);

					if (parameter.Default != null)
					{
						Verifier.Verify(initialContext, parameter.Default);
					    initialContext.VerifyType(parameter.Default.ResultType, parameter.ParameterType);
					}
				}
				catch (Exception e)
				{
					initialContext.ReportMessage(new VerificationException(String.Format("Exceptions occurred verifying parameter {0}.", parameter.Name), e), null);
				}
			}

			var context = new VerificationContext(library.Models, library.Libraries, library.Parameters, library.Expressions, library.CodeSystems, library.ValueSets, initialContext.Messages);

			// Verify expressions
			foreach (var expression in library.Expressions)
			{
				// If the result type is already set, this expression ref has already been resolved.
				if (expression.Expression.ResultType == null)
				{
					Verifier.Verify(context, expression.Expression);
				}
			}

            return context.Messages;
		}
Example #2
0
        public IEnumerable <VerificationException> Verify(Library library)
        {
            // Parameters must be validated without access to parameter definitions, or expression definitions
            var initialContext = new VerificationContext(library.Models, library.Libraries, null, null, null, null, null);

            // Resolve parameter types and verify default expressions
            foreach (var parameter in library.Parameters)
            {
                try
                {
                    parameter.ParameterType = initialContext.ResolveType(parameter.TypeName);

                    if (parameter.Default != null)
                    {
                        Verifier.Verify(initialContext, parameter.Default);
                        initialContext.VerifyType(parameter.Default.ResultType, parameter.ParameterType);
                    }
                }
                catch (Exception e)
                {
                    initialContext.ReportMessage(new VerificationException(String.Format("Exceptions occurred verifying parameter {0}.", parameter.Name), e), null);
                }
            }

            var context = new VerificationContext(library.Models, library.Libraries, library.Parameters, library.Expressions, library.CodeSystems, library.ValueSets, initialContext.Messages);

            // Verify expressions
            foreach (var expression in library.Expressions)
            {
                // If the result type is already set, this expression ref has already been resolved.
                if (expression.Expression.ResultType == null)
                {
                    Verifier.Verify(context, expression.Expression);
                }
            }

            return(context.Messages);
        }
		public void Verify(VerificationContext context, ASTNode node)
		{
			Verifier.Verify(context, node.Children[0]);
			Verifier.Verify(context, node.Children[1]);

			var comparandType = node.Children[0].ResultType;
			context.VerifyType(node.Children[1].ResultType, comparandType);

			node.ResultType = comparandType;
		}
		public void Verify(VerificationContext context, ASTNode node)
		{
			Verifier.Verify(context, node.Children[0]);

			context.VerifyType(node.Children[0].ResultType, DataTypes.Boolean);

			node.ResultType = DataTypes.Boolean;
		}
		public void Verify(VerificationContext context, ASTNode node)
		{
			var comparand = node.Children.FirstOrDefault(n => n.Name == "comparand");

			DataType comparisonType = null;
			if (comparand != null)
			{
				Verifier.Verify(context, comparand);
				comparisonType = comparand.ResultType;
			}
			else
			{
				comparisonType = DataTypes.Boolean;
			}

			DataType resultType = null;

			foreach (var caseItem in ((Node)node).Children.Where(n => n.Name == "caseItem"))
			{
				var when = caseItem.Children[0] as ASTNode;
				var then = caseItem.Children[1] as ASTNode;

				Verifier.Verify(context, when);
				context.VerifyType(when.ResultType, comparisonType);

				Verifier.Verify(context, then);
				if (resultType == null)
				{
					resultType = then.ResultType;
					if (resultType == null)
					{
						throw new InvalidOperationException("Could not determine result type for case expression based on then element of first case item.");
					}
				}
				else
				{
					context.VerifyType(then.ResultType, resultType);
				}
			}

			var elseNode = node.Children.FirstOrDefault(n => n.Name == "else") as ASTNode;
			if (elseNode != null)
			{
				Verifier.Verify(context, elseNode);
				context.VerifyType(elseNode.ResultType, resultType);
			}

			node.ResultType = resultType;
		}
		public void Verify(VerificationContext context, ASTNode node)
		{
			var source = node.Children[0];
			var condition = node.Children[1];

			Verifier.Verify(context, source);
			var sourceListType = source.ResultType as ListType;
			if (sourceListType == null)
			{
				throw new InvalidOperationException("Filter expression source must be a list type expression.");
			}

			context.PushSymbol(new Symbol(node.GetAttribute<string>("scope", VerificationContext.Current), sourceListType.ElementType));
			try
			{
				Verifier.Verify(context, condition);
				context.VerifyType(condition.ResultType, DataTypes.Boolean);
			}
			finally
			{
				context.PopSymbol();
			}

			node.ResultType = sourceListType;
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			var left = node.Children[0];
			var right = node.Children[1];

			var leftIntervalType = left.ResultType as IntervalType;
			if (leftIntervalType != null)
			{
				context.VerifyType(right.ResultType, leftIntervalType);
				node.ResultType = DataTypes.Boolean;
			}
			else
			{
				throw new InvalidOperationException("List type expected.");
			}
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			var source = node.Children[0];
			var index = node.Children[1];

			var sourceListType = source.ResultType as ListType;
			if (sourceListType != null)
			{
				node.ResultType = sourceListType.ElementType;
			}
			else
			{
				context.VerifyType(source.ResultType, DataTypes.String);
				node.ResultType = DataTypes.String;
			}

			context.VerifyType(index.ResultType, DataTypes.Integer);
		}
		protected virtual void InternalVerify(VerificationContext context, ASTNode node, ObjectType dataType)
		{
			// idProperty - If present, must reference a property of type String (or explicitly convertible to string) on the resolved model type.
			var idProperty = node.GetAttribute<string>("idProperty");
			if (!String.IsNullOrEmpty(idProperty))
			{
				var idPropertyType = context.ResolveProperty(dataType, idProperty);
				if (!(DataTypes.Equivalent(idPropertyType, DataTypes.ResolveType(typeof(II))) || DataTypes.Equal(idPropertyType, DataTypes.String)))
				{
					throw new InvalidOperationException("Id property must be either an Identifier or a String.");
				}
			}

			// Validate children
			// timeOffset - If present, must evaluate to a value of type PIVL_TS
			var timeOffset = node.Children.Where(n => n.Name == "timeOffset").FirstOrDefault();
			if (timeOffset != null)
			{
				Verifier.Verify(context, timeOffset);
				context.VerifyType(timeOffset.ResultType, DataTypes.ResolveType(typeof(PIVL_TS)));
			}
		}
        protected override void InternalVerify(VerificationContext context, ASTNode node)
        {
            base.InternalVerify(context, node);

            var numerator = ((Node)node).Children[0];
            var denominator = ((Node)node).Children[1];

            var numeratorType = context.ResolveType(numerator.NodeType);
            var denominatorType = context.ResolveType(denominator.NodeType);

            context.VerifyType(numeratorType, DataTypes.Quantity);
            context.VerifyType(denominatorType, DataTypes.Quantity);

            node.ResultType = DataTypes.ResolveType(typeof(RTO));
        }
		protected override DataType GetResultType(VerificationContext context, ListType listType)
		{
			context.VerifyType(listType.ElementType, DataTypes.Boolean);
			return DataTypes.Boolean;
		}
		public void Verify(VerificationContext context, ASTNode node)
		{
			// objectType
            var objectTypeName = node.GetAttribute<string>("classType");
            if (objectTypeName != null)
            {
			    var objectType = context.ResolveType(node.GetAttribute<string>("classType")) as ObjectType;

			    // foreach property
			    foreach (var child in ((Node)node).Children)
			    {
					if (child.Name == "element") 
					{
						// Verify the property exists
						var childPropertyType = context.ResolveProperty(objectType, child.GetAttribute<string>("name"));

						// Verify the value
						var value = (ASTNode)child.Children[0];
						Verifier.Verify(context, value);

						// Verify the value type is appropriate for the property type
						context.VerifyType(value.ResultType, childPropertyType);
					}
			    }

			    node.ResultType = objectType;
            }
            else
            {
                var propertyList = new List<PropertyDef>();

                foreach (var child in ((Node)node).Children)
                {
					if (child.Name == "element")
					{
						var value = (ASTNode)child.Children[0];
						Verifier.Verify(context, value);

						var property = new PropertyDef(child.GetAttribute<string>("name"), value.ResultType);
						propertyList.Add(property);
					}
                }

                var objectType = new ObjectType(Guid.NewGuid().ToString(), propertyList);

                node.ResultType = objectType;
            }
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			var source = node.Children[0];
			var element = node.Children[1];

			var sourceListType = source.ResultType as ListType;
			if (sourceListType == null)
			{
				throw new InvalidOperationException("List type expected.");
			}

			context.VerifyType(element.ResultType, sourceListType.ElementType);
			node.ResultType = DataTypes.Integer;
		}
        public IEnumerable<VerificationException> Verify(Artifact artifact)
        {
            // Parameters must be validated without access to parameter definitions, or expression definitions
            var initialContext = new VerificationContext(artifact.Models, null, null, null);

            // Resolve parameter types and verify default expressions
            foreach (var parameter in artifact.Parameters)
            {
                try
                {
                    parameter.ParameterType = initialContext.ResolveType(parameter.TypeName);

                    if (parameter.Default != null)
                    {
                        Verifier.Verify(initialContext, parameter.Default);
                        initialContext.VerifyType(parameter.Default.ResultType, parameter.ParameterType);
                    }
                }
                catch (Exception e)
                {
                    initialContext.ReportMessage(new VerificationException(String.Format("Exceptions occurred verifying parameter {0}.", parameter.Name), e), null);
                }
            }

            var context = new VerificationContext(artifact.Models, artifact.Parameters, artifact.Expressions, initialContext.Messages);

            // Verify expressions
            foreach (var expression in artifact.Expressions)
            {
                // If the result type is already set, this expression ref has already been resolved.
                if (expression.Expression.ResultType == null)
                {
                    Verifier.Verify(context, expression.Expression);
                }
            }

            // Verify conditions
            foreach (var condition in artifact.Conditions)
            {
                Verifier.Verify(context, condition);

                if (!DataTypes.Equal(condition.ResultType, DataTypes.Boolean))
                {
                    context.ReportMessage(new InvalidOperationException("Condition must evaluate to a value of type boolean."), condition);
                }
            }

            // Verify trigger expressions
            foreach (var trigger in artifact.Triggers)
            {
                VerifyExpressionNodes(context, trigger);
            }

            // Verify action conditions
            if (artifact.ActionGroup != null)
            {
                var containers = new Dictionary<string, ParameterDef>();

                // Verify documentation template conditions and binding expressions
                VerifyResponseBindings(context, artifact.ActionGroup, containers);

                foreach (var parameter in containers.Values)
                {
                    context.AddParameterDef(parameter);
                }

                VerifyExpressionNodes(context, artifact.ActionGroup);
            }

            return context.Messages;
        }
Example #15
0
        public void Verify(VerificationContext context, HeD.Engine.Model.ASTNode node)
        {
            Symbol sourceSymbol = null;

            // foreach source
                // add to the output context
            var sources = ((Node)node).Children.Where(c => c.Name == "source").ToList();
            foreach (var source in sources)
            {
                if (sourceSymbol == null)
                {
                    sourceSymbol = ProcessAliasedQuerySource(context, source);
                }
                else
                {
                    throw new NotImplementedException("Multi-source query verification is not implemented.");
                }
            }

            if (sourceSymbol == null)
            {
                throw new InvalidOperationException("Could not determine query source type.");
            }

            var sourceSymbolListType = sourceSymbol.DataType as ListType;
            var sourceSymbolElementType = sourceSymbolListType != null ? sourceSymbolListType.ElementType : null;
            var sourceElementSymbol = sourceSymbolElementType != null ? new Symbol(sourceSymbol.Name, sourceSymbolElementType) : null;

            context.PushSymbol(sourceElementSymbol ?? sourceSymbol);
            try
            {
                // foreach define
                    // add to the current scope
                var defines = ((Node)node).Children.Where(c => c.Name == "define").ToList();
                foreach (var define in defines)
                {
                    throw new NotImplementedException("Query defines are not implemented.");
                }

                // verify each with/without clause
                var relationships = ((Node)node).Children.Where(c => c.Name == "relationship").ToList();
                foreach (var relationship in relationships)
                {
                    var relatedSourceSymbol = ProcessAliasedQuerySource(context, relationship);
                    var relatedSourceSymbolListType = relatedSourceSymbol.DataType as ListType;
                    var relatedSourceSymbolElementType = relatedSourceSymbolListType != null ? relatedSourceSymbolListType.ElementType : null;
                    var relatedSourceElementSymbol = relatedSourceSymbolElementType != null ? new Symbol(relatedSourceSymbol.Name, relatedSourceSymbolElementType) : null;

                    context.PushSymbol(relatedSourceElementSymbol ?? relatedSourceSymbol);
                    try
                    {
                        var suchThat = relationship.Children[1] as ASTNode;
                        if (suchThat == null)
                        {
                            throw new InvalidOperationException(String.Format("Could not determine such that for relationship '{0}'.", relatedSourceSymbol.Name));
                        }

                        Verifier.Verify(context, suchThat);
                        context.VerifyType(suchThat.ResultType, DataTypes.Boolean);
                    }
                    finally
                    {
                        context.PopSymbol();
                    }
                }

                // verify the where clause
                var whereClause = ((Node)node).Children.Where(c => c.Name == "where").FirstOrDefault() as ASTNode;
                if (whereClause != null)
                {
                    Verifier.Verify(context, whereClause);
                    context.VerifyType(whereClause.ResultType, DataTypes.Boolean);
                }

                // verify the return clause
                var returnClause = ((Node)node).Children.Where(c => c.Name == "return").FirstOrDefault();
                if (returnClause != null)
                {
                    throw new NotImplementedException("Return clause is not implemented.");
                }

                // verify the sort clause
                var sortClause = ((Node)node).Children.Where(c => c.Name == "sort").FirstOrDefault();
                if (sortClause != null)
                {
                    throw new NotImplementedException("Sort clause is not implemented.");
                }

                node.ResultType = sourceSymbol.DataType;
            }
            finally
            {
                context.PopSymbol();
            }
        }
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			DataType operandType = null;

			foreach (var child in node.Children)
			{
				if (operandType == null)
				{
					operandType = child.ResultType;
				}
				else
				{
					context.VerifyType(child.ResultType, operandType);
				}
			}

			node.ResultType = operandType;
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			var child = node.Children[0];
			var intervalType = child.ResultType as IntervalType;
			if (intervalType != null)
			{
				var lengthOperator = context.ResolveCall("Subtract", new Signature(new DataType[] { intervalType.PointType, intervalType.PointType }));
				node.ResultType = lengthOperator.ResultType;
			}
			else
			{
				context.VerifyType(child.ResultType, DataTypes.String);
				node.ResultType = DataTypes.Integer;
			}
		}
		public void Verify(VerificationContext context, ASTNode node)
		{
			// Verify source
			Verifier.Verify(context, node.Children[0]);

			var objectType = node.Children[0].ResultType as ObjectType;
			if (objectType == null)
			{
				throw new InvalidOperationException("The source expression for an object redefine must evaluate to a value of a structured type.");
			}

			// Push the source into context as a symbol
			context.PushSymbol(new Symbol(node.GetAttribute<string>("Scope", VerificationContext.Current), objectType));
			try
			{
				// foreach property
				for (int i = 1; i < ((Node)node).Children.Count; i++)
				{
					// Verify the property exists
					var child = ((Node)node).Children[i];
					var childPropertyType = context.ResolveProperty(objectType, child.GetAttribute<string>("name"));

					// Verify the value
					var value = (ASTNode)child.Children[0];
					Verifier.Verify(context, value);

					// Verify the value type is appropriate for the property type
					context.VerifyType(value.ResultType, childPropertyType);
				}
			}
			finally
			{
				context.PopSymbol();
			}

			node.ResultType = objectType;
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			var source = node.Children[0];
			var element = node.Children[1];

			var sourceListType = source.ResultType as ListType;
			if (sourceListType != null)
			{
				context.VerifyType(element.ResultType, sourceListType.ElementType);

				node.ResultType = DataTypes.Boolean;
			}

			var sourceIntervalType = source.ResultType as IntervalType;
			if (sourceIntervalType != null)
			{
				context.VerifyType(element.ResultType, sourceIntervalType.PointType);

				node.ResultType = DataTypes.Boolean;
			}

			if (node.ResultType == null)
			{
				throw new InvalidOperationException("Expected an argument of type list or interval.");
			}
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node, ObjectType dataType)
		{
			base.InternalVerify(context, node, dataType);

			// codeProperty - If present, must reference a property of type Code on the resolved model type.
			var codeProperty = node.GetAttribute<string>("codeProperty");
			if (!String.IsNullOrEmpty(codeProperty))
			{
				var codePropertyType = context.ResolveProperty(dataType, codeProperty);
				context.VerifyType(codePropertyType, DataTypes.Code);
			}

			// dateProperty - If present, must reference a property of type Timestamp on the resolved model type. (TODO: Handle Interval<Timestamp>?)
			var dateProperty = node.GetAttribute<string>("dateProperty");
			if (!String.IsNullOrEmpty(dateProperty))
			{
				var datePropertyType = context.ResolveProperty(dataType, dateProperty);
				context.VerifyType(datePropertyType, DataTypes.DateTime);
			}

			// codes - If present, must evaluate to a value of type List<Code>
			var codes = node.Children.Where(n => n.Name == "codes").FirstOrDefault();
			if (codes != null)
			{
				Verifier.Verify(context, codes);
				context.VerifyType(codes.ResultType, DataTypes.CodeList);
			}

			// dateRange - If present, must evaluate to a value of type Interval<Timestamp>
			var dateRange = node.Children.Where(n => n.Name == "dateRange").FirstOrDefault();
			if (dateRange != null)
			{
				Verifier.Verify(context, dateRange);
				context.VerifyType(dateRange.ResultType, DataTypes.DateTimeInterval);
			}
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			if (node.Children.Count == 0)
			{
				throw new InvalidOperationException("Expected at least one child argument.");
			}

			DataType operandType = null;
			foreach (var child in node.Children)
			{
				if (operandType == null)
				{
					operandType = child.ResultType;

					if (!(operandType is ListType || operandType is IntervalType))
					{
						throw new InvalidOperationException("List or interval type expected.");
					}
				}
				else
				{
					context.VerifyType(child.ResultType, operandType);
				}
			}

			node.ResultType = operandType;
		}
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);

			foreach (var child in node.Children)
			{
				context.VerifyType(child.ResultType, GetOperandType());
			}

			node.ResultType = GetResultType();
		}
        public IEnumerable <VerificationException> Verify(Artifact artifact)
        {
            // Parameters must be validated without access to parameter definitions, or expression definitions
            var initialContext = new VerificationContext(artifact.Models, null, null, null);

            // Resolve parameter types and verify default expressions
            foreach (var parameter in artifact.Parameters)
            {
                try
                {
                    parameter.ParameterType = initialContext.ResolveType(parameter.TypeName);

                    if (parameter.Default != null)
                    {
                        Verifier.Verify(initialContext, parameter.Default);
                        initialContext.VerifyType(parameter.Default.ResultType, parameter.ParameterType);
                    }
                }
                catch (Exception e)
                {
                    initialContext.ReportMessage(new VerificationException(String.Format("Exceptions occurred verifying parameter {0}.", parameter.Name), e), null);
                }
            }

            var context = new VerificationContext(artifact.Models, artifact.Parameters, artifact.Expressions, initialContext.Messages);

            // Verify expressions
            foreach (var expression in artifact.Expressions)
            {
                // If the result type is already set, this expression ref has already been resolved.
                if (expression.Expression.ResultType == null)
                {
                    Verifier.Verify(context, expression.Expression);
                }
            }

            // Verify conditions
            foreach (var condition in artifact.Conditions)
            {
                Verifier.Verify(context, condition);

                if (!DataTypes.Equal(condition.ResultType, DataTypes.Boolean))
                {
                    context.ReportMessage(new InvalidOperationException("Condition must evaluate to a value of type boolean."), condition);
                }
            }

            // Verify trigger expressions
            foreach (var trigger in artifact.Triggers)
            {
                VerifyExpressionNodes(context, trigger);
            }

            // Verify action conditions
            if (artifact.ActionGroup != null)
            {
                var containers = new Dictionary <string, ParameterDef>();

                // Verify documentation template conditions and binding expressions
                VerifyResponseBindings(context, artifact.ActionGroup, containers);

                foreach (var parameter in containers.Values)
                {
                    context.AddParameterDef(parameter);
                }

                VerifyExpressionNodes(context, artifact.ActionGroup);
            }

            return(context.Messages);
        }
		protected override void InternalVerify(VerificationContext context, ASTNode node)
		{
			base.InternalVerify(context, node);
			var conditionNode = node.Children[0];
			var thenNode = node.Children[1];
			var elseNode = node.Children[2];

			context.VerifyType(conditionNode.ResultType, DataTypes.Boolean);

			var resultType = thenNode.ResultType;

			if (resultType == null)
			{
				throw new InvalidOperationException("Could not determine type of then expression for conditional.");
			}

			context.VerifyType(elseNode.ResultType, resultType);

			node.ResultType = resultType;
		}