public void AddPlugin(TypeNode pluginType, TypeSystem typeSystem, Node offendingNode){ if (pluginType == null || typeSystem == null || typeSystem.ErrorHandler == null || offendingNode == null){Debug.Assert(false); return;} Type pType = pluginType.GetRuntimeType(); if (pType == null){ ((ErrorHandler)typeSystem.ErrorHandler).HandleError(offendingNode, Error.CouldNotLoadPluginType, typeSystem.ErrorHandler.GetTypeName(pluginType)); return; } this.AddPlugin(pType, typeSystem, offendingNode); }
Expression GetConvertFromString(TypeNode targetType, Expression src, bool always) { if (targetType == SystemTypes.String) return src;// nothing to do! if (targetType is EnumNode) { // e.g. return (DayOfWeek)Enum.Parse(typeof(DayOfWeek),"Sunday"); Method method = SystemTypes.Enum.GetMethod(Identifier.For("Parse"), new TypeNode[2]{ SystemTypes.Type, SystemTypes.String}); UnaryExpression typeOfEnum = new UnaryExpression(new MemberBinding(null, targetType), NodeType.Typeof); MethodCall call = new MethodCall(new MemberBinding(new MemberBinding(null, targetType), method), new ExpressionList(new Expression[2]{typeOfEnum, src }), NodeType.Call, SystemTypes.Object); return CastTo(call, targetType); } // See if it has a type converter. Class converterClass = Checker.GetTypeConverter(targetType); if (converterClass != null) { TypeConverter converter = TypeDescriptor.GetConverter(targetType.GetRuntimeType()); if (converter != null) { Type converterType = converter.GetType(); AssemblyNode converterAssembly = AssemblyNode.GetAssembly(converterType.Assembly, cache, false, true); converterClass = converterAssembly.GetType(Identifier.For(converterType.Namespace), Identifier.For(converterType.Name)) as Class; Expression e = tempChecker.GetConverterFromString(converter, converterClass, SystemTypes.String, src, SystemTypes.Object); if (e != null) { //Do I need to add namespace and assembly reference for type converter? return CastTo(e, targetType); } } } if (always) { // e.g. return PointArray.Parse("10,20 30,40 50,60"); Method method = targetType.GetImplicitCoercionFromMethod(SystemTypes.String); if (method == null) { method = targetType.GetMethod(Identifier.For("Parse"), new TypeNode[1]{ SystemTypes.String}); } if (method != null) { MemberBinding typeBinding = new MemberBinding(null, targetType); MethodCall call = new MethodCall(new MemberBinding(typeBinding, method), new ExpressionList(new Expression[1]{ src }), NodeType.Call, targetType ); return call; } } return null; }
/// <summary> /// Gets the value of the literal coercing literals of TypeNode, EnumNode, TypeNode[], and EnumNode[] as needed. /// </summary> /// <param name="type">A TypeNode representing the type of the literal</param> /// <param name="value">The value of the literal</param> /// <returns>An object that has been coerced to the appropriate runtime type</returns> protected object GetCoercedLiteralValue(TypeNode type, object value) { if(type == null || value == null) return null; switch(type.typeCode) { case ElementType.Class: return ((TypeNode)value).GetRuntimeType(); case ElementType.ValueType: return System.Enum.ToObject(type.GetRuntimeType(), value); case ElementType.SzArray: return this.GetCoercedArrayLiteral((ArrayType)type, (Array)value); default: Literal lit = value as Literal; if(lit != null && type == CoreSystemTypes.Object && lit.Type is EnumNode) return this.GetCoercedLiteralValue(lit.Type, lit.Value); break; } return value; }