/// <summary> /// Converts a value in this type /// </summary> /// <param name="value">The value to convert</param> /// <returns></returns> public override IValue convert(IValue value) { ListValue retVal = value as ListValue; if (retVal != null) { if (retVal.Val.Count <= getMaxSize()) { foreach (IValue val in retVal.Val) { if (!Type.Match(val.Type)) { throw new Exception("Invalid element type in collection " + val.LiteralName); } } } else { throw new Exception("Too many elements in collection"); } retVal.Type = this; } return(retVal); }
/// <summary> /// Indicates that this collection matches the other collections /// </summary> /// <param name="otherType"></param> /// <returns></returns> public override bool Match(Type otherType) { bool retVal = base.Match(otherType); if (!retVal && otherType is Collection) { Collection otherCollection = (Collection)otherType; if (Type != null) { if (otherCollection.Type != null) { retVal = Type.Match(otherCollection.Type); } else { // null type for a collection means "any type" retVal = true; } } else { // null type for a collection means "any type" retVal = true; } } return(retVal); }
/// <summary> /// Performs the semantic analysis of the expression /// </summary> /// <param name="instance">the reference instance on which this element should analysed</param> /// <param name="expectation">Indicates the kind of element we are looking for</param> /// <returns>True if semantic analysis should be continued</returns> public override bool SemanticAnalysis(INamable instance, BaseFilter expectation) { bool retVal = base.SemanticAnalysis(instance, expectation); if (retVal) { Type elementType = null; if (ListElements != null) { foreach (Expression expr in ListElements) { expr.SemanticAnalysis(instance, expectation); StaticUsage.AddUsages(expr.StaticUsage, null); Type current = expr.GetExpressionType(); if (elementType == null) { elementType = current; } else { if (!current.Match(elementType)) { AddError("Cannot mix types " + current + " and " + elementType + "in collection", RuleChecksEnum.SemanticAnalysisError); } } } } if (elementType != null) { ExpressionType = (Collection)acceptor.getFactory().createCollection(); ExpressionType.Type = elementType; ExpressionType.Name = "ListOf_" + elementType.FullName; ExpressionType.Enclosing = Root.EFSSystem; ExpressionType.setMaxSize(ListElements.Count); StaticUsage.AddUsage(elementType, Root, Usage.ModeEnum.Type); } else { ExpressionType = new GenericCollection(EfsSystem.Instance); } } return(retVal); }
/// <summary> /// Performs the semantic analysis of the statement /// </summary> /// <param name="instance">the reference instance on which this element should analysed</param> /// <returns>True if semantic analysis should be continued</returns> public override bool SemanticAnalysis(INamable instance = null) { bool retVal = base.SemanticAnalysis(instance); if (retVal) { // ListExpression Collection collectionType = null; if (ListExpression != null) { ListExpression.SemanticAnalysis(instance); StaticUsage.AddUsages(ListExpression.StaticUsage, Usage.ModeEnum.ReadAndWrite); collectionType = ListExpression.GetExpressionType() as Collection; if (collectionType != null) { IteratorVariable.Type = collectionType.Type; } else { AddError("Cannot determine collection type", RuleChecksEnum.SemanticAnalysisError); } } else { AddError("List expression not provided", RuleChecksEnum.SemanticAnalysisError); } // Value if (Value != null) { Value.SemanticAnalysis(instance); StaticUsage.AddUsages(Value.StaticUsage, Usage.ModeEnum.Read); Type valueType = Value.GetExpressionType(); if (valueType != null) { if (collectionType != null && !valueType.Match(collectionType.Type)) { AddError("Type of " + Value + " does not match collection type " + collectionType, RuleChecksEnum.SemanticAnalysisError); } } else { AddError("Cannot determine type of " + Value, RuleChecksEnum.SemanticAnalysisError); } } else { AddError("Replacement value not provided", RuleChecksEnum.SemanticAnalysisError); } // Condition if (Condition != null) { Condition.SemanticAnalysis(instance); StaticUsage.AddUsages(Condition.StaticUsage, Usage.ModeEnum.Read); } } return(retVal); }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { VariableIdentification.CheckExpression(); if (VariableIdentification.Ref is Parameter) { Root.AddError("Cannot assign a value to a parameter (" + VariableIdentification + ")"); } if (VariableIdentification.Ref == null) { Root.AddError("Cannot assign a value to " + VariableIdentification); } Type targetType = VariableIdentification.GetExpressionType(); if (targetType == null) { Root.AddError("Cannot determine type of target " + VariableIdentification); } else if (Expression != null) { Expression.CheckExpression(); Type type = Expression.GetExpressionType(); if (type != null) { if (!targetType.Match(type)) { UnaryExpression unaryExpression = Expression as UnaryExpression; if (unaryExpression != null && unaryExpression.Term.LiteralValue != null) { Root.AddError("Expression " + Expression + " does not fit in variable " + VariableIdentification); } else { Root.AddError("Expression [" + Expression + "] type (" + type.FullName + ") does not match variable [" + VariableIdentification + "] type (" + targetType.FullName + ")"); } } else { Range rangeType = targetType as Range; if (rangeType != null) { IValue value = Expression.Ref as IValue; if (value != null) { if (rangeType.convert(value) == null) { Root.AddError("Cannot set " + value.LiteralName + " in variable of type " + rangeType.Name); } } } } if (Expression.Ref == EfsSystem.Instance.EmptyValue) { if (targetType is Collection) { Root.AddError("Assignation of " + Expression.Ref.Name + " cannot be performed on variables of type collection. Use [] instead."); } } } else { Root.AddError("Cannot determine expression type (3) for " + Expression); } } else { Root.AddError("Invalid expression in assignment"); } // Check that the incoming variables are not modified if (EnclosingFinder <DataDictionary.Types.NameSpace> .find(Root, true) != null) { IVariable variable = VariableIdentification.Ref as IVariable; if (variable != null && variable.Mode == acceptor.VariableModeEnumType.aIncoming) { Root.AddError("An incoming variable cannot be written"); } } }