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 (resultGroup.NonMethod.IsStatic && targetResolveResult is ThisResolveResult) { targetResolveResult = new TypeResolveResult(targetResolveResult.Type); } if (lookupGroups.Count > 1) { return new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod); } else { if (isInEnumMemberInitializer) { IField field = resultGroup.NonMethod as IField; if (field != null && field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum) { return new MemberResolveResult( targetResolveResult, field, field.DeclaringTypeDefinition.EnumUnderlyingType, field.IsConst, field.ConstantValue); } } return new MemberResolveResult(targetResolveResult, resultGroup.NonMethod); } }
public override ResolveResult Resolve(CSharpResolver resolver) { ResolveResult rr; if (targetType != null) rr = new TypeResolveResult(targetType.Resolve(resolver.Context)); else rr = targetExpression.Resolve(resolver); return resolver.ResolveMemberAccess(rr, memberName, ConstantIdentifierReference.ResolveTypes(resolver, typeArguments)); }
public AliasTypeResolveResult(string alias, TypeResolveResult underlyingResult) : base (underlyingResult.Type) { this.Alias = alias; }
public bool IsVariableReferenceWithSameType(ResolveResult rr, string identifier, out TypeResolveResult trr) { if (!(rr is MemberResolveResult || rr is LocalResolveResult)) { trr = null; return false; } trr = LookupSimpleNameOrTypeName (identifier, EmptyList<IType>.Instance, NameLookupMode.Type) as TypeResolveResult; return trr != null && trr.Type.Equals (rr.Type); }
/// <summary> /// Resolves an invocation. /// </summary> /// <param name="target">The target of the invocation. Usually a MethodGroupResolveResult.</param> /// <param name="arguments"> /// Arguments passed to the method. /// The resolver may mutate this array to wrap elements in <see cref="ConversionResolveResult"/>s! /// </param> /// <param name="argumentNames"> /// The argument names. Pass the null string for positional arguments. /// </param> /// <returns>InvocationResolveResult or UnknownMethodResolveResult</returns> public ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arguments, string[] argumentNames = null) { // C# 4.0 spec: §7.6.5 if (target.Type.Kind == TypeKind.Dynamic) { return new DynamicInvocationResolveResult(target, DynamicInvocationType.Invocation, AddArgumentNamesIfNecessary(arguments, argumentNames)); } MethodGroupResolveResult mgrr = target as MethodGroupResolveResult; if (mgrr != null) { if (arguments.Any(a => a.Type.Kind == TypeKind.Dynamic)) { // If we have dynamic arguments, we need to represent the invocation as a dynamic invocation if there is more than one applicable method. var or2 = CreateOverloadResolution(arguments, argumentNames, mgrr.TypeArguments.ToArray()); var applicableMethods = mgrr.MethodsGroupedByDeclaringType.SelectMany(m => m, (x, m) => new { x.DeclaringType, Method = m }).Where(x => OverloadResolution.IsApplicable(or2.AddCandidate(x.Method))).ToList(); if (applicableMethods.Count > 1) { ResolveResult actualTarget; if (applicableMethods.All(x => x.Method.IsStatic) && !(mgrr.TargetResult is TypeResolveResult)) actualTarget = new TypeResolveResult(mgrr.TargetType); else actualTarget = mgrr.TargetResult; var l = new List<MethodListWithDeclaringType>(); foreach (var m in applicableMethods) { if (l.Count == 0 || l[l.Count - 1].DeclaringType != m.DeclaringType) l.Add(new MethodListWithDeclaringType(m.DeclaringType)); l[l.Count - 1].Add(m.Method); } return new DynamicInvocationResolveResult(new MethodGroupResolveResult(actualTarget, mgrr.MethodName, l, mgrr.TypeArguments), DynamicInvocationType.Invocation, AddArgumentNamesIfNecessary(arguments, argumentNames)); } } OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, checkForOverflow: checkForOverflow, conversions: conversions); if (or.BestCandidate != null) { if (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeResolveResult)) return or.CreateResolveResult(new TypeResolveResult(mgrr.TargetType)); else return or.CreateResolveResult(mgrr.TargetResult); } else { // No candidate found at all (not even an inapplicable one). // This can happen with empty method groups (as sometimes used with extension methods) return new UnknownMethodResolveResult( mgrr.TargetType, mgrr.MethodName, mgrr.TypeArguments, CreateParameters(arguments, argumentNames)); } } UnknownMemberResolveResult umrr = target as UnknownMemberResolveResult; if (umrr != null) { return new UnknownMethodResolveResult(umrr.TargetType, umrr.MemberName, umrr.TypeArguments, CreateParameters(arguments, argumentNames)); } UnknownIdentifierResolveResult uirr = target as UnknownIdentifierResolveResult; if (uirr != null && CurrentTypeDefinition != null) { return new UnknownMethodResolveResult(CurrentTypeDefinition, uirr.Identifier, EmptyList<IType>.Instance, CreateParameters(arguments, argumentNames)); } IMethod invokeMethod = target.Type.GetDelegateInvokeMethod(); if (invokeMethod != null) { OverloadResolution or = CreateOverloadResolution(arguments, argumentNames); or.AddCandidate(invokeMethod); return new CSharpInvocationResolveResult( target, invokeMethod, //invokeMethod.ReturnType.Resolve(context), or.GetArgumentsWithConversionsAndNames(), or.BestCandidateErrors, isExpandedForm: or.BestCandidateIsExpandedForm, isDelegateInvocation: true, argumentToParameterMap: or.GetArgumentToParameterMap()); } return ErrorResult; }
public ResolveResult LookupMethodName(TypeResolveResult typeResolveResult, string typeName, string name) { if(!BVE5ResourceManager.BuiltinTypeHasMethod(typeName, name)) return new UnknownMemberResolveResult(GetBuitlinType(typeName), name, EmptyList<IType>.Instance); var type_def = typeResolveResult.Type as ITypeDefinition; if(type_def == null) throw new Exception("Internal: target type is not a type definition!"); return new MethodGroupResolveResult(typeResolveResult, name, new List<IMethod>(type_def.GetMethods((member) => member.Name == name))); }
public override ResolveResult Resolve(CppResolver resolver) { ResolveResult rr; if (targetType != null) rr = new TypeResolveResult(targetType.Resolve(resolver.CurrentTypeResolveContext)); else rr = targetExpression.Resolve(resolver); return resolver.ResolveMemberAccess(rr, memberName, typeArguments.Resolve(resolver.CurrentTypeResolveContext)); }