public virtual bool IsAssignment(ICbValue obj, bool isCast) { if (obj is ParamNameOnly) { return(false); } if (IsList) { ICbList cbList = GetListValue; if (isCast && cbList.IsArrayType && obj.IsList) { return(true); // ToArrya() を行う特殊なキャスト } if (isCast && obj.IsList) { ICbList ListObj = obj.GetListValue; if (ListObj.IsArrayType) { return(true); // List<>(array) を行う特殊なキャスト } } if (OriginalType.IsAssignableFrom(obj.OriginalType)) { return(true); } } return(CbSTUtils.IsAssignment(OriginalType, obj.OriginalType, isCast)); }
/// <summary> /// オリジナル型の値に変換します。 /// </summary> /// <param name="value"></param> /// <param name="col"></param> /// <param name="dummyArgumentsControl"></param> /// <param name="dummyArgumentsStack"></param> /// <returns></returns> private object getBindObject( ICbValue value, MultiRootConnector col, DummyArgumentsControl dummyArgumentsControl, DummyArgumentsStack dummyArgumentsStack ) { if (value.IsList) { ICbList cbList = value.GetListValue; // リストは、オリジナルの型のインスタンスを用意する if (dummyArgumentsControl is null) { return(cbList.ConvertOriginalTypeList(col, dummyArgumentsStack)); } else { return(cbList.ConvertOriginalTypeList(dummyArgumentsControl, dummyArgumentsStack)); } } else if (dummyArgumentsControl != null && value is ICbEvent cbEvent) { // Func<> 及び Action<> は、オリジナルの型のインスタンスを用意する if (cbEvent.Callback is null) { return(null); } else { Debug.Assert(dummyArgumentsControl != null); return(cbEvent.GetCallbackOriginalType(dummyArgumentsControl, dummyArgumentsStack)); } } if (value.IsNull) { return(null); } return(value.Data); }
/// <summary> /// 返り値を処理します。 /// </summary> /// <param name="col">スクリプトのルートノード</param> /// <param name="returnValue">返り値を格納する変数</param> /// <param name="result">メソッド呼び出しの返り値</param> private static void ProcReturnValue(MultiRootConnector col, ICbValue returnValue, object result) { if (returnValue.IsList) { ICbList retCbList = returnValue.GetListValue; retCbList.CopyFrom(result); col.LinkConnectorControl.UpdateValueData(); } else if (result != null && returnValue is ICbEvent cbEvent) { // デリゲート型の返し値 Type resultType = CbSTUtils.GetDelegateReturnType(result.GetType()); if (!CbSTUtils.IsVoid(resultType)) { // 返し値のあるデリゲート型 cbEvent.Callback = (cagt) => { ICbValue retTypeValue = null; try { // イベントからの返り値を取得 object tempReturnValue = ((dynamic)result).Invoke(cagt.GetValue().Data); // 直接メソッドを呼ぶため帰ってくるのは通常の値なので Cb タイプに変換する retTypeValue = CbST.CbCreate(tempReturnValue.GetType()); retTypeValue.Data = tempReturnValue; } catch (Exception ex) { col.ExceptionFunc(null, ex); } return(retTypeValue); }; } else { // 返し値の無いデリゲート型 cbEvent.Callback = (cagt) => { try { var argType = cagt.GetValue(); if (argType is null) { ((dynamic)result).Invoke(null); } else { ((dynamic)result).Invoke(argType.Data); } } catch (Exception ex) { col.ExceptionFunc(null, ex); } return(new CbVoid()); }; } } else { returnValue.Data = result; } }
/// <summary> /// メソッド呼び出しの実装です。 /// </summary> /// <param name="col">スクリプトのルートノード</param> /// <param name="dummyArgumentsControl">仮引数管理オブジェクト</param> /// <param name="callArguments">引数リスト</param> /// <param name="dummyArgumentsStack">仮引数スタック</param> /// <param name="returnValue">返り値</param> private void ImplCallMethod( MultiRootConnector col, Type classType, DummyArgumentsControl dummyArgumentsControl, List <ICbValue> callArguments, DummyArgumentsStack dummyArgumentsStack, ICbValue returnValue ) { try { bool isClassInstanceMethod = ArgumentTypeList != null && ArgumentTypeList[0].IsSelf && !IsConstructor; List <object> methodArguments = null; methodArguments = SetArguments( col, dummyArgumentsControl, callArguments, dummyArgumentsStack, isClassInstanceMethod, methodArguments ); object classInstance = null; if (isClassInstanceMethod) { // クラスメソッドの第一引数は、self(this)を受け取るのでクラスインスタンスとして扱う classInstance = getBindObject(callArguments[0], col, dummyArgumentsControl, dummyArgumentsStack); if (classInstance is null) { throw new Exception($"self(this) is invalid."); } // 返却方法が入っていないならセットしておく var cbVSValue = callArguments[0]; if (!cbVSValue.IsDelegate && !cbVSValue.IsLiteral && cbVSValue.ReturnAction is null) { if (cbVSValue.IsList) { ICbList cbList = cbVSValue.GetListValue; cbVSValue.ReturnAction = (value) => { cbList.CopyFrom(value); }; } else if (!(cbVSValue is ICbClass)) { cbVSValue.ReturnAction = (value) => { cbVSValue.Data = value; }; } } } object result = CallMethod( classInstance, col, classType, callArguments, isClassInstanceMethod, methodArguments); ProcReturnValue(col, returnValue, result); } catch (Exception ex) { col.ExceptionFunc(returnValue, ex); } }
private static ICbValue _CbCreate(Type type, string name, bool isCancelClass) { string typeName = type.Name; if (!isCancelClass && type.IsByRef) { // リファレンス情報を消す typeName = typeName.Replace("&", ""); } switch (typeName) { case nameof(Byte): return(CbByte.Create(name)); case nameof(SByte): return(CbSByte.Create(name)); case nameof(Int16): return(CbShort.Create(name)); case nameof(Int32): return(CbInt.Create(name)); case nameof(Int64): return(CbLong.Create(name)); case nameof(UInt16): return(CbUShort.Create(name)); case nameof(UInt32): return(CbUInt.Create(name)); case nameof(UInt64): return(CbULong.Create(name)); case nameof(Char): return(CbChar.Create(name)); case nameof(Single): return(CbFloat.Create(name)); case nameof(Double): return(CbDouble.Create(name)); case nameof(Decimal): return(CbDecimal.Create(name)); case nameof(Boolean): return(CbBool.Create(name)); case nameof(String): return(CbString.Create(name)); case nameof(Object): return(CbObject.Create(name)); case nameof(CbText): return(CbText.Create(name)); case nameof(CbImagePath): return(CbImagePath.Create(name)); default: break; } if (type.IsArray) { // 配列は、List<>に置き換える string _mame = "xxx"; if (type.FullName != null) { _mame = type.FullName; } else if (type.Name != null) { _mame = type.Name; } Type tType = CbST.GetTypeEx(_mame); if (tType != null) { Type element = tType.GetElementType(); if (element != null) { Type collectionType = typeof(List <>).MakeGenericType(element); var ret = CbList.Create(collectionType, name); if (ret.IsList) { ICbList cbList = ret.GetListValue; cbList.IsArrayType = true; } return(ret); } } if (type.ContainsGenericParameters) { return(CbGeneMethArg.NTF(name, type, type.GetGenericArguments(), false)); } } if (type.IsEnum) { // 列挙型 return(CbEnumTools.EnumValue(type, name)); } if (!type.IsGenericType && CbSTUtils.IsDelegate(type)) { // デリゲート型 return(CbFunc.FuncValue(type, typeof(CbVoid), name)); } if (CbSTUtils.HaveGenericParamater(type)) { // 確定していない型なので仮の型に差し替える if (!type.IsPublic) { return(null); } if (CbSTUtils.IsDelegate(type)) { // 確定していないデリゲート型 return(CbGeneMethArg.NTF(name, type, type.GetGenericArguments(), true)); } return(CbGeneMethArg.NTF(name, type, type.GetGenericArguments(), false)); } if (type.IsGenericType) { // ジェネリック型 if (CbList.HaveInterface(type, typeof(IEnumerable <>))) { // リスト管理(UIで特別扱い) if (type.GenericTypeArguments.Length > 1) { return(null); } return(CbList.Create(type, name)); } if (CbSTUtils.IsDelegate(type)) { // デリゲート型 var returnType = CbSTUtils.GetDelegateReturnType(type); if (CbSTUtils.IsVoid(returnType)) { return(CbFunc.FuncValue(type, typeof(CbVoid), name)); } else { return(CbFunc.FuncValue(type, returnType, name)); } } if (type.GetGenericTypeDefinition() == typeof(Nullable <>)) { // Null許容型 if (type.GenericTypeArguments.Length > 1) { return(null); } Type param = type.GenericTypeArguments[0]; switch (param.Name) { case nameof(Byte): return(CbNullableByte.Create(name)); case nameof(SByte): return(CbNullableSByte.Create(name)); case nameof(Int16): return(CbNullableShort.Create(name)); case nameof(Int32): return(CbNullableInt.Create(name)); case nameof(Int64): return(CbNullableLong.Create(name)); case nameof(UInt16): return(CbNullableUShort.Create(name)); case nameof(UInt32): return(CbNullableUInt.Create(name)); case nameof(UInt64): return(CbNullableULong.Create(name)); case nameof(Char): return(CbNullableChar.Create(name)); case nameof(Single): return(CbNullableFloat.Create(name)); case nameof(Double): return(CbNullableDouble.Create(name)); case nameof(Decimal): return(CbNullableDecimal.Create(name)); case nameof(Boolean): return(CbNullableBool.Create(name)); default: break; } if (CbStruct.IsStruct(param)) { // 構造体 return(CbStruct.NullableStructValue(param, name)); } if (param.IsEnum) { // 列挙型 return(CbEnumTools.NullableEnumValue(param, name)); } Debug.Assert(false); return(null); } // その他のジェネリックは、構造体かクラスとして扱う if (CbStruct.IsStruct(type)) { return(CbStruct.StructValue(type, name)); } return(CbClass.ClassValue(type, name)); } if (CbStruct.IsStruct(type)) { // 構造体 if (type.FullName == "System.Void") { Debug.Assert(false); return(null); } if (!isCancelClass) { var ret = CbStruct.StructValue(type, name); if (ret != null && ret is ICbStruct cbStruct) { return(_CbCreate(cbStruct.OriginalReturnType, name, true)); } } return(CbStruct.StructValue(type, name)); } if (type.IsClass || type.IsInterface) { // クラス var elements = CbSTUtils.GetGenericIEnumerables(type); if (elements.Count() != 0) { // IEnumerable<> を持っているのでリストとして扱う(ただし、オリジナルのデータ形式も保存する) var elementType = elements.First(); // 最初に見つかった要素のみを対象とする(妥協) var chgType = CbList.Create(typeof(IEnumerable <>).MakeGenericType(new Type[] { elementType }), name); (chgType as ICbList).CastType = type; // 元の型にキャスト(メソッドを呼ぶときは、オリジナルのデータ形式を参照する) return(chgType); } if (!isCancelClass) { var ret = CbClass.ClassValue(type, name); if (ret != null && ret is ICbClass cbClass) { return(_CbCreate(cbClass.OriginalReturnType, name, true)); } } return(CbClass.ClassValue(type, name)); } return(null); }