private void ProjectMethods(EmbeddedItem externalItem) { Type type = externalItem.HostType; object obj = externalItem.HostObject; JsValue typeValue = externalItem.ScriptValue; IList <JsNativeFunction> nativeFunctions = externalItem.NativeFunctions; bool instance = externalItem.IsInstance; string typeName = type.FullName; BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance); IEnumerable <MethodInfo> methods = type.GetMethods(defaultBindingFlags) .Where(ReflectionHelpers.IsFullyFledgedMethod); IEnumerable <IGrouping <string, MethodInfo> > methodGroups = methods.GroupBy(m => m.Name); foreach (IGrouping <string, MethodInfo> methodGroup in methodGroups) { string methodName = methodGroup.Key; MethodInfo[] methodCandidates = methodGroup.ToArray(); JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) => { if (instance && obj == null) { JsValue undefinedValue = JsValue.Undefined; JsValue errorValue = JsErrorHelpers.CreateTypeError( string.Format(Strings.Runtime_InvalidThisContextForHostObjectMethod, methodName)); JsErrorHelpers.SetException(errorValue); return(undefinedValue); } object[] processedArgs = GetHostItemMemberArguments(args); var bestFitMethod = (MethodInfo)ReflectionHelpers.GetBestFitMethod( methodCandidates, processedArgs); if (bestFitMethod == null) { JsValue undefinedValue = JsValue.Undefined; JsValue errorValue = JsErrorHelpers.CreateReferenceError( string.Format(Strings.Runtime_SuitableMethodOfHostObjectNotFound, methodName)); JsErrorHelpers.SetException(errorValue); return(undefinedValue); } ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitMethod.GetParameters()); object result; try { result = bestFitMethod.Invoke(obj, processedArgs); } catch (Exception e) { string errorMessage = instance ? string.Format( Strings.Runtime_HostObjectMethodInvocationFailed, methodName, e.Message) : string.Format( Strings.Runtime_HostTypeMethodInvocationFailed, methodName, typeName, e.Message) ; JsValue undefinedValue = JsValue.Undefined; JsValue errorValue = JsErrorHelpers.CreateError(errorMessage); JsErrorHelpers.SetException(errorValue); return(undefinedValue); } JsValue resultValue = MapToScriptType(result); return(resultValue); }; nativeFunctions.Add(nativeFunction); JsValue methodValue = JsValue.CreateFunction(nativeFunction); typeValue.SetProperty(methodName, methodValue, true); } }
private static void CreateAndSetReferenceError(string message) { JsValue errorValue = JsErrorHelpers.CreateReferenceError(message); JsErrorHelpers.SetException(errorValue); }
private EmbeddedType CreateEmbeddedType(Type type) { #if NET40 Type typeInfo = type; #else TypeInfo typeInfo = type.GetTypeInfo(); #endif string typeName = type.FullName; BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(true); ConstructorInfo[] constructors = type.GetConstructors(defaultBindingFlags); JsNativeFunction nativeConstructorFunction = (callee, isConstructCall, args, argCount, callbackData) => { object result; JsValue resultValue; object[] processedArgs = GetHostItemMemberArguments(args); if (processedArgs.Length == 0 && typeInfo.IsValueType) { result = Activator.CreateInstance(type); resultValue = MapToScriptType(result); return(resultValue); } if (constructors.Length == 0) { JsValue undefinedValue = JsValue.Undefined; JsValue errorValue = JsErrorHelpers.CreateError( string.Format(Strings.Runtime_HostTypeConstructorNotFound, typeName)); JsErrorHelpers.SetException(errorValue); return(undefinedValue); } var bestFitConstructor = (ConstructorInfo)ReflectionHelpers.GetBestFitMethod( constructors, processedArgs); if (bestFitConstructor == null) { JsValue undefinedValue = JsValue.Undefined; JsValue errorValue = JsErrorHelpers.CreateReferenceError( string.Format(Strings.Runtime_SuitableConstructorOfHostTypeNotFound, typeName)); JsErrorHelpers.SetException(errorValue); return(undefinedValue); } ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitConstructor.GetParameters()); try { result = bestFitConstructor.Invoke(processedArgs); } catch (Exception e) { JsValue undefinedValue = JsValue.Undefined; JsValue errorValue = JsErrorHelpers.CreateError( string.Format(Strings.Runtime_HostTypeConstructorInvocationFailed, typeName, e.Message)); JsErrorHelpers.SetException(errorValue); return(undefinedValue); } resultValue = MapToScriptType(result); return(resultValue); }; GCHandle embeddedTypeHandle = GCHandle.Alloc(type); IntPtr embeddedTypePtr = GCHandle.ToIntPtr(embeddedTypeHandle); JsValue objValue = JsValue.CreateExternalObject(embeddedTypePtr, _embeddedTypeFinalizeCallback); JsValue typeValue = JsValue.CreateFunction(nativeConstructorFunction); SetNonEnumerableProperty(typeValue, ExternalObjectPropertyName, objValue); var embeddedType = new EmbeddedType(type, typeValue, new List <JsNativeFunction> { nativeConstructorFunction }); ProjectFields(embeddedType); ProjectProperties(embeddedType); ProjectMethods(embeddedType); FreezeObject(typeValue); return(embeddedType); }