public static string[] ToKeyValueCollection(string collectionName, Type keyType, Type valueType) { string keyRtType = TX.ToWinRT(keyType); string[] keyTypeToJs = ToJS(keyType, TX.MainModel.Types.ContainsKey(keyType)); string keyCheckType = TypeCheck(keyType, TX.MainModel.Types.ContainsKey(keyType)); string[] jsToKeyElementType = ToWinRT(keyType, TX.MainModel.Types.ContainsKey(keyType)); string valueRtType = TX.ToWinRT(valueType); string[] valueTypeToJs = ToJS(valueType, TX.MainModel.Types.ContainsKey(valueType)); string valueCheckType = TypeCheck(valueType, TX.MainModel.Types.ContainsKey(valueType)); string[] jsToValueElementType = ToWinRT(valueType, TX.MainModel.Types.ContainsKey(valueType)); // note that double curl braces here are used because String.Format will string creatorFunction = "NodeRT::Collections::" + collectionName + "Wrapper<" + keyRtType + "," + valueRtType + ">::Create" + collectionName + "Wrapper({0}, \r\n" + " [](" + keyRtType + " val) -> Local<Value> {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(keyTypeToJs[1], "val")) + ";\r\n" + " }},\r\n" + " [](Local<Value> value) -> bool {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(keyCheckType, "value")) + ";\r\n" + " }},\r\n" + " [](Local<Value> value) -> " + keyRtType + " {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(jsToKeyElementType[1], "value")) + ";\r\n" + " }},\r\n" + " [](" + valueRtType + " val) -> Local<Value> {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(valueTypeToJs[1], "val")) + ";\r\n" + " }},\r\n" + " [](Local<Value> value) -> bool {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(valueCheckType, "value")) + ";\r\n" + " }},\r\n" + " [](Local<Value> value) -> " + valueRtType + " {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(jsToValueElementType[1], "value")) + ";\r\n" + " }}\r\n" + " )"; return(new[] { "NodeRT::Collections::Create" + collectionName + "<" + keyRtType + "," + valueRtType + ">", creatorFunction }); }
// If you try to get a value of a property // not defined in the class, this method is called. public override bool TryGetMember( GetMemberBinder binder, out object result) { string name = binder.Name; // If the property name is found in a dictionary, // set the result parameter to the property value and return true. // Otherwise, try to load the template. if (!dictionary.TryGetValue(name, out result)) { Func <dynamic, String> template = TX.LazyTemplate(name, this.templateLocation, this.templateExtension); if (template != null) { dictionary[name] = template; result = template; return(true); } return(false); } return(true); }
public static string[] ToCollection(string collectionName, Type elementType) { string elementRtType = TX.ToWinRT(elementType); string[] elementTypeToJs = ToJS(elementType, TX.MainModel.Types.ContainsKey(elementType)); string checkType = TypeCheck(elementType, TX.MainModel.Types.ContainsKey(elementType)); string[] jsToElementType = ToWinRT(elementType, TX.MainModel.Types.ContainsKey(elementType)); // note that double curl braces here are used because String.Format will string creatorFunction = "NodeRT::Collections::" + collectionName + "Wrapper<" + elementRtType + ">::Create" + collectionName + "Wrapper({0}, \r\n" + " [](" + elementRtType + " val) -> Handle<Value> {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(elementTypeToJs[1], "val")) + ";\r\n" + " }},\r\n" + " [](Handle<Value> value) -> bool {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(checkType, "value")) + ";\r\n" + " }},\r\n" + " [](Handle<Value> value) -> " + elementRtType + " {{\r\n" + " return " + ReplaceBracketsWithDoubleBrackets(String.Format(jsToElementType[1], "value")) + ";\r\n" + " }}\r\n" + " )"; return(new[] { "NodeRT::Collections::Create" + collectionName + "<" + elementRtType + ">", creatorFunction }); }
public static dynamic GenerateModel(Assembly assembly, string winRTNamespace) { if (!VerifyNamespaceInAssembly(assembly, winRTNamespace)) { throw new Exception(String.Format("The namespace {0} is not defined in the given WinMD file.", winRTNamespace)); } dynamic mainModel = new DynamicDictionary(); TX.MainModel = mainModel; mainModel.Assembly = assembly; var types = new Dictionary <Type, dynamic>(); mainModel.Types = types; var namespaces = new List <String>(); namespaces.Add("NodeRT"); namespaces.AddRange(winRTNamespace.Split('.')); mainModel.Namespaces = namespaces; mainModel.WinRTNamespace = winRTNamespace; var filteredTypes = GetTypesForNamespace(assembly, winRTNamespace); mainModel.Enums = (from t in assembly.ExportedTypes where t.Namespace.Equals(winRTNamespace, StringComparison.InvariantCultureIgnoreCase) && t.IsEnum select t).ToArray(); mainModel.ValueTypes = (from t in assembly.ExportedTypes where t.Namespace.Equals(winRTNamespace, StringComparison.InvariantCultureIgnoreCase) && t.IsValueType && !t.IsEnum select t).ToArray(); // use this container to aggregate value types which are not in the namespace // we will need to generate converter methods for those types mainModel.ExternalReferencedValueTypes = new List <Type>(); // use this container to aggreate other namesapces which are references from this namespaces // we will need to create a dependancy list from these namespaces mainModel.ExternalReferencedNamespaces = new List <String>(); foreach (var t in filteredTypes) { dynamic typeDefinition = new DynamicDictionary(); types.Add(t, typeDefinition); typeDefinition.Name = t.Name; typeDefinition.MemberProperties = t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); typeDefinition.StaticProperties = t.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); var memberEvents = t.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy).Select(eventInfo => { dynamic dict = new DynamicDictionary(); dict.EventInfo = eventInfo; dict.IsStatic = false; return(dict); }).ToArray(); var staticEvents = t.GetEvents(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).Select(eventInfo => { dynamic dict = new DynamicDictionary(); dict.EventInfo = eventInfo; dict.IsStatic = true; return(dict); }).ToArray(); // one function will handle both static and member events, so put them in the same list typeDefinition.Events = memberEvents.Concat(staticEvents).ToArray(); // this will be used in the InitExports method typeDefinition.HasStaticEvents = (staticEvents.Length > 0); typeDefinition.HasMemberEvents = (memberEvents.Length > 0); typeDefinition.Type = t; var publicMethods = t.GetRuntimeMethods().Where((methodInfo) => { return(methodInfo.DeclaringType == t && (methodInfo.IsPublic || methodInfo.IsHideBySig) && !methodInfo.Name.StartsWith("add_") && !methodInfo.Name.StartsWith("remove_") && !methodInfo.Name.StartsWith("get_") && !methodInfo.Name.StartsWith("put_") && !methodInfo.IsStatic && !TX.ShouldIgnoreMethod(methodInfo)); }).GroupBy(methodInfo => methodInfo.Name).Select(method => { dynamic dict = new DynamicDictionary(); dict.Name = method.Key; dict.Overloads = method.ToArray(); return(dict); }).ToArray(); typeDefinition.MemberAsyncMethods = publicMethods.Where((methodInfo) => { return(TX.IsAsync(methodInfo.Overloads[0])); }).ToArray(); typeDefinition.MemberSyncMethods = publicMethods.Where((methodInfo) => { return(!TX.IsAsync(methodInfo.Overloads[0])); }).ToArray(); var staticMethods = t.GetRuntimeMethods().Where((methodInfo) => { return(methodInfo.DeclaringType == t && (methodInfo.IsPublic || methodInfo.IsHideBySig) && !methodInfo.Name.StartsWith("add_") && !methodInfo.Name.StartsWith("remove_") && !methodInfo.Name.StartsWith("get_") && !methodInfo.Name.StartsWith("put_") && methodInfo.IsStatic && !TX.ShouldIgnoreMethod(methodInfo)); }).GroupBy(methodInfo => methodInfo.Name).Select(method => { dynamic dict = new DynamicDictionary(); dict.Name = method.Key; dict.Overloads = method.ToArray(); return(dict); }).ToArray(); typeDefinition.StaticAsyncMethods = staticMethods.Where((methodInfo) => { return(TX.IsAsync(methodInfo.Overloads[0])); }).ToArray(); typeDefinition.StaticSyncMethods = staticMethods.Where((methodInfo) => { return(!TX.IsAsync(methodInfo.Overloads[0])); }).ToArray(); ExternalTypesHelper.GetExternalReferencedDataForType(typeDefinition, mainModel.ExternalReferencedValueTypes, mainModel.ExternalReferencedNamespaces); } return(mainModel); }
public static string TypeCheck(Type type, bool typeIsInNameSpace = false) { // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. if (type.IsPrimitive) { if (type == typeof(Byte) || type == typeof(SByte) || type == typeof(Int16) || type == typeof(UInt16) || type == typeof(Int32) ) { return("{0}->IsInt32()"); } else if (type == typeof(UInt32)) { return("{0}->IsUint32()"); } else if (type == typeof(Int64) || type == typeof(UInt64)) { return("{0}->IsNumber()"); } else if (type == typeof(Double) || type == typeof(Single) || type == typeof(IntPtr) || type == typeof(UIntPtr)) { return("{0}->IsNumber()"); } else if (type == typeof(Boolean)) { return("{0}->IsBoolean()"); } else if (type == typeof(Char)) { return("{0}->IsString()"); } } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(TypeCheck(type.GetGenericArguments()[0], TX.MainModel.Types.ContainsKey(type.GetGenericArguments()[0]))); } if (type == typeof(Guid)) { return("NodeRT::Utils::IsGuid({0})"); } if (type.FullName == "Windows.UI.Color") { return("NodeRT::Utils::IsColor({0})"); } if (type.FullName == "Windows.Foundation.Point") { return("NodeRT::Utils::IsPoint({0})"); } if (type.FullName == "Windows.Foundation.Size") { return("NodeRT::Utils::IsSize({0})"); } if (type.FullName == "Windows.Foundation.Rect") { return("NodeRT::Utils::IsRect({0})"); } if (type.IsEnum) { return("{0}->IsInt32()"); } if (type == typeof(String)) { return("{0}->IsString()"); } if (type == typeof(DateTimeOffset) || type == typeof(DateTime)) { return("{0}->IsDate()"); } if (type == typeof(TimeSpan)) { return("{0}->IsNumber()"); } // this if clause should come after IsEnum, since an enum will also return true for IsValueType if (type.IsValueType && !(type.IsGenericType && type.FullName.StartsWith("System.Collections.Generic.KeyValuePair`2"))) { return("Is" + type.Name + "JsObject({0})"); } string wrapperTest = "NodeRT::Utils::IsWinRtWrapperOf<" + TX.ToWinRT(type, true) + ">({0})"; string jsType; if (IsWinrtCollection(type, out jsType)) { // in case the type is a winrt collection, we allow to pass a JS Object/Array instead of a wrapped collection return("(" + wrapperTest + " || " + "{0}->Is" + jsType + "())"); } return(wrapperTest); }
public static string[] ToWinRT(Type type, bool typeIsInNameSpace = false) { // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. if (type.IsPrimitive) { if (type == typeof(Byte)) { return(new[] { "unsigned char", "static_cast<unsigned char>(Nan::To<int32_t>({0}).FromMaybe(0))" }); } else if (type == typeof(SByte)) { return(new[] { "char", "static_cast<char>(Nan::To<int32_t>({0}).FromMaybe(0))" }); } else if (type == typeof(Int16)) { return(new[] { "short", "static_cast<short>(Nan::To<int32_t>({0}).FromMaybe(0))" }); } else if (type == typeof(UInt16)) { return(new[] { "unsigned short", "static_cast<unsigned short>(Nan::To<int32_t>({0}).FromMaybe(0))" }); } else if (type == typeof(Int32)) { return(new[] { "int", "static_cast<int>(Nan::To<int32_t>({0}).FromMaybe(0))" }); } else if (type == typeof(UInt32)) { return(new[] { "unsigned int", "static_cast<unsigned int>(Nan::To<uint32_t>({0}).FromMaybe(0))" }); } else if (type == typeof(Int64)) { return(new[] { "__int64", "Nan::To<int64_t>({0}).FromMaybe(0)" }); } else if (type == typeof(UInt64)) { return(new[] { "unsigned __int64", "static_cast<unsigned __int64>(Nan::To<int64_t>({0}).FromMaybe(0))" }); } else if (type == typeof(IntPtr)) { return(new[] { "__int64", "Nan::To<int64_t>({0}).FromMaybe(0)" }); } else if (type == typeof(UIntPtr)) { return(new[] { "unsigned __int64", "static_cast<unsigned __int64>(Nan::To<int64_t>({0}).FromMaybe(0))" }); } else if (type == typeof(Single)) { return(new[] { "float", "static_cast<float>(Nan::To<double>({0}).FromMaybe(0.0))" }); } else if (type == typeof(Double)) { return(new[] { "double", "Nan::To<double>({0}).FromMaybe(0.0)" }); } else if (type == typeof(Boolean)) { return(new[] { "bool", "Nan::To<bool>({0}).FromMaybe(false)" }); } else if (type == typeof(Char)) { return(new[] { "wchar_t", "NodeRT::Utils::GetFirstChar({0})" }); } } if (type == typeof(String)) { return(new[] { "Platform::String^", "ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value({0})))" }); } if (type == typeof(DateTime) || type == typeof(DateTimeOffset)) { return(new[] { "::Windows::Foundation::DateTime", "NodeRT::Utils::DateTimeFromJSDate({0})" }); } if (type == typeof(Guid)) { return(new[] { "::Platform::Guid", "NodeRT::Utils::GuidFromJs({0})" }); } if (type == typeof(Exception)) { return(new[] { "::Windows::Foundation::HResult", "NodeRT::Utils::HResultFromJsInt32(Nan::To<int32_t>({0}).FromMaybe(0))" }); } if (type == typeof(TimeSpan)) { return(new[] { "::Windows::Foundation::TimeSpan", "NodeRT::Utils::TimeSpanFromMilli(Nan::To<int64_t>({0}).FromMaybe(0))" }); } if (type.FullName == "Windows.UI.Color") { return(new[] { "::Windows::UI::Color", "NodeRT::Utils::ColorFromJs({0})" }); } if (type.FullName == "Windows.Foundation.Point") { return(new[] { "::Windows::Foundation::Point", "NodeRT::Utils::PointFromJs({0})" }); } if (type.FullName == "Windows.Foundation.Rect") { return(new[] { "::Windows::Foundation::Rect", "NodeRT::Utils::RectFromJs({0})" }); } if (type.FullName == "Windows.Foundation.Size") { return(new[] { "::Windows::Foundation::Size", "NodeRT::Utils::SizeFromJs({0})" }); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { var genericArgConversionInfo = ToWinRT(type.GetGenericArguments()[0]); return(new[] { "::Platform::IBox<" + genericArgConversionInfo[0] + ">^", "ref new ::Platform::Box<" + genericArgConversionInfo[0] + ">(" + genericArgConversionInfo[1] + ")" }); } var winrtFullType = TX.ToWinRT(type); if (type.IsEnum) { return(new[] { winrtFullType, "static_cast<" + winrtFullType + ">(Nan::To<int32_t>({0}).FromMaybe(0))" }); } // this if clause should come after IsEnum, since an enum will also return true for IsValueType if (type.IsValueType && !(type.IsGenericType && type.FullName.StartsWith("System.Collections.Generic.KeyValuePair`2"))) { return(new[] { winrtFullType, type.Name + "FromJsObject({0})" }); } string jsType; if (IsWinrtCollection(type, out jsType)) { return(new[] { winrtFullType, JsToWinrtCollection(type, jsType, winrtFullType, typeIsInNameSpace) }); } if (typeIsInNameSpace) { return(new[] { winrtFullType, "Unwrap" + type.Name + "({0})" }); } return(new[] { winrtFullType, "dynamic_cast<" + winrtFullType + ">(NodeRT::Utils::GetObjectInstance({0}))" }); }
public static string[] GetValueTypeAndLambdas(Type valueType) { return(new[] { "<" + TX.ToWinRT(valueType) + ">", GetTypeCheckerAndConverterLambdas(valueType) + "\r\n" }); }