Exemplo n.º 1
0
		public void InferFromMethodReturnType()
		{
			// static void M<T>(Func<T> f) {}
			// M(Console.ReadKey); // type inference produces ConsoleKeyInfo
			
			var T = new DefaultTypeParameter(compilation, SymbolKind.Method, 0, "T");
			
			IType declType = compilation.FindType(typeof(Console));
			var methods = new MethodListWithDeclaringType(declType, declType.GetMethods(m => m.Name == "ReadKey"));
			var argument = new MethodGroupResolveResult(new TypeResolveResult(declType), "ReadKey", new[] { methods }, new IType[0]);
			
			bool success;
			Assert.AreEqual(
				new [] { compilation.FindType(typeof(ConsoleKeyInfo)) },
				ti.InferTypeArguments(new [] { T }, new [] { argument },
				                      new [] { new ParameterizedType(compilation.FindType(typeof(Func<>)).GetDefinition(), new[] { T }) },
				                      out success));
			Assert.IsTrue(success);
		}
Exemplo n.º 2
0
		public void CannotInferFromMethodParameterTypes()
		{
			// static void M<A, B>(Func<A, B> f) {}
			// M(int.Parse); // type inference fails
			var A = new DefaultTypeParameter(compilation, SymbolKind.Method, 0, "A");
			var B = new DefaultTypeParameter(compilation, SymbolKind.Method, 1, "B");
			
			IType declType = compilation.FindType(typeof(int));
			var methods = new MethodListWithDeclaringType(declType, declType.GetMethods(m => m.Name == "Parse"));
			var argument = new MethodGroupResolveResult(new TypeResolveResult(declType), "Parse", new[] { methods }, new IType[0]);
			
			bool success;
			ti.InferTypeArguments(new [] { A, B }, new [] { argument },
			                      new [] { new ParameterizedType(compilation.FindType(typeof(Func<,>)).GetDefinition(), new[] { A, B }) },
			                      out success);
			Assert.IsFalse(success);
		}
Exemplo n.º 3
0
		/// <summary>
		/// Looks up the indexers on the target type.
		/// </summary>
		public IList<MethodListWithDeclaringType> LookupIndexers(IType targetType)
		{
			bool allowProtectedAccess = IsProtectedAccessAllowed(targetType);
			Predicate<IProperty> filter = delegate(IProperty property) {
				return property.IsIndexer && IsAccessible(property, allowProtectedAccess);
			};
			
			List<LookupGroup> lookupGroups = new List<LookupGroup>();
			foreach (IType type in targetType.GetNonInterfaceBaseTypes(context)) {
				List<IParameterizedMember> newMethods = null;
				IMember newNonMethod = null;
				
				IEnumerable<IType> typeBaseTypes = null;
				
				var members = type.GetProperties(context, filter, GetMemberOptions.IgnoreInheritedMembers);
				AddMembers(type, members, lookupGroups, true, ref typeBaseTypes, ref newMethods, ref newNonMethod);
				
				if (newMethods != null || newNonMethod != null)
					lookupGroups.Add(new LookupGroup(type, null, newMethods, newNonMethod));
			}
			
			// Remove interface members hidden by class members.
			if (targetType.Kind == TypeKind.TypeParameter) {
				// This can happen only with type parameters.
				RemoveInterfaceMembersHiddenByClassMembers(lookupGroups);
			}
			
			// Remove all hidden groups
			lookupGroups.RemoveAll(g => g.MethodsAreHidden || g.Methods.Count == 0);
			
			MethodListWithDeclaringType[] methodLists = new MethodListWithDeclaringType[lookupGroups.Count];
			for (int i = 0; i < methodLists.Length; i++) {
				methodLists[i] = new MethodListWithDeclaringType(lookupGroups[i].DeclaringType, lookupGroups[i].Methods);
			}
			return methodLists;
		}
Exemplo n.º 4
0
		ResolveResult CreateResult(ResolveResult targetResolveResult, List<LookupGroup> lookupGroups, string name, IList<IType> typeArguments)
		{
			// Remove all hidden groups
			lookupGroups.RemoveAll(g => g.AllHidden);
			
			if (lookupGroups.Count == 0) {
				// No members found
				return new UnknownMemberResolveResult(targetResolveResult.Type, name, typeArguments);
			}
			
			if (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0)) {
				// If there are methods, make a MethodGroupResolveResult.
				// Note that a conflict between a member and a method (possible with multiple interface inheritance)
				// is only a warning, not an error, and the C# compiler will prefer the method group.
				List<MethodListWithDeclaringType> methodLists = new List<MethodListWithDeclaringType>();
				foreach (var lookupGroup in lookupGroups) {
					if (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0) {
						var methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType);
						foreach (var method in lookupGroup.Methods) {
							methodListWithDeclType.Add((IMethod)method);
						}
						methodLists.Add(methodListWithDeclType);
					}
				}
				
				return new MethodGroupResolveResult(targetResolveResult, name, methodLists, typeArguments);
			}
			
			// If there are ambiguities, report the most-derived result (last group)
			LookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1];
			if (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0) {
				if (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1)
					return new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]);
				else
					return new TypeResolveResult(resultGroup.NestedTypes[0]);
			}
			
			if (lookupGroups.Count > 1) {
				return new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod,
				                                        resultGroup.NonMethod.ReturnType.Resolve(context));
			} else {
				return new MemberResolveResult(targetResolveResult, resultGroup.NonMethod, context);
			}
		}
Exemplo n.º 5
0
		/// <summary>
		/// Looks up the indexers on the target type.
		/// </summary>
		public IList<MethodListWithDeclaringType> LookupIndexers(ResolveResult targetResolveResult)
		{
			if (targetResolveResult == null)
				throw new ArgumentNullException("targetResolveResult");
			
			IType targetType = targetResolveResult.Type;
			bool allowProtectedAccess = IsProtectedAccessAllowed(targetResolveResult);
			Predicate<IUnresolvedProperty> filter = p => p.IsIndexer;
			
			List<LookupGroup> lookupGroups = new List<LookupGroup>();
			foreach (IType type in targetType.GetNonInterfaceBaseTypes()) {
				List<IParameterizedMember> newMethods = null;
				IMember newNonMethod = null;
				
				IEnumerable<IType> typeBaseTypes = null;
				
				var members = type.GetProperties(filter, GetMemberOptions.IgnoreInheritedMembers);
				AddMembers(type, members, allowProtectedAccess, lookupGroups, true, ref typeBaseTypes, ref newMethods, ref newNonMethod);
				
				if (newMethods != null || newNonMethod != null)
					lookupGroups.Add(new LookupGroup(type, null, newMethods, newNonMethod));
			}
			
			// Remove interface members hidden by class members.
			if (targetType.Kind == TypeKind.TypeParameter) {
				// This can happen only with type parameters.
				RemoveInterfaceMembersHiddenByClassMembers(lookupGroups);
			}
			
			// Remove all hidden groups
			lookupGroups.RemoveAll(g => g.MethodsAreHidden || g.Methods.Count == 0);
			
			MethodListWithDeclaringType[] methodLists = new MethodListWithDeclaringType[lookupGroups.Count];
			for (int i = 0; i < methodLists.Length; i++) {
				methodLists[i] = new MethodListWithDeclaringType(lookupGroups[i].DeclaringType, lookupGroups[i].Methods);
			}
			return methodLists;
		}