/// <summary> /// Constructor. /// </summary> /// <param name="parserContext"></param> /// <param name="kind"></param> /// <param name="castTypeName"></param> /// <param name="expression"></param> public CastExpression(IParserLocation parserContext, CoercionKind kind, string castTypeName, IExpression expression) { Location = parserContext; Kind = kind; CastTypeName = castTypeName; Expression = expression; }
/// <summary> /// Creates a coercion rule /// </summary> /// <param name="kind"></param> /// <param name="originalType"></param> /// <param name="castingType"></param> /// <param name="cast"></param> public CoercionRule(CoercionKind kind, Type originalType, Type castingType, Func <object, object> cast) { Kind = kind; OriginalType = originalType; CastingType = castingType; Cast = cast; }
/// <summary> /// Adds a new coercion rule. Trys to avoid cyclic implicit casts chains. /// </summary> /// <typeparam name="TOriginalType"></typeparam> /// <typeparam name="TCastingType"></typeparam> /// <param name="kind"></param> /// <param name="cast"></param> public void AddCoercionRule <TOriginalType, TCastingType>(CoercionKind kind, Func <TOriginalType, TCastingType> cast) { var original = typeof(TOriginalType); var casting = typeof(TCastingType); if (GetTypeByNative(original) == null) { throw new UnknownTypeException(original); } if (GetTypeByNative(casting) == null) { throw new UnknownTypeException(casting); } var rule = new CoercionRule(kind, original, casting, a => cast((TOriginalType)a)); if (allCoercionRules.TryGetEdge(original, casting, out TaggedEdge <Type, CoercionRule> existingEdge)) { throw new InvalidOperationException("Such a rule does already exist!"); } var edge = new TaggedEdge <System.Type, CoercionRule>(original, casting, rule); if (kind == CoercionKind.Implicit) { implicitCoercionRules.AddVertex(original); implicitCoercionRules.AddVertex(casting); implicitCoercionRules.AddEdge(edge); if (implicitCoercionRules.StronglyConnectedComponents(out IDictionary <Type, int> components) != implicitCoercionRules.Vertices.Count()) { implicitCoercionRules.RemoveEdge(edge); throw new InvalidOperationException("This action would create an implicit conversion cycle!"); } } allCoercionRules.AddVertex(original); allCoercionRules.AddVertex(casting); allCoercionRules.AddEdge(edge); Debug.WriteLine($"- added coercion rule from '{original.Name}' to '{casting.Name}'"); }
/// <summary> /// Adds a coercion rule. /// </summary> /// <typeparam name="TOriginalType"></typeparam> /// <typeparam name="TCastingType"></typeparam> /// <param name="kind"></param> /// <param name="cast"></param> public void AddCoercionRule <TOriginalType, TCastingType>(CoercionKind kind, Func <TOriginalType, TCastingType> cast) { typeSystem.AddCoercionRule(kind, cast); }