public IReadOnlyList<MethodGroup> DiscoverTestMethodGroups(Assembly assembly) { RunContext.Set(options); var conventions = new ConventionDiscoverer(assembly).GetConventions(); var discoveredTestMethodGroups = new List<MethodGroup>(); foreach (var convention in conventions) { var classDiscoverer = new ClassDiscoverer(convention); var candidateTypes = assembly.GetTypes(); var testClasses = classDiscoverer.TestClasses(candidateTypes); var methodDiscoverer = new MethodDiscoverer(convention); foreach (var testClass in testClasses) { var distinctMethodGroups = new Dictionary<string, MethodGroup>(); foreach (var testMethod in methodDiscoverer.TestMethods(testClass)) { var methodGroup = new MethodGroup(testMethod); distinctMethodGroups[methodGroup.FullName] = methodGroup; } discoveredTestMethodGroups.AddRange(distinctMethodGroups.Values); } } return discoveredTestMethodGroups; }
static PythonStandardModuleMethodGroupResolveResult Create(MethodGroup methods) { MethodGroup[] methodGroups = new MethodGroup[] { methods }; IMethod method = methods[0]; IReturnType returnType = new DefaultReturnType(method.DeclaringType); return new PythonStandardModuleMethodGroupResolveResult(returnType, method.Name, methodGroups); }
public void Init() { PythonStandardModuleType moduleType = new PythonStandardModuleType(typeof(SysModule), "sys"); completionItems = new SysModuleCompletionItems(moduleType); exitMethodGroup = completionItems.GetMethods("exit"); displayHookMethodGroup = completionItems.GetMethods("displayhook"); }
static IEnumerable<MethodInfo> GetMethods(Assembly assembly, MethodGroup methodGroup) { return assembly .GetType(methodGroup.Class) .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.Name == methodGroup.Method); }
/// <summary> /// Default ctor /// </summary> internal MethodRenamer(TargetFramework target) { // Build groups foreach (var method in target.MethodMap.AllMethods.Where(x => !(x.IsStatic || x.IsConstructor))) { if (method.MethodGroup != null) continue; var possibleGroups = method.Overrides.Select(x => x.MethodGroup).Where(x => x != null).Distinct().ToList(); while (possibleGroups.Count > 1) { var sourceIndex = possibleGroups.Count - 1; possibleGroups[0].MergeFrom(possibleGroups[sourceIndex]); possibleGroups.RemoveAt(sourceIndex); } var group = possibleGroups.SingleOrDefault(); if (group == null) { // Create new group group = new MethodGroup(method.Name); groups.Add(group); } // Add method to group group.Add(method); // Add all overrides to group group.AddRange(method.Overrides); } }
private TestResult GetTestResult(MethodGroup methodGroup, TestStatus status, string reason = null) { return new TestResult { Assembly = _assembly.Name, Class = methodGroup.Class, Method = methodGroup.Method, Namespace = methodGroup.FullName, Reason = reason, Status = status, Test = string.Format("{0}.{1}", methodGroup.Class, methodGroup.Method) }; }
public bool TryGetSourceLocation(MethodGroup methodGroup, out SourceLocation sourceLocation) { if (types == null) types = CacheTypes(assemblyPath); sourceLocation = null; var className = methodGroup.Class; var methodName = methodGroup.Method; SequencePoint sequencePoint; if (TryGetSequencePoint(className, methodName, out sequencePoint)) sourceLocation = new SourceLocation(sequencePoint.Document.Url, sequencePoint.StartLine); return sourceLocation != null; }
public bool TryGetSourceLocation(MethodGroup methodGroup, out SourceLocation sourceLocation) { if (types == null) types = CacheTypes(assemblyPath); var className = methodGroup.Class; var methodName = methodGroup.Method; sourceLocation = GetMethods(className) .Where(m => m.Name == methodName) .Select(FirstOrDefaultSequencePoint) .Where(x => x != null) .OrderBy(x => x.StartLine) .Select(x => new SourceLocation(x.Document.Url, x.StartLine)) .FirstOrDefault(); return sourceLocation != null; }
/// <summary> /// Populates the object with functions by searching a .NET type for methods marked with /// the [JSFunction] attribute. Should be called only once at startup. /// </summary> /// <param name="type"> The type to search for methods. </param> internal protected void PopulateFunctions(Type type) { if (type == null) type = this.GetType(); // Group the methods on the given type by name. var functions = new Dictionary<string, MethodGroup>(20); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (var method in methods) { // Make sure the method has the [JSFunction] attribute. var attribute = (JSFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(JSFunctionAttribute)); if (attribute == null) continue; // Determine the name of the method. string name; if (attribute.Name != null) { name = Compiler.Lexer.ResolveIdentifier(this.Engine, attribute.Name); if (name == null) throw new InvalidOperationException(string.Format("The name provided to [JSFunction] on {0} is not a valid identifier.", method)); } else name = method.Name; // Get a reference to the method group. MethodGroup methodGroup; if (functions.ContainsKey(name) == false) { methodGroup = new MethodGroup { Methods = new List<JSBinderMethod>(1), Length = -1 }; functions.Add(name, methodGroup); } else methodGroup = functions[name]; // Add the method to the list. methodGroup.Methods.Add(new JSBinderMethod(method, attribute.Flags)); // If the length doesn't equal -1, that indicates an explicit length has been set. // Make sure it is consistant with the other methods. if (attribute.Length >= 0) { if (methodGroup.Length != -1 && methodGroup.Length != attribute.Length) throw new InvalidOperationException(string.Format("Inconsistant Length property detected on {0}.", method)); methodGroup.Length = attribute.Length; } } // Now set the relevant properties on the object. foreach (KeyValuePair<string, MethodGroup> pair in functions) { string name = pair.Key; MethodGroup methodGroup = pair.Value; // Add the function as a property of the object. this.FastSetProperty(name, new ClrFunction(this.Engine.Function.InstancePrototype, methodGroup.Methods, name, methodGroup.Length), PropertyAttributes.NonEnumerable); } PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (PropertyInfo prop in properties) { var attribute = Attribute.GetCustomAttribute(prop, typeof(JSPropertyAttribute), false) as JSPropertyAttribute; if (attribute == null) continue; string name; if (!string.IsNullOrEmpty(attribute.Name)) { name = Compiler.Lexer.ResolveIdentifier(this.Engine, attribute.Name); if (name == null) throw new InvalidOperationException(string.Format("The name provided to [JSProperty] on {0} is not a valid identifier.", prop)); } else { name = prop.Name; } ClrFunction getter = null, setter = null; PropertyAttributes descriptorAttributes = PropertyAttributes.Sealed; if (prop.CanRead) { var getMethod = prop.GetGetMethod(true); getter = new ClrFunction(engine.Function.InstancePrototype, new ClrBinder(getMethod)); descriptorAttributes |= PropertyAttributes.IsAccessorProperty; } if (prop.CanWrite) { var setMethod = prop.GetSetMethod(); setter = new ClrFunction(engine.Function.InstancePrototype, new ClrBinder(setMethod)); descriptorAttributes |= PropertyAttributes.Writable; } if (attribute.IsEnumerable) descriptorAttributes |= PropertyAttributes.Enumerable; if (attribute.IsConfigurable) descriptorAttributes |= PropertyAttributes.Configurable; PropertyDescriptor descriptor = new PropertyDescriptor(getter, setter, descriptorAttributes); this.DefineProperty(name, descriptor, true); } }
/// <summary> /// Populates the object with functions by searching a .NET type for methods marked with /// the [JSFunction] attribute. Should be called only once at startup. Also automatically /// populates properties marked with the [JSProperty] attribute. /// </summary> /// <param name="type"> The type to search for methods. </param> /// <param name="bindingFlags"> The binding flags to use to search for properties and methods. </param> internal protected void PopulateFunctions(Type type, BindingFlags bindingFlags) { if (type == null) type = this.GetType(); // Group the methods on the given type by name. var functions = new Dictionary<string, MethodGroup>(20); var methods = type.GetMethods(bindingFlags); foreach (var method in methods) { // Make sure the method has the [JSInternalFunction] attribute. var attribute = (JSFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(JSFunctionAttribute)); if (attribute == null) continue; // Determine the name of the method. string name; if (attribute.Name != null) name = attribute.Name; else name = method.Name; // Get a reference to the method group. MethodGroup methodGroup; if (functions.ContainsKey(name) == false) { methodGroup = new MethodGroup { Methods = new List<JSBinderMethod>(1), Length = -1 }; functions.Add(name, methodGroup); } else methodGroup = functions[name]; // Internal functions return nulls as undefined. if (attribute is JSInternalFunctionAttribute) attribute.Flags |= JSFunctionFlags.ConvertNullReturnValueToUndefined; // Add the method to the list. methodGroup.Methods.Add(new JSBinderMethod(method, attribute.Flags)); // If the length doesn't equal -1, that indicates an explicit length has been set. // Make sure it is consistant with the other methods. if (attribute.Length >= 0) { if (methodGroup.Length != -1 && methodGroup.Length != attribute.Length) throw new InvalidOperationException(string.Format("Inconsistant Length property detected on {0}.", method)); methodGroup.Length = attribute.Length; } // Check property attributes. var descriptorAttributes = PropertyAttributes.Sealed; if (attribute.IsEnumerable) descriptorAttributes |= PropertyAttributes.Enumerable; if (attribute.IsConfigurable) descriptorAttributes |= PropertyAttributes.Configurable; if (attribute.IsWritable) descriptorAttributes |= PropertyAttributes.Writable; if (methodGroup.Methods.Count > 1 && methodGroup.PropertyAttributes != descriptorAttributes) throw new InvalidOperationException(string.Format("Inconsistant property attributes detected on {0}.", method)); methodGroup.PropertyAttributes = descriptorAttributes; } // Now set the relevant properties on the object. foreach (KeyValuePair<string, MethodGroup> pair in functions) { string name = pair.Key; MethodGroup methodGroup = pair.Value; // Add the function as a property of the object. this.FastSetProperty(name, new ClrFunction(this.Engine.Function.InstancePrototype, methodGroup.Methods, name, methodGroup.Length), methodGroup.PropertyAttributes); } PropertyInfo[] properties = type.GetProperties(bindingFlags); foreach (PropertyInfo prop in properties) { var attribute = Attribute.GetCustomAttribute(prop, typeof(JSPropertyAttribute), false) as JSPropertyAttribute; if (attribute == null) continue; // The property name. string name; if (attribute.Name != null) name = attribute.Name; else name = prop.Name; // The property getter. ClrFunction getter = null; if (prop.CanRead) { var getMethod = prop.GetGetMethod(true); getter = new ClrFunction(engine.Function.InstancePrototype, new JSBinderMethod[] { new JSBinderMethod(getMethod) }, name, 0); } // The property setter. ClrFunction setter = null; if (prop.CanWrite) { var setMethod = prop.GetSetMethod((bindingFlags & BindingFlags.NonPublic) != 0); if (setMethod != null) setter = new ClrFunction(engine.Function.InstancePrototype, new JSBinderMethod[] { new JSBinderMethod(setMethod) }, name, 1); } // The property attributes. var descriptorAttributes = PropertyAttributes.Sealed; if (attribute.IsEnumerable) descriptorAttributes |= PropertyAttributes.Enumerable; if (attribute.IsConfigurable) descriptorAttributes |= PropertyAttributes.Configurable; // Define the property. var descriptor = new PropertyDescriptor(getter, setter, descriptorAttributes); this.DefineProperty(name, descriptor, true); } }
static MethodInfo[] GetMethods(Assembly assembly, MethodGroup[] methodGroups) { return methodGroups.SelectMany(methodGroup => GetMethods(assembly, methodGroup)).ToArray(); }
internal override void Bind(Binder binder) { // We have a series of temporary variables, so we will need // to discard them after the call is made binder.Bookmark(); // We have the process // Eval arg i, assign variable i, eval arg i+1, assign variable i+1 // so if we, for instance, bind every argument, then bind every temp // variable, we are sure to clobber our own arguments for (int i = 0; i < Arguments.Length; i++) { Arguments[i].Bind(binder); binder.BindVariable(ArgumentVariables[i]); } binder.Checkout(); bool fullyResolvedTypes; if (Callee == null) { fullyResolvedTypes = FunctionName.GetKnownType() != null; } else { fullyResolvedTypes = Callee.GetKnownType() != null; } RedwoodType[] argumentTypes = new RedwoodType[Arguments.Length]; for (int i = 0; i < Arguments.Length; i++) { argumentTypes[i] = Arguments[i].GetKnownType(); // Not really sure whether we care about this, but it might be useful // for compiling variable assignments ArgumentVariables[i].KnownType = argumentTypes[i]; fullyResolvedTypes &= argumentTypes[i] != null; } // If we have fully resolved types (ie. all argument types are known // and so is the callee type) we definitely know the return type FullyResolved = fullyResolvedTypes; // We have two options for determining an exact type, either: // 1) The method is fully resolved. One lambda type will come out of // the many, // or // 2) the method is not fully resolved, but the provided arguments // narrow the methods down a single option. if (Callee == null) { LambdaType = FunctionName.GetKnownType(); // If we have a lambda group, we should try to resolve it ResolveLambdaGroupOverload(argumentTypes); } else if (Callee.GetKnownType() == null) { LambdaType = null; } else if (Callee.GetKnownType().CSharpType == null) { LambdaType = Callee .GetKnownType() .GetKnownTypeOfMember(FunctionName.Name); // Make sure that calls to class functions also have the correct // lambda type ResolveLambdaGroupOverload(argumentTypes); } else if (Callee.GetKnownType().CSharpType == typeof(RedwoodType)) { if (!Callee.Constant) { LambdaType = null; } else if (Callee.EvaluateConstant() is RedwoodType calleeType) { if (calleeType.CSharpType == null) { LambdaType = calleeType .GetKnownTypeForStaticMember(FunctionName.Name); ResolveLambdaGroupOverload(argumentTypes); } else { MethodInfo[] infos; bool methodExists = MemberResolver.TryResolveMethod( null, calleeType, FunctionName.Name, true, out infos); if (!methodExists) { throw new NotImplementedException(); } BindExternal(infos); } } else { // This should never happen? throw new NotImplementedException(); } } else { MethodInfo[] infos; bool methodExists = MemberResolver.TryResolveMethod( null, Callee.GetKnownType(), FunctionName.Name, false, out infos); if (!methodExists) { // TODO: Can an object have a lambda field? throw new NotImplementedException(); } BindExternal(infos); } void BindExternal(MethodInfo[] infos) { ExternalMethodGroup = new MethodGroup(infos); ExternalMethodGroup.SelectOverloads(argumentTypes); if (ExternalMethodGroup.infos.Length == 0) { throw new NotImplementedException(); } else if (ExternalMethodGroup.infos.Length == 1) { RedwoodType returnType = RedwoodType.GetForCSharpType(ExternalMethodGroup.infos[0].ReturnType); RedwoodType[] paramTypes = ExternalMethodGroup.infos[0].GetParameters() .Select(param => RedwoodType.GetForCSharpType(param.ParameterType)) .ToArray(); LambdaType = RedwoodType.GetForLambdaArgsTypes( typeof(ExternalLambda), returnType, paramTypes); } } }
protected override void Create(MethodGroup methodGroup) { var userSort = Choice("UsersOrderBy", new[] { "id", "name", "path", "created_at", "updated_at", "last_activity_at", "repository_size", "storage_size", "packages_size", "wiki_size" }); methodGroup.AddMethod("GetAll", MethodType.GetPaged, "/projects", "https://docs.gitlab.com/ee/api/projects.html#list-all-projects") .WithReturnType(Models.Project) .AddOptionalParameter("archived", ModelRef.Boolean) .AddOptionalParameter("visibility", Models.Visibility) .AddOptionalParameter("search", ModelRef.String) .AddOptionalParameter("simple", ModelRef.Boolean) .AddOptionalParameter("owned", ModelRef.Boolean) .AddOptionalParameter("membership", ModelRef.Boolean) .AddOptionalParameter("starred", ModelRef.Boolean) .AddOptionalParameter("statistics", ModelRef.Boolean) .AddOptionalParameter("with_issues_enabled", ModelRef.Boolean) .AddOptionalParameter("with_merge_requests_enabled", ModelRef.Boolean) .AddOptionalParameter("wiki_checksum_failed", ModelRef.Boolean) .AddOptionalParameter("repository_checksum_failed", ModelRef.Boolean) .AddOptionalParameter("min_access_level", Models.AccessLevel) .AddOptionalParameter("order_by", userSort) .AddOptionalParameter("sort", Models.OrderByDirection) ; methodGroup.AddMethod("GetByUser", MethodType.GetPaged, "/users/:user_id/projects", "https://docs.gitlab.com/ee/api/projects.html#list-user-projects") .WithReturnType(Models.Project) .AddRequiredParameter("user_id", Models.UserIdOrUserNameRef) .AddOptionalParameter("archived", ModelRef.Boolean) .AddOptionalParameter("visibility", Models.Visibility) .AddOptionalParameter("search", ModelRef.String) .AddOptionalParameter("simple", ModelRef.Boolean) .AddOptionalParameter("owned", ModelRef.Boolean) .AddOptionalParameter("membership", ModelRef.Boolean) .AddOptionalParameter("starred", ModelRef.Boolean) .AddOptionalParameter("statistics", ModelRef.Boolean) .AddOptionalParameter("with_issues_enabled", ModelRef.Boolean) .AddOptionalParameter("with_merge_requests_enabled", ModelRef.Boolean) .AddOptionalParameter("min_access_level", Models.AccessLevel) .AddOptionalParameter("order_by", userSort) .AddOptionalParameter("sort", Models.OrderByDirection) ; methodGroup.AddMethod("GetById", MethodType.Get, "/projects/:id", "https://docs.gitlab.com/ee/api/projects.html#get-single-project") .WithReturnType(Models.Project) .AddRequiredParameter("id", Models.ProjectIdOrPathRef) ; methodGroup.AddMethod("Create", MethodType.Post, "/projects", "https://docs.gitlab.com/ee/api/projects.html#create-project") .WithReturnType(Models.Project) .AddOptionalParameter("name", ModelRef.String) .AddOptionalParameter("path", ModelRef.String) .AddOptionalParameter("namespace_id", ModelRef.NumberId) .AddOptionalParameter("default_branch", ModelRef.String) .AddOptionalParameter("description", ModelRef.String) .AddOptionalParameter("issues_enabled", ModelRef.Boolean) .AddOptionalParameter("merge_requests_enabled", ModelRef.Boolean) .AddOptionalParameter("jobs_enabled", ModelRef.Boolean) .AddOptionalParameter("wiki_enabled", ModelRef.Boolean) .AddOptionalParameter("snippets_enabled", ModelRef.Boolean) .AddOptionalParameter("resolve_outdated_diff_discussions", ModelRef.Boolean) .AddOptionalParameter("container_registry_enabled", ModelRef.Boolean) .AddOptionalParameter("shared_runners_enabled", ModelRef.Boolean) .AddOptionalParameter("public_builds", ModelRef.Boolean) .AddOptionalParameter("only_allow_merge_if_pipeline_succeeds", ModelRef.Boolean) .AddOptionalParameter("only_allow_merge_if_all_discussions_are_resolved", ModelRef.Boolean) .AddOptionalParameter("request_access_enabled", ModelRef.Boolean) .AddOptionalParameter("lfs_enabled", ModelRef.Boolean) .AddOptionalParameter("printing_merge_request_link_enabled", ModelRef.Boolean) .AddOptionalParameter("merge_method", Models.MergeMethod) .AddOptionalParameter("visibility", Models.Visibility) .AddOptionalParameter("tag_list", ModelRef.StringCollection) .AddOptionalParameter("ci_config_path", ModelRef.String) .AddOptionalParameter("approvals_before_merge", ModelRef.Number) ; methodGroup.AddMethod("UploadFile", MethodType.Post, "/projects/:id/uploads", "https://docs.gitlab.com/ee/api/projects.html#upload-a-file") .WithReturnType(Models.RepositoryFileUploaded) .AddRequiredParameter("id", Models.ProjectIdOrPathRef) .AddRequiredParameter("file", ModelRef.FileUpload) ; }
public ExecuteInEditModeSceneCommand(MonoBehaviour[] mono) : base(0) { SceneCommandName = "Execute In Edit Mode"; selected = new MethodGroup[mono.Length]; int i = 0; foreach (var behaviour in mono) { Type type = behaviour.GetType(); MethodInfo awake = type.GetMethod("Awake", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default); if (awake != null) { awake.Invoke(behaviour, null); } MethodInfo onEnable = type.GetMethod("OnEnable", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default); if (onEnable != null) { onEnable.Invoke(behaviour, null); } MethodInfo start = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default); if (start != null) { start.Invoke(behaviour, null); } MethodGroup group = new MethodGroup(); group.Behaviour = behaviour; MethodInfo fixedUpdate = type.GetMethod("FixedUpdate", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default); if (fixedUpdate != null) { group.updateMethods.Add(fixedUpdate); } MethodInfo update = type.GetMethod("Update", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default); if (update != null) { group.updateMethods.Add(update); } MethodInfo lateUpdate = type.GetMethod("LateUpdate", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default); if (lateUpdate != null) { group.updateMethods.Add(lateUpdate); } selected[i] = group; i++; } }
public NCGroup FindMethod(string method) { return(MethodGroup.Find(a => a.Name.Equals(method, StringComparison.CurrentCultureIgnoreCase))); }
protected override void Visit(MethodGroup group) { VisitList(group.Members); }
protected override void Create(MethodGroup methodGroup) { methodGroup.AddMethod("Get", MethodType.Get, "/version", "https://docs.gitlab.com/ee/api/version.html#version-api") .WithReturnType(Models.ServerVersion) ; }
protected abstract void Create(MethodGroup methodGroup);
static void AssertMethodGroup(MethodGroup actual, string expectedClass, string expectedMethod, string expectedFullName) { actual.Class.ShouldEqual(expectedClass); actual.Method.ShouldEqual(expectedMethod); actual.FullName.ShouldEqual(expectedFullName); }
public RunnableActionAttribute(MethodGroup group) { Group = group; }
private static ICandidate[] CreateCandidates([NotNull] string rangeStartText, MethodGroup overloads, int argsCount) { var methods = overloads.Methods; switch (rangeStartText) { case "<": return(methods.Select(m => new FSharpTypeArgumentCandidate(overloads.MethodName, m)).ToArray <ICandidate>()); default: return(methods .Select(m => new FSharpParameterInfoCandidate(m, argsCount > 1 && m.Parameters.Length < argsCount)) .ToArray <ICandidate>()); } }
public AssemblyResult RunMethods(Assembly assembly, MethodGroup[] methodGroups) { return RunMethods(assembly, GetMethods(assembly, methodGroups)); }
static Error ValidateMethod(string name, MethodGroup value, IEnumerable<MethodInfo> methods) { methods = methods.Where(m => m.Name == name).ToArray(); if (!value.All(mock => methods.Any(m => mock.RepresentsMethod(m)))) return new Error(Errors.CannotFindMethodToOverride, "Cannot find method \"" + name + "\" with the given parameters to mock."); return null; }
TestCase TestCase(MethodGroup methodGroup) { return(new TestCase(methodGroup.FullName, VsTestExecutor.Uri, assemblyPath)); }
/// <summary> /// Generates example code from an x-ms-examples section. /// </summary> public virtual string GenerateSample(bool isolateSnippet, CodeModel cm, MethodGroup g, Method m, string exampleName, Model.XmsExtensions.Example example) => null;
public AssemblyResult RunMethods(string assemblyFullPath, Options options, Listener listener, MethodGroup[] methodGroups) { var assembly = LoadAssembly(assemblyFullPath); return Runner(options, listener).RunMethods(assembly, methodGroups); }
internal JSValue proxyMember(bool forWrite, IList <MemberInfo> m) { JSValue r = null; if (m.Count > 1) { for (int i = 0; i < m.Count; i++) { if (!(m[i] is MethodBase)) { ExceptionHelper.Throw(_context.ProxyValue(new TypeError("Incompatible fields types."))); } } var cache = new MethodProxy[m.Count]; for (int i = 0; i < m.Count; i++) { cache[i] = new MethodProxy(_context, m[i] as MethodBase); } r = new MethodGroup(cache); } else { #if PORTABLE || NETCORE switch (m[0].GetMemberType()) #else switch (m[0].MemberType) #endif { case MemberTypes.Method: { var method = (MethodInfo)m[0]; r = new MethodProxy(_context, method); r._attributes &= ~(JSValueAttributesInternal.ReadOnly | JSValueAttributesInternal.DoNotDelete | JSValueAttributesInternal.NonConfigurable | JSValueAttributesInternal.DoNotEnumerate); break; } case MemberTypes.Field: { var field = (m[0] as FieldInfo); if ((field.Attributes & (FieldAttributes.Literal | FieldAttributes.InitOnly)) != 0 && (field.Attributes & FieldAttributes.Static) != 0) { r = _context.ProxyValue(field.GetValue(null)); r._attributes |= JSValueAttributesInternal.ReadOnly; } else { r = new JSValue() { _valueType = JSValueType.Property, _oValue = new PropertyPair ( new ExternalFunction((thisBind, a) => _context.ProxyValue(field.GetValue(field.IsStatic ? null : thisBind.Value))), !m[0].IsDefined(typeof(ReadOnlyAttribute), false) ? new ExternalFunction((thisBind, a) => { field.SetValue(field.IsStatic ? null : thisBind.Value, a[0].Value); return(null); }) : null ) }; r._attributes = JSValueAttributesInternal.Immutable | JSValueAttributesInternal.Field; if ((r._oValue as PropertyPair).setter == null) { r._attributes |= JSValueAttributesInternal.ReadOnly; } } break; } case MemberTypes.Property: { var pinfo = (PropertyInfo)m[0]; r = new JSValue() { _valueType = JSValueType.Property, _oValue = new PropertyPair ( #if (PORTABLE || NETCORE) pinfo.CanRead && pinfo.GetMethod != null ? new MethodProxy(_context, pinfo.GetMethod) : null, pinfo.CanWrite && pinfo.SetMethod != null && !pinfo.IsDefined(typeof(ReadOnlyAttribute), false) ? new MethodProxy(_context, pinfo.SetMethod) : null #else pinfo.CanRead&& pinfo.GetGetMethod(false) != null ? new MethodProxy(_context, pinfo.GetGetMethod(false)) : null, pinfo.CanWrite && pinfo.GetSetMethod(false) != null && !pinfo.IsDefined(typeof(ReadOnlyAttribute), false) ? new MethodProxy(_context, pinfo.GetSetMethod(false)) : null #endif ) }; r._attributes = JSValueAttributesInternal.Immutable; if ((r._oValue as PropertyPair).setter == null) { r._attributes |= JSValueAttributesInternal.ReadOnly; } if (pinfo.IsDefined(typeof(FieldAttribute), false)) { r._attributes |= JSValueAttributesInternal.Field; } break; } case MemberTypes.Event: { var pinfo = (EventInfo)m[0]; r = new JSValue() { _valueType = JSValueType.Property, _oValue = new PropertyPair ( null, #if (PORTABLE || NETCORE) new MethodProxy(_context, pinfo.AddMethod) #else new MethodProxy(_context, pinfo.GetAddMethod()) #endif ) }; break; } case MemberTypes.TypeInfo: #if (PORTABLE || NETCORE) { r = GetConstructor((m[0] as TypeInfo).AsType()); break; } #else case MemberTypes.NestedType: { r = _context.GetConstructor((Type)m[0]); break; } default: throw new NotImplementedException("Convertion from " + m[0].MemberType + " not implemented"); #endif } } if (m[0].IsDefined(typeof(DoNotEnumerateAttribute), false)) { r._attributes |= JSValueAttributesInternal.DoNotEnumerate; } if (forWrite && r.NeedClone) { r = r.CloneImpl(false); } for (var i = m.Count; i-- > 0;) { if (!m[i].IsDefined(typeof(DoNotEnumerateAttribute), false)) { r._attributes &= ~JSValueAttributesInternal.DoNotEnumerate; } if (m[i].IsDefined(typeof(ReadOnlyAttribute), false)) { r._attributes |= JSValueAttributesInternal.ReadOnly; } if (m[i].IsDefined(typeof(NotConfigurable), false)) { r._attributes |= JSValueAttributesInternal.NonConfigurable; } if (m[i].IsDefined(typeof(DoNotDeleteAttribute), false)) { r._attributes |= JSValueAttributesInternal.DoNotDelete; } } return(r); }
public PythonStandardModuleMethodGroupResolveResult(IReturnType containingType, string methodName, MethodGroup[] methodGroups) : base(null, null, containingType, methodName, methodGroups) { }
void MockMethod(string name, IMethodMock method) { MethodGroup existingMock = null; if (Values.ContainsKey(name)) { existingMock = Values[name] as MethodGroup; if (existingMock == null) throw new InvalidMockException("The member \"" + name + "\" has already been set as a parameter and cannot be mocked now as a method"); //TODM } if (existingMock == null) { existingMock = new MethodGroup(method); SetMember(name, existingMock); } else { //TODM: if a method is mocked twice, the second mock will take precedence existingMock.Insert(0, method); } }
public Method(MethodGroup group, string name, Datatype returnDatatype = null) { Group = group; Name = name; ReturnDatatype = returnDatatype; }
/// <summary> /// Adds the given method to the prototype. /// </summary> private void AddMethod(MethodBase method, Type type, int staticMode) { // Get the properties attribute if it's got one: var attribute = (JSProperties)Attribute.GetCustomAttribute(method, typeof(JSProperties)); if (attribute != null && attribute.Hidden) { return; } // Determine the name of the method. string name; if (attribute != null && attribute.Name != null) { name = attribute.Name; } else { name = method.Name; } // Reject properties (but not constructors): if (method.IsSpecialName && name != ".ctor") { return; } ParameterInfo[] mParams = null; if (method.IsStatic && staticMode != 0) { // If it's static and it does not have a 'thisObj' property // then it's a constructor level static function, IF the object has a constructor at all. mParams = method.GetParameters(); if (mParams.Length > 0) { if (mParams[0].Name == "thisObj" || (mParams.Length > 1 && mParams[1].Name == "thisObj")) { // Not actually static. if (staticMode == 2) { return; } } else if (staticMode == 1) { return; } } } bool enumerable = true; if (name == "OnConstruct" || name == ".ctor") { name = ".make"; enumerable = false; } else if (name == "OnCall") { name = ".call"; enumerable = false; } // Special case for get_ or set_ methods - we want them to act like properties. // Chop off get_ or set_ here (so the actual name entering the proto is correct) // then when the user attempts to use it like a property, it checks then. int actLikeProperty = 0; if (name.StartsWith("get_")) { name = name.Substring(4); actLikeProperty = 1; } else if (name.StartsWith("set_")) { name = name.Substring(4); actLikeProperty = 2; } // For methods, auto == lowercase. if (attribute == null) { name = char.ToLower(name[0]) + name.Substring(1); } else { // For methods, auto == lowercase if (attribute.FirstCharacter == CaseMode.Upper) { name = char.ToUpper(name[0]) + name.Substring(1); } else if (attribute.FirstCharacter == CaseMode.Lower || attribute.FirstCharacter == CaseMode.Auto) { name = char.ToLower(name[0]) + name.Substring(1); } } if (actLikeProperty != 0) { if (name == "_Item") { // Rename! Actually got an indexer here. name = "___item"; if (mParams == null) { mParams = method.GetParameters(); } // Skip thisObj and engine if they're set: for (int i = 0; i < mParams.Length; i++) { ParameterInfo p = mParams[i]; if (i < 2) { // Skip special parameters. if (p.Name == "thisObj" || (i == 0 && p.ParameterType == typeof(ScriptEngine))) { continue; } } // Append the type name: name += "_" + p.ParameterType.Name; } } else if (name == "_Properties") { // Rename! Got the property enumerator here. name = "___properties"; } } // Check property attributes. Nitrassic.Library.PropertyAttributes descriptorAttributes = Nitrassic.Library.PropertyAttributes.Sealed; if (attribute != null && attribute.IsEnumerable && enumerable) { descriptorAttributes |= Nitrassic.Library.PropertyAttributes.Enumerable; } if (attribute == null || attribute.IsConfigurable) { descriptorAttributes |= Nitrassic.Library.PropertyAttributes.Configurable; } if (attribute == null || attribute.IsWritable) { descriptorAttributes |= Nitrassic.Library.PropertyAttributes.Writable; } // Already defined this property? PropertyVariable property = GetProperty(name); if (property == null) { // Add as a single method, optionally as a virtual property: object propertyValue; if (actLikeProperty == 0) { // Straight apply the method: propertyValue = method; } else { // Create a virtual property: VirtualProperty vProperty = new VirtualProperty(); // Apply the method: if (actLikeProperty == 1) { vProperty.GetMethod = method; vProperty.LoadMeta(); } else { vProperty.SetMethod = method; } // Apply virtual property as the value: propertyValue = vProperty; } property = AddProperty(name, propertyValue, descriptorAttributes); } else if (actLikeProperty != 0) { // Got the other method in a property. VirtualProperty vProperty = property.ConstantValue as VirtualProperty; // Apply the method: if (actLikeProperty == 1) { vProperty.GetMethod = method; vProperty.LoadMeta(); } else { vProperty.SetMethod = method; } } else { // Already a method set? MethodGroup group = property.ConstantValue as MethodGroup; if (group == null) { // Create a method group and add the current method to it: group = new MethodGroup(); // Set the attributes: group.PropertyAttributes = descriptorAttributes; // Add the method: group.Add(property.ConstantValue as MethodBase); // Force the property to change type: property.ForceChange(group); } // Add this method to the group: group.Add(method); if (group.PropertyAttributes != descriptorAttributes) { throw new InvalidOperationException("Inconsistant property attributes detected on " + method + "."); } } }
/// <summary> /// Populates the object with functions by searching a .NET type for methods marked with /// the [JSFunction] attribute. Should be called only once at startup. /// </summary> /// <param name="type"> The type to search for methods. </param> internal protected void PopulateFunctions(Type type) { if (type == null) type = this.GetType(); // Group the methods on the given type by name. var functions = new Dictionary<string, MethodGroup>(20); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (var method in methods) { // Make sure the method has the [JSFunction] attribute. var attribute = (JSFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(JSFunctionAttribute)); if (attribute == null) continue; // Determine the name of the method. string name; if (attribute.Name != null) { name = Compiler.Lexer.ResolveIdentifier(this.Engine, attribute.Name); if (name == null) throw new InvalidOperationException(string.Format("The name provided to [JSFunction] on {0} is not a valid identifier.", method)); } else name = method.Name; // Get a reference to the method group. MethodGroup methodGroup; if (functions.ContainsKey(name) == false) { methodGroup = new MethodGroup { Methods = new List<JSBinderMethod>(1), Length = -1 }; functions.Add(name, methodGroup); } else methodGroup = functions[name]; // Add the method to the list. methodGroup.Methods.Add(new JSBinderMethod(method, attribute.Flags)); // If the length doesn't equal -1, that indicates an explicit length has been set. // Make sure it is consistant with the other methods. if (attribute.Length >= 0) { if (methodGroup.Length != -1 && methodGroup.Length != attribute.Length) throw new InvalidOperationException(string.Format("Inconsistant Length property detected on {0}.", method)); methodGroup.Length = attribute.Length; } } // Now set the relevant properties on the object. foreach (KeyValuePair<string, MethodGroup> pair in functions) { string name = pair.Key; MethodGroup methodGroup = pair.Value; // Add the function as a property of the object. this.FastSetProperty(name, new ClrFunction(this.Engine.Function.InstancePrototype, methodGroup.Methods, name, methodGroup.Length), PropertyAttributes.NonEnumerable); } }
TestCase TestCase(MethodGroup methodGroup) { return new TestCase(methodGroup.FullName, VsTestExecutor.Uri, assemblyPath); }
/// <summary> /// Generates sync or async stored procedure mapping method. /// </summary> /// <param name="storedProcedure">Stored procedure model.</param> /// <param name="dataContextType">Data context class type.</param> /// <param name="methodsGroup">Method group to add new mapping method.</param> /// <param name="useOrdinalMapping">If <c>true</c>, by-ordinal mapping used for result mapping instead of by-name mapping.</param> /// <param name="customTable">Custom result record model.</param> /// <param name="returnElementType">Type of result record for procedure with result.</param> /// <param name="customRecordProperties">Column properties for custom result record type.</param> /// <param name="classes">Procedure classes group.</param> /// <param name="asyncResult">Optional result class model for async signature.</param> /// <param name="async">If <c>true</c>, generate async version of mapping.</param> private void BuildStoredProcedureMethod( StoredProcedureModel storedProcedure, IType dataContextType, MethodGroup methodsGroup, bool useOrdinalMapping, ResultTableModel?customTable, IType?returnElementType, CodeProperty[]?customRecordProperties, ClassGroup classes, AsyncProcedureResult?asyncResult, bool async) { var hasParameters = storedProcedure.Parameters.Count > 0 || storedProcedure.Return != null; // generate ToList materialization call or mark method async in two cases: // - when return type of mapping is List<T> // - when procedure has non-input parameters var toListRequired = _options.DataModel.GenerateProcedureResultAsList && storedProcedure.Results.Count == 1 && (storedProcedure.Results[0].Entity != null || storedProcedure.Results[0].CustomTable != null); var toListOrAsyncRequired = toListRequired || storedProcedure.Return != null || storedProcedure.Parameters.Any(p => p.Parameter.Direction != CodeParameterDirection.In); // declare mapping method var method = DefineMethod( methodsGroup, storedProcedure.Method, async, async && toListOrAsyncRequired); // declare data context parameter (extension `this` parameter) var ctxParam = AST.Parameter( // see method notes above regarding type of this parameter dataContextType, AST.Name(STORED_PROCEDURE_CONTEXT_PARAMETER), CodeParameterDirection.In); method.Parameter(ctxParam); var body = method.Body(); // array of procedure parameters (DataParameter objects) CodeVariable?parametersVar = null; CodeAssignmentStatement[]? parameterRebinds = null; Dictionary <FunctionParameterModel, int>?rebindedParametersIndexes = null; if (hasParameters) { var resultParametersCount = storedProcedure.Parameters.Count(p => p.Parameter.Direction != CodeParameterDirection.In) + (storedProcedure.Return != null ? 1 : 0); // bindings of parameter values to output parameters of method after procedure call parameterRebinds = resultParametersCount > 0 ? new CodeAssignmentStatement[resultParametersCount] : Array <CodeAssignmentStatement> .Empty; var rebindIndex = 0; if (resultParametersCount > 0) { rebindedParametersIndexes = new(resultParametersCount); } // DataParameter collection initialization var parameterValues = new ICodeExpression[storedProcedure.Parameters.Count + (storedProcedure.Return != null ? 1 : 0)]; parametersVar = AST.Variable(AST.Name(STORED_PROCEDURE_PARAMETERS_VARIABLE), WellKnownTypes.LinqToDB.Data.DataParameterArray, true); // build non-return parameters for (var i = 0; i < storedProcedure.Parameters.Count; i++) { var p = storedProcedure.Parameters[i]; ILValue?rebindTo = null; var rebindRequired = p.Parameter.Direction != CodeParameterDirection.In; CodeParameter param; if (async && p.Parameter.Direction != CodeParameterDirection.In) { param = DefineParameter(method, p.Parameter.WithDirection(CodeParameterDirection.In)); } else { param = DefineParameter(method, p.Parameter); } if (rebindRequired) { rebindTo = param.Reference; } parameterValues[i] = BuildProcedureParameter( param, param.Type.Type, p.Direction, rebindTo, p.DbName, p.DataType, p.Type, parametersVar, i, parameterRebinds !, rebindIndex); if (p.Parameter.Direction != CodeParameterDirection.In) { rebindedParametersIndexes !.Add(p, rebindIndex); rebindIndex++; } } // build return parameter if (storedProcedure.Return != null) { CodeParameter?param = null; if (!async) { param = DefineParameter(method, storedProcedure.Return.Parameter); } parameterValues[storedProcedure.Parameters.Count] = BuildProcedureParameter( param, storedProcedure.Return.Parameter.Type, System.Data.ParameterDirection.ReturnValue, param?.Reference ?? AST.Variable(AST.Name("fake"), storedProcedure.Return.Parameter.Type, false).Reference, storedProcedure.Return.DbName ?? STORED_PROCEDURE_DEFAULT_RETURN_PARAMETER, storedProcedure.Return.DataType, storedProcedure.Return.Type, parametersVar, storedProcedure.Parameters.Count, parameterRebinds !, rebindIndex); rebindedParametersIndexes !.Add(storedProcedure.Return, rebindIndex); } var parametersArray = AST.Assign( parametersVar, AST.Array(WellKnownTypes.LinqToDB.Data.DataParameter, true, false, parameterValues)); body.Append(parametersArray); } CodeParameter?cancellationTokenParameter = null; if (async) { cancellationTokenParameter = DefineParameter( method, new ParameterModel(CANCELLATION_TOKEN_PARAMETER, WellKnownTypes.System.Threading.CancellationToken, CodeParameterDirection.In), AST.Default(WellKnownTypes.System.Threading.CancellationToken, true)); } ICodeExpression?returnValue = null; IType returnType; if (storedProcedure.Results.Count == 0 || (storedProcedure.Results.Count == 1 && storedProcedure.Results[0].CustomTable == null && storedProcedure.Results[0].Entity == null)) { // for stored procedure call without result set we use ExecuteProc API // prepare call parameters var parametersCount = (hasParameters ? 3 : 2) + (async ? 1 : 0); var executeProcParameters = new ICodeExpression[parametersCount]; executeProcParameters[0] = ctxParam.Reference; executeProcParameters[1] = AST.Constant(BuildFunctionName(storedProcedure.Name), true); if (async) { executeProcParameters[2] = cancellationTokenParameter !.Reference; } if (hasParameters) { executeProcParameters[async ? 3 : 2] = parametersVar !.Reference; } returnType = WellKnownTypes.System.Int32; if (async) { returnValue = AST.ExtCall( WellKnownTypes.LinqToDB.Data.DataConnectionExtensions, WellKnownTypes.LinqToDB.Data.DataConnectionExtensions_ExecuteProcAsync, WellKnownTypes.System.Int32, executeProcParameters); if (asyncResult != null) { var rowCountVar = AST.Variable( AST.Name(STORED_PROCEDURE_RESULT_VARIABLE), WellKnownTypes.System.Int32, true); body.Append(AST.Assign(rowCountVar, AST.AwaitExpression(returnValue))); returnValue = rowCountVar.Reference; } } else { returnValue = AST.ExtCall( WellKnownTypes.LinqToDB.Data.DataConnectionExtensions, WellKnownTypes.LinqToDB.Data.DataConnectionExtensions_ExecuteProc, WellKnownTypes.System.Int32, executeProcParameters); } } else if (storedProcedure.Results.Count == 1) { // QueryProc type- and regular parameters IType[] queryProcTypeArgs; ICodeExpression[] queryProcParameters; if (useOrdinalMapping) { // for ordinal mapping we call QueryProc API with mapper lambda parameter: // manual mapping // Example: /* * dataReader => new CustomResult() * { * Column1 = Converter.ChangeTypeTo<int>(dataReader.GetValue(0), dataConnection.MappingSchema), * Column2 = Converter.ChangeTypeTo<string>(dataReader.GetValue(1), dataConnection.MappingSchema), * } */ queryProcParameters = new ICodeExpression[(hasParameters ? 4 : 3) + (async ? 1 : 0)]; // generate positional mapping lambda // TODO: switch to ColumnReader.GetValue in future to utilize more precise mapping // based on column mapping attributes var drParam = AST.LambdaParameter( AST.Name(STORED_PROCEDURE_CUSTOM_MAPPER_PARAMETER), // TODO: add IDataReader support here for linq2db v3 WellKnownTypes.System.Data.Common.DbDataReader); var initializers = new CodeAssignmentStatement[customTable !.Columns.Count];