示例#1
0
        IEnumerable <IMethod> CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult)
        {
            var  lookup     = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
            bool onlyStatic = false;

            if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic || resolveResult.TargetResult is TypeResolveResult)
            {
                onlyStatic = true;
            }
            foreach (var method in resolveResult.Methods)
            {
                if (method.IsConstructor)
                {
                    continue;
                }
                if (!lookup.IsAccessible(method, true))
                {
                    continue;
                }
                if (onlyStatic && !method.IsStatic)
                {
                    continue;
                }
                yield return(method);
            }

            foreach (var extMethods in resolveResult.GetEligibleExtensionMethods(true))
            {
                foreach (var method in extMethods)
                {
                    yield return(method);
                }
            }
        }
            public override void VisitTypeDeclaration(TypeDeclaration declaration)
            {
                base.VisitTypeDeclaration(declaration);
                var result = ctx.Resolve(declaration) as TypeResolveResult;

                if (result == null || result.IsError)
                {
                    return;
                }
                var baseType = result.Type.DirectBaseTypes.FirstOrDefault(t => !t.IsKnownType(KnownTypeCode.Object) && t.Kind != TypeKind.Interface);

                if (baseType != null)
                {
                    var baseConstructor = baseType.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();
                    var memberLookup    = new MemberLookup(result.Type.GetDefinition(), ctx.Compilation.MainAssembly, false);

                    if (baseConstructor == null || !memberLookup.IsAccessible(baseConstructor, true))
                    {
                        var constructor = result.Type.GetConstructors(f => !f.IsSynthetic).FirstOrDefault();

                        if (constructor == null)
                        {
                            // If there are no constructors declared then the base constructor isn't being invoked
                            this.AddIssue(declaration, baseType);
                        }
                    }
                }
            }
        public ConstructorParameterDataProvider(int startOffset, CSharpCompletionTextEditorExtension ext, IType type, AstNode skipInitializer = null) : base(startOffset, ext)
        {
            this.type = type;

            var ctx = ext.CSharpUnresolvedFile.GetTypeResolveContext(ext.UnresolvedFileCompilation, ext.Document.Editor.Caret.Location) as CSharpTypeResolveContext;

            var  lookup             = new MemberLookup(ctx.CurrentTypeDefinition, ext.Compilation.MainAssembly);
            bool isProtectedAllowed = false;
            var  typeDefinition     = type.GetDefinition();

            if (ctx.CurrentTypeDefinition != null && typeDefinition != null)
            {
                isProtectedAllowed = ctx.CurrentTypeDefinition.IsDerivedFrom(ctx.CurrentTypeDefinition.Compilation.Import(typeDefinition));
            }
            foreach (var method in type.GetConstructors())
            {
                if (!lookup.IsAccessible(method, isProtectedAllowed))
                {
                    continue;
                }
                if (!method.IsBrowsable())
                {
                    continue;
                }
                if (skipInitializer != null && skipInitializer.Parent.StartLocation == method.Region.Begin)
                {
                    continue;
                }
                methods.Add(method);
            }
            methods.Sort(MethodComparer);
        }
示例#4
0
        OverloadResolutionErrors IsUnambiguousCall(ExpectedTargetDetails expectedTargetDetails, IMethod method,
                                                   TranslatedExpression target, IType[] typeArguments, IList <TranslatedExpression> arguments)
        {
            var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
            var or     = new OverloadResolution(resolver.Compilation, arguments.SelectArray(a => a.ResolveResult), typeArguments: typeArguments);

            if (expectedTargetDetails.CallOpCode == OpCode.NewObj)
            {
                foreach (IMethod ctor in method.DeclaringType.GetConstructors())
                {
                    if (lookup.IsAccessible(ctor, allowProtectedAccess: resolver.CurrentTypeDefinition == method.DeclaringTypeDefinition))
                    {
                        or.AddCandidate(ctor);
                    }
                }
            }
            else
            {
                var result = lookup.Lookup(target.ResolveResult, method.Name, EmptyList <IType> .Instance, true) as MethodGroupResolveResult;
                if (result == null)
                {
                    return(OverloadResolutionErrors.AmbiguousMatch);
                }
                or.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray());
            }
            if (or.BestCandidateErrors != OverloadResolutionErrors.None)
            {
                return(or.BestCandidateErrors);
            }
            if (!IsAppropriateCallTarget(expectedTargetDetails, method, or.GetBestCandidateWithSubstitutedTypeArguments()))
            {
                return(OverloadResolutionErrors.AmbiguousMatch);
            }
            return(OverloadResolutionErrors.None);
        }
            public override void VisitConstructorDeclaration(ConstructorDeclaration declaration)
            {
                var result = ctx.Resolve(declaration) as MemberResolveResult;

                if (result == null || result.IsError)
                {
                    return;
                }

                var baseType = result.Member.DeclaringType.DirectBaseTypes.FirstOrDefault(t => !t.IsKnownType(KnownTypeCode.Object) && t.Kind != TypeKind.Interface);

                if (baseType != null)
                {
                    var baseConstructor = baseType.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();
                    var memberLookup    = new MemberLookup(result.Member.DeclaringType.GetDefinition(), ctx.Compilation.MainAssembly, false);

                    if (baseConstructor == null || !memberLookup.IsAccessible(baseConstructor, true))
                    {
                        this.initializerInvoked = false;
                        this.initializer        = null;

                        base.VisitConstructorDeclaration(declaration);

                        if (!this.initializerInvoked)
                        {
                            int argumentCount = initializer != null ? initializer.Arguments.Count : 0;
                            this.AddIssue(declaration, baseType, argumentCount);
                        }
                    }
                }
            }
        IEnumerable <IProperty> GetAccessibleIndexers(IType type)
        {
            var lookup     = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
            var properties = new List <IProperty>();

            foreach (var property in type.GetProperties())
            {
                if (!property.IsIndexer)
                {
                    continue;
                }
                if (!lookup.IsAccessible(property, true))
                {
                    continue;
                }
                if (property.IsShadowing)
                {
                    for (int j = 0; j < properties.Count; j++)
                    {
                        if (ParameterListComparer.Instance.Equals(properties[j].Parameters, property.Parameters))
                        {
                            properties.RemoveAt(j);
                            j--;
                        }
                    }
                }

                properties.Add(property);
            }
            return(properties);
        }
示例#7
0
        IEnumerable <CodeAction> GetActionsForExtensionMethodInvocation(RefactoringContext context, InvocationExpression invocation)
        {
            var rr = context.Resolve(invocation) as UnknownMethodResolveResult;

            if (rr == null)
            {
                return(EmptyList <CodeAction> .Instance);
            }

            var lookup = new MemberLookup(null, context.Compilation.MainAssembly);
            HashSet <string>  namespaces = new HashSet <string>();
            List <CodeAction> result     = new List <CodeAction>();

            foreach (var typeDefinition in context.Compilation.GetAllTypeDefinitions())
            {
                if (!(typeDefinition.HasExtensionMethods && lookup.IsAccessible(typeDefinition, false)))
                {
                    continue;
                }
                foreach (var method in typeDefinition.Methods.Where(m => m.IsExtensionMethod && m.Name == rr.MemberName))
                {
                    IType[] inferredTypes;
                    if (CSharpResolver.IsEligibleExtensionMethod(rr.TargetType, method, true, out inferredTypes))
                    {
                        // avoid offering the same namespace twice
                        if (namespaces.Add(typeDefinition.Namespace))
                        {
                            result.Add(NewUsingAction(context, invocation, typeDefinition.Namespace));
                        }
                        break;                         // continue with the next type
                    }
                }
            }
            return(result);
        }
示例#8
0
        private IEnumerable <IMethod> FilterMethodsForAccessibility(IType type, IEnumerable <IMethod> methods)
        {
            var  typeResolveContext     = context.TypeResolveContextAtCaret;
            var  lookup                 = new MemberLookup(typeResolveContext.CurrentTypeDefinition, typeResolveContext.Compilation.MainAssembly);
            bool protectedAccessAllowed = lookup.IsProtectedAccessAllowed(type);

            return(protectedAccessAllowed ? methods : methods.Where(x => !x.IsProtected));
        }
示例#9
0
        TranslatedExpression HandleDelegateConstruction(CallInstruction inst)
        {
            ILInstruction func = inst.Arguments[1];
            IMethod       method;

            switch (func.OpCode)
            {
            case OpCode.LdFtn:
                method = ((LdFtn)func).Method;
                break;

            case OpCode.LdVirtFtn:
                method = ((LdVirtFtn)func).Method;
                break;

            default:
                method = (IMethod)typeSystem.Resolve(((ILFunction)func).Method);
                break;
            }
            var target = expressionBuilder.TranslateTarget(method, inst.Arguments[0], func.OpCode == OpCode.LdFtn);
            var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
            var or     = new OverloadResolution(resolver.Compilation, method.Parameters.SelectArray(p => new TypeResolveResult(p.Type)));
            var result = lookup.Lookup(target.ResolveResult, method.Name, method.TypeArguments, true) as MethodGroupResolveResult;

            if (result == null)
            {
                target = target.ConvertTo(method.DeclaringType, expressionBuilder);
            }
            else
            {
                or.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray());
                if (or.BestCandidateErrors != OverloadResolutionErrors.None || !IsAppropriateCallTarget(method, or.BestCandidate, func.OpCode == OpCode.LdVirtFtn))
                {
                    target = target.ConvertTo(method.DeclaringType, expressionBuilder);
                }
            }

            var mre = new MemberReferenceExpression(target, method.Name);

            mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
            var oce = new ObjectCreateExpression(expressionBuilder.ConvertType(inst.Method.DeclaringType), mre)
                      //				.WithAnnotation(new DelegateConstruction.Annotation(func.OpCode == OpCode.LdVirtFtn, target, method.Name))
                      .WithILInstruction(inst)
                      .WithRR(new ConversionResolveResult(
                                  inst.Method.DeclaringType,
                                  new MemberResolveResult(target.ResolveResult, method),
                                  // TODO handle extension methods capturing the first argument
                                  Conversion.MethodGroupConversion(method, func.OpCode == OpCode.LdVirtFtn, false)));

            if (func is ILFunction)
            {
                return(expressionBuilder.TranslateFunction(oce, target, (ILFunction)func));
            }
            else
            {
                return(oce);
            }
        }
        IEnumerable <IMethod> CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult)
        {
            var  lookup     = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
            bool onlyStatic = false;

            if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic || resolveResult.TargetResult is TypeResolveResult)
            {
                onlyStatic = true;
            }
            var methods = new List <IMethod>();

            foreach (var method in resolveResult.Methods)
            {
                if (method.IsConstructor)
                {
                    continue;
                }
                if (!lookup.IsAccessible(method, true))
                {
                    continue;
                }
                if (onlyStatic && !method.IsStatic)
                {
                    continue;
                }
                if (method.IsShadowing)
                {
                    for (int j = 0; j < methods.Count; j++)
                    {
                        if (ParameterListComparer.Instance.Equals(methods[j].Parameters, method.Parameters))
                        {
                            methods.RemoveAt(j);
                            j--;
                        }
                    }
                }
                methods.Add(method);
            }
            foreach (var m in methods)
            {
                yield return(m);
            }
            foreach (var extMethods in resolveResult.GetEligibleExtensionMethods(true))
            {
                foreach (var method in extMethods)
                {
                    if (methods.Contains(method))
                    {
                        continue;
                    }
                    yield return(new ReducedExtensionMethod(method));
                }
            }
        }
示例#11
0
        ExpressionWithResolveResult HandleAccessorCall(ExpectedTargetDetails expectedTargetDetails, IMethod method, TranslatedExpression target, IList <TranslatedExpression> arguments)
        {
            var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
            var result = lookup.Lookup(target.ResolveResult, method.AccessorOwner.Name, EmptyList <IType> .Instance, isInvocation: false);

            if (result.IsError || (result is MemberResolveResult && !IsAppropriateCallTarget(expectedTargetDetails, method.AccessorOwner, ((MemberResolveResult)result).Member)))
            {
                target = target.ConvertTo(method.AccessorOwner.DeclaringType, expressionBuilder);
            }
            var rr = new MemberResolveResult(target.ResolveResult, method.AccessorOwner);

            if (method.ReturnType.IsKnownType(KnownTypeCode.Void))
            {
                var value = arguments.Last();
                arguments.Remove(value);
                TranslatedExpression expr;
                if (arguments.Count == 0)
                {
                    expr = new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name)
                           .WithoutILInstruction().WithRR(rr);
                }
                else
                {
                    expr = new IndexerExpression(target.Expression, arguments.Select(a => a.Expression))
                           .WithoutILInstruction().WithRR(rr);
                }
                var op          = AssignmentOperatorType.Assign;
                var parentEvent = method.AccessorOwner as IEvent;
                if (parentEvent != null)
                {
                    if (method.Equals(parentEvent.AddAccessor))
                    {
                        op = AssignmentOperatorType.Add;
                    }
                    if (method.Equals(parentEvent.RemoveAccessor))
                    {
                        op = AssignmentOperatorType.Subtract;
                    }
                }
                return(new AssignmentExpression(expr, op, value.Expression).WithRR(new TypeResolveResult(method.AccessorOwner.ReturnType)));
            }
            else
            {
                if (arguments.Count == 0)
                {
                    return(new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name).WithRR(rr));
                }
                else
                {
                    return(new IndexerExpression(target.Expression, arguments.Select(a => a.Expression)).WithRR(rr));
                }
            }
        }
            string GetCountProperty(ITypeDefinition currentTypeDefinition, ResolveResult targetResolveResult)
            {
                var memberLookup = new MemberLookup(currentTypeDefinition, ctx.Compilation.MainAssembly);

                string countProperty = TryProperty(memberLookup, targetResolveResult, "Count");

                if (countProperty != null)
                {
                    return(countProperty);
                }

                return(TryProperty(memberLookup, targetResolveResult, "Length"));
            }
示例#13
0
            bool CanIndex(ITypeDefinition currentTypeDefinition, ResolveResult targetResolveResult)
            {
                if (targetResolveResult.Type is ArrayType)
                {
                    return(true);
                }

                var memberLookup = new MemberLookup(currentTypeDefinition, ctx.Compilation.MainAssembly);
                var indexers     = memberLookup.LookupIndexers(targetResolveResult).ToList();

                return(indexers.SelectMany(methodList => methodList).Any(
                           member => ((IProperty)member).CanGet && ((IProperty)member).Getter.Parameters.Count == 1));
            }
示例#14
0
        /// <summary>
        /// Resolves an object creation.
        /// </summary>
        /// <param name="type">Type of the object to create.</param>
        /// <param name="arguments">
        /// Arguments passed to the constructor.
        /// The resolver may mutate this array to wrap elements in <see cref="CastExpression"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <param name="allowProtectedAccess">
        /// Whether to allow calling protected constructors.
        /// This should be false except when resolving constructor initializers.
        /// </param>
        /// <param name="initializerStatements">
        /// Statements for Objects/Collections initializer.
        /// <see cref="InvocationExpression.InitializerStatements"/>
        /// </param>
        /// <returns>InvocationResolveResult or ErrorResolveResult</returns>
        public static Expression ResolveObjectCreation(ResolveContext rc, Location l, IType type, Expression[] arguments, string[] argumentNames = null, bool allowProtectedAccess = false, IList <Expression> initializerStatements = null)
        {
            if (type.Kind == TypeKind.Delegate)
            {
                if (arguments == null || arguments.Length != 1)
                {
                    rc.Report.Error(0, l, "Method name expected");
                    return(null);
                }
                Expression input  = arguments[0];
                IMethod    invoke = input.Type.GetDelegateInvokeMethod();
                if (invoke != null)
                {
                    input = new MethodGroupExpression(
                        input, invoke.Name,
                        methods: new[] { new MethodListWithDeclaringType(input.Type)
                                         {
                                             invoke
                                         } },
                        typeArguments: EmptyList <IType> .Instance
                        );
                }
                return(rc.Convert(input, type));
            }
            OverloadResolution or            = rc.CreateOverloadResolution(arguments, argumentNames);
            MemberLookup       lookup        = rc.CreateMemberLookup();
            List <IMethod>     allApplicable = null;

            foreach (IMethod ctor in type.GetConstructors())
            {
                if (lookup.IsAccessible(ctor, allowProtectedAccess))
                {
                    or.AddCandidate(ctor);
                }
                else
                {
                    or.AddCandidate(ctor, OverloadResolutionErrors.Inaccessible);
                }
            }
            if (or.BestCandidate != null)
            {
                return(or.CreateInvocation(null, initializerStatements));
            }
            else
            {
                rc.Report.Error(0, l,
                                "The type `{0}' does not contain a constructor that takes `{1}' arguments",
                                type.ToString(), arguments != null ? arguments.Length.ToString() : "0");
                return(ErrorResult);
            }
        }
示例#15
0
 public void AddNamespace(MemberLookup lookup, INamespace ns)
 {
     if (usedNamespaces.Contains(ns.Name))
     {
         return;
     }
     if (!IsAccessible(lookup, ns))
     {
         usedNamespaces.Add(ns.Name);
         return;
     }
     usedNamespaces.Add(ns.Name);
     result.Add(Factory.CreateNamespaceCompletionData(ns));
 }
示例#16
0
 bool IsUnambiguousAccess(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method)
 {
     if (target == null)
     {
         var result = resolver.ResolveSimpleName(method.AccessorOwner.Name, EmptyList <IType> .Instance, isInvocationTarget: false) as MemberResolveResult;
         return(!(result == null || result.IsError || !IsAppropriateCallTarget(expectedTargetDetails, method.AccessorOwner, result.Member)));
     }
     else
     {
         var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
         var result = lookup.Lookup(target, method.AccessorOwner.Name, EmptyList <IType> .Instance, isInvocation: false) as MemberResolveResult;
         return(!(result == null || result.IsError || !IsAppropriateCallTarget(expectedTargetDetails, method.AccessorOwner, result.Member)));
     }
 }
示例#17
0
 bool IsAccessible(MemberLookup lookup, INamespace ns)
 {
     if (ns.Types.Any(t => lookup.IsAccessible(t, false)))
     {
         return(true);
     }
     foreach (var child in ns.ChildNamespaces)
     {
         if (IsAccessible(lookup, child))
         {
             return(true);
         }
     }
     return(false);
 }
示例#18
0
        Expression LookInCurrentType(ResolveContext rc, string identifier, IList <IType> typeArguments, NameLookupMode lookupMode, bool parameterizeResultType)
        {
            int          k      = typeArguments.Count;
            MemberLookup lookup = rc.CreateMemberLookup(lookupMode);

            // look in current type definitions
            for (ITypeDefinition t = rc.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition)
            {
                if (k == 0)
                {
                    // Look for type parameter with that name
                    var typeParameters = t.TypeParameters;
                    // Look at all type parameters, including those copied from outer classes,
                    // so that we can fetch the version with the correct owner.
                    for (int i = 0; i < typeParameters.Count; i++)
                    {
                        if (typeParameters[i].Name == identifier)
                        {
                            return(new TypeExpression(typeParameters[i], Location));
                        }
                    }
                }

                if (lookupMode == NameLookupMode.BaseTypeReference && t == rc.CurrentTypeDefinition)
                {
                    // don't look in current type when resolving a base type reference
                    continue;
                }

                Expression r;
                if (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget)
                {
                    Expression targetResolveResult = (t == rc.CurrentTypeDefinition ? (Expression) new SelfReference(t, Location) : new TypeExpression(t, Location));
                    r = lookup.Lookup(targetResolveResult, identifier, typeArguments, lookupMode == NameLookupMode.InvocationTarget);
                }
                else
                {
                    r = lookup.LookupType(t, identifier, typeArguments, parameterizeResultType);
                }

                if (!(r is UnknownMemberExpression)) // but do return AmbiguousMemberResolveResult
                {
                    return(r);
                }
            }
            return(null);
        }
            bool BaseTypeHasUsableParameterlessConstructor()
            {
                var memberLookup      = new MemberLookup(currentType.GetDefinition(), ctx.Compilation.MainAssembly);
                OverloadResolution or = new OverloadResolution(ctx.Compilation, new ResolveResult[0]);

                foreach (var ctor in baseType.GetConstructors())
                {
                    if (memberLookup.IsAccessible(ctor, allowProtectedAccess: true))
                    {
                        if (or.AddCandidate(ctor) == OverloadResolutionErrors.None)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }
        protected override void Run()
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
            {
                return;
            }
            ITextEditorExtension ext = doc.EditorExtension;

            while (ext != null && !(ext is CompletionTextEditorExtension))
            {
                ext = ext.Next;
            }
            if (ext == null)
            {
                return;
            }

            var dom = doc.Compilation;
            ImportSymbolCache cache = new ImportSymbolCache();
            var lookup = new MemberLookup(null, doc.Compilation.MainAssembly);

            List <ImportSymbolCompletionData> typeList = new List <ImportSymbolCompletionData> ();

            foreach (var type in dom.GetAllTypeDefinitions())
            {
                if (!lookup.IsAccessible(type, false))
                {
                    continue;
                }
                typeList.Add(new ImportSymbolCompletionData(doc, cache, type));
            }

            typeList.Sort(delegate(ImportSymbolCompletionData left, ImportSymbolCompletionData right) {
                return(left.Type.Name.CompareTo(right.Type.Name));
            });


            CompletionDataList completionList = new CompletionDataList();

            completionList.IsSorted = true;
            typeList.ForEach(cd => completionList.Add(cd));

            ((CompletionTextEditorExtension)ext).ShowCompletion(completionList);
        }
            string TryProperty(MemberLookup memberLookup, ResolveResult targetResolveResult, string name)
            {
                var countResolveResult         = memberLookup.Lookup(targetResolveResult, name, EmptyList <IType> .Instance, false);
                var countPropertyResolveResult = countResolveResult as MemberResolveResult;

                if (countPropertyResolveResult == null)
                {
                    return(null);
                }

                var property = countPropertyResolveResult.Member as IProperty;

                if (property == null || !property.CanGet)
                {
                    return(null);
                }

                return(name);
            }
示例#22
0
        /// <summary>
        /// Resolves an indexer access.
        /// </summary>
        /// <param name="target">Target expression.</param>
        /// <param name="arguments">
        /// Arguments passed to the indexer.
        /// The resolver may mutate this array to wrap elements in <see cref="CastExpression"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <returns>ArrayAccessResolveResult, InvocationResolveResult, or ErrorResolveResult</returns>
        public Expression ResolveIndexer(ResolveContext rc, Expression target, Expression[] arguments, string[] argumentNames = null)
        {
            switch (target.Type.Kind)
            {
            case TypeKind.Array:
                // �6.6.1 Array access
                if (argumentNames != null && argumentNames.Length > 0)
                {
                    rc.Report.Error(0, Arguments.args.Where(x => x is NamedArgument).First().loc, "An element access expression cannot use named argument");
                }


                return(new ArrayAccessExpression(((ElementTypeSpec)target.Type).ElementType, target, arguments));

            case TypeKind.Pointer:
                // �.5.3 Pointer element access
                if (argumentNames != null && argumentNames.Length > 0)
                {
                    rc.Report.Error(0, Arguments.args.Where(x => x is NamedArgument).First().loc, "An element access expression cannot use named argument");
                }

                return(new PointerArithmeticExpression(((ElementTypeSpec)target.Type).ElementType, target, arguments));
            }

            // �6.6.2 Indexer access
            MemberLookup lookup   = rc.CreateMemberLookup();
            var          indexers = lookup.LookupIndexers(target);

            OverloadResolution or = rc.CreateOverloadResolution(arguments, argumentNames);

            or.AddMethodLists(indexers);
            if (or.BestCandidate != null)
            {
                return(or.CreateInvocation(target));
            }
            else
            {
                rc.Report.Error(0, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
                                target.Type.ToString());
                return(null);
            }
        }
示例#23
0
        IEnumerable <CodeAction> GetActionsForType(RefactoringContext context, AstNode node)
        {
            var rr = context.Resolve(node) as UnknownIdentifierResolveResult;

            if (rr == null)
            {
                return(EmptyList <CodeAction> .Instance);
            }

            string identifier          = rr.Identifier;
            int    tc                  = rr.TypeArgumentCount;
            string attributeIdentifier = null;

            if (node.Parent is Attribute)
            {
                attributeIdentifier = identifier + "Attribute";
            }

            var lookup = new MemberLookup(null, context.Compilation.MainAssembly);
            List <CodeAction> actions = new List <CodeAction>();

            foreach (var typeDefinition in context.Compilation.GetAllTypeDefinitions())
            {
                if ((typeDefinition.Name == identifier || typeDefinition.Name == attributeIdentifier) &&
                    typeDefinition.TypeParameterCount == tc &&
                    lookup.IsAccessible(typeDefinition, false))
                {
                    if (typeDefinition.DeclaringTypeDefinition == null)
                    {
                        actions.Add(NewUsingAction(context, node, typeDefinition.Namespace));
                    }
                    actions.Add(ReplaceWithFullTypeNameAction(context, node, typeDefinition));
                }
            }
            return(actions);
        }
示例#24
0
        bool IsUnambiguousAccess(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method, out IMember foundMember)
        {
            foundMember = null;
            MemberResolveResult result;

            if (target == null)
            {
                result = resolver.ResolveSimpleName(method.AccessorOwner.Name, EmptyList <IType> .Instance, isInvocationTarget: false) as MemberResolveResult;
            }
            else
            {
                var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
                if (method.AccessorOwner.SymbolKind == SymbolKind.Indexer)
                {
                    // TODO: use OR here, etc.
                    result = null;
                    foreach (var methodList in lookup.LookupIndexers(target))
                    {
                        foreach (var indexer in methodList)
                        {
                            if (IsAppropriateCallTarget(expectedTargetDetails, method.AccessorOwner, indexer))
                            {
                                foundMember = indexer;
                                return(true);
                            }
                        }
                    }
                }
                else
                {
                    result = lookup.Lookup(target, method.AccessorOwner.Name, EmptyList <IType> .Instance, isInvocation: false) as MemberResolveResult;
                }
            }
            foundMember = result?.Member;
            return(!(result == null || result.IsError || !IsAppropriateCallTarget(expectedTargetDetails, method.AccessorOwner, result.Member)));
        }
        static IEnumerable <Tuple <string, bool> > GetPossibleNamespaces(Document doc, AstNode node, ResolveResult resolveResult, DocumentLocation location)
        {
            var unit = doc.ParsedDocument.GetAst <SyntaxTree> ();

            if (unit == null)
            {
                yield break;
            }

            int  tc                    = GetTypeParameterCount(node);
            var  attribute             = unit.GetNodeAt <ICSharpCode.NRefactory.CSharp.Attribute> (location);
            bool isInsideAttributeType = attribute != null && attribute.Type.Contains(location);
            var  compilation           = doc.Compilation;
            var  lookup                = new MemberLookup(null, compilation.MainAssembly);

            if (resolveResult is AmbiguousTypeResolveResult)
            {
                var aResult = resolveResult as AmbiguousTypeResolveResult;
                var file    = doc.ParsedDocument.ParsedFile as CSharpUnresolvedFile;
                var scope   = file.GetUsingScope(location).Resolve(compilation);
                while (scope != null)
                {
                    foreach (var u in scope.Usings)
                    {
                        foreach (var typeDefinition in u.Types)
                        {
                            if (typeDefinition.Name == aResult.Type.Name &&
                                typeDefinition.TypeParameterCount == tc &&
                                lookup.IsAccessible(typeDefinition, false))
                            {
                                yield return(Tuple.Create(typeDefinition.Namespace, true));
                            }
                        }
                    }
                    scope = scope.Parent;
                }
                yield break;
            }

            if (resolveResult is UnknownIdentifierResolveResult)
            {
                var    uiResult = resolveResult as UnknownIdentifierResolveResult;
                string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : null;
                foreach (var typeDefinition in compilation.GetAllTypeDefinitions())
                {
                    if ((typeDefinition.Name == uiResult.Identifier || typeDefinition.Name == possibleAttributeName) && typeDefinition.TypeParameterCount == tc &&
                        lookup.IsAccessible(typeDefinition, false))
                    {
                        if (typeDefinition.DeclaringTypeDefinition != null)
                        {
                            var builder = new TypeSystemAstBuilder(new CSharpResolver(doc.Compilation));
                            yield return(Tuple.Create(builder.ConvertType(typeDefinition.DeclaringTypeDefinition).ToString(), false));
                        }
                        else
                        {
                            yield return(Tuple.Create(typeDefinition.Namespace, true));
                        }
                    }
                }
                yield break;
            }

            if (resolveResult is UnknownMemberResolveResult)
            {
                var    umResult = (UnknownMemberResolveResult)resolveResult;
                string possibleAttributeName = isInsideAttributeType ? umResult.MemberName + "Attribute" : null;
                foreach (var typeDefinition in compilation.GetAllTypeDefinitions().Where(t => t.HasExtensionMethods))
                {
                    foreach (var method in typeDefinition.Methods.Where(m => m.IsExtensionMethod && (m.Name == umResult.MemberName || m.Name == possibleAttributeName)))
                    {
                        IType[] inferredTypes;
                        if (CSharpResolver.IsEligibleExtensionMethod(
                                compilation.Import(umResult.TargetType),
                                method,
                                true,
                                out inferredTypes
                                ))
                        {
                            yield return(Tuple.Create(typeDefinition.Namespace, true));

                            goto skipType;
                        }
                    }
skipType:
                    ;
                }
                yield break;
            }

            if (resolveResult is ErrorResolveResult)
            {
                var identifier = unit != null?unit.GetNodeAt <Identifier> (location) : null;

                if (identifier != null)
                {
                    var uiResult = resolveResult as UnknownIdentifierResolveResult;
                    if (uiResult != null)
                    {
                        string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : null;
                        foreach (var typeDefinition in compilation.GetAllTypeDefinitions())
                        {
                            if ((identifier.Name == uiResult.Identifier || identifier.Name == possibleAttributeName) &&
                                typeDefinition.TypeParameterCount == tc &&
                                lookup.IsAccessible(typeDefinition, false))
                            {
                                yield return(Tuple.Create(typeDefinition.Namespace, true));
                            }
                        }
                    }
                }
                yield break;
            }
        }
示例#26
0
        public Expression ResolveMemberAccess(ResolveContext rc, VSC.AST.Expression target, string identifier, IList <IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression)
        {
            // V# 4.0 spec: §7.6.4

            bool           parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));
            AliasNamespace nrr = target as AliasNamespace;

            if (nrr != null)
            {
                return(ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, parameterizeResultType));
            }

            // TODO:Dynamic Resolution
            //if (target.Type.Kind == TypeKind.Dynamic)
            //    return new DynamicMemberResolveResult(target, identifier);

            MemberLookup lookup = rc.CreateMemberLookup(lookupMode);
            Expression   result;

            switch (lookupMode)
            {
            case NameLookupMode.Expression:
                result = lookup.Lookup(target, identifier, typeArguments, isInvocation: false);
                break;

            case NameLookupMode.InvocationTarget:
                result = lookup.Lookup(target, identifier, typeArguments, isInvocation: true);
                break;

            case NameLookupMode.Type:
            case NameLookupMode.TypeInUsingDeclaration:
            case NameLookupMode.BaseTypeReference:
                // Don't do the UnknownMemberResolveResult/MethodGroupResolveResult processing,
                // it's only relevant for expressions.
                return(lookup.LookupType(target.Type, identifier, typeArguments, parameterizeResultType));

            default:
                throw new NotSupportedException("Invalid value for NameLookupMode");
            }
            if (result is UnknownMemberExpression)
            {
                // We intentionally use all extension methods here, not just the eligible ones.
                // Proper eligibility checking is only possible for the full invocation
                // (after we know the remaining arguments).
                // The eligibility check in GetExtensionMethods is only intended for code completion.
                var extensionMethods = rc.GetExtensionMethods(identifier, typeArguments);
                if (extensionMethods.Count > 0)
                {
                    return(new MethodGroupExpression(target, identifier, EmptyList <MethodListWithDeclaringType> .Instance, typeArguments)
                    {
                        extensionMethods = extensionMethods
                    });
                }
            }
            else
            {
                MethodGroupExpression mgrr = result as MethodGroupExpression;
                if (mgrr != null)
                {
                    Debug.Assert(mgrr.extensionMethods == null);
                    // set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work
                    mgrr.resolver = rc;
                }
            }
            return(result);
        }
示例#27
0
        TranslatedExpression HandleDelegateConstruction(CallInstruction inst)
        {
            ILInstruction func = inst.Arguments[1];
            IMethod       method;

            switch (func.OpCode)
            {
            case OpCode.LdFtn:
                method = ((LdFtn)func).Method;
                break;

            case OpCode.LdVirtFtn:
                method = ((LdVirtFtn)func).Method;
                break;

            default:
                throw new ArgumentException($"Unknown instruction type: {func.OpCode}");
            }
            var invokeMethod = inst.Method.DeclaringType.GetDelegateInvokeMethod();
            TranslatedExpression target;
            IType targetType;
            bool  requireTarget;

            if (method.IsExtensionMethod && invokeMethod != null && method.Parameters.Count - 1 == invokeMethod.Parameters.Count)
            {
                targetType    = method.Parameters[0].Type;
                target        = expressionBuilder.Translate(inst.Arguments[0], targetType);
                target        = ExpressionBuilder.UnwrapBoxingConversion(target);
                requireTarget = true;
            }
            else
            {
                targetType    = method.DeclaringType;
                target        = expressionBuilder.TranslateTarget(method, inst.Arguments[0], func.OpCode == OpCode.LdFtn);
                target        = ExpressionBuilder.UnwrapBoxingConversion(target);
                requireTarget = expressionBuilder.HidesVariableWithName(method.Name) ||
                                (method.IsStatic ? !expressionBuilder.IsCurrentOrContainingType(method.DeclaringTypeDefinition) : !(target.Expression is ThisReferenceExpression));
            }
            var expectedTargetDetails = new ExpectedTargetDetails {
                CallOpCode = inst.OpCode
            };
            bool          needsCast = false;
            ResolveResult result    = null;
            var           or        = new OverloadResolution(resolver.Compilation, method.Parameters.SelectArray(p => new TypeResolveResult(p.Type)));

            if (!requireTarget)
            {
                result = resolver.ResolveSimpleName(method.Name, method.TypeArguments, isInvocationTarget: false);
                if (result is MethodGroupResolveResult mgrr)
                {
                    or.AddMethodLists(mgrr.MethodsGroupedByDeclaringType.ToArray());
                    requireTarget = (or.BestCandidateErrors != OverloadResolutionErrors.None || !IsAppropriateCallTarget(expectedTargetDetails, method, or.BestCandidate));
                }
                else
                {
                    requireTarget = true;
                }
            }
            MemberLookup lookup = null;

            if (requireTarget)
            {
                lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
                var rr = lookup.Lookup(target.ResolveResult, method.Name, method.TypeArguments, false);
                needsCast = true;
                result    = rr;
                if (rr is MethodGroupResolveResult mgrr)
                {
                    or.AddMethodLists(mgrr.MethodsGroupedByDeclaringType.ToArray());
                    needsCast = (or.BestCandidateErrors != OverloadResolutionErrors.None || !IsAppropriateCallTarget(expectedTargetDetails, method, or.BestCandidate));
                }
            }
            if (needsCast)
            {
                Debug.Assert(requireTarget);
                target = target.ConvertTo(targetType, expressionBuilder);
                result = lookup.Lookup(target.ResolveResult, method.Name, method.TypeArguments, false);
            }
            Expression targetExpression;

            if (requireTarget)
            {
                var mre = new MemberReferenceExpression(target, method.Name);
                mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
                mre.WithRR(result);
                targetExpression = mre;
            }
            else
            {
                var ide = new IdentifierExpression(method.Name)
                          .WithRR(result);
                targetExpression = ide;
            }
            var oce = new ObjectCreateExpression(expressionBuilder.ConvertType(inst.Method.DeclaringType), targetExpression)
                      .WithILInstruction(inst)
                      .WithRR(new ConversionResolveResult(
                                  inst.Method.DeclaringType,
                                  new MemberResolveResult(target.ResolveResult, method),
                                  Conversion.MethodGroupConversion(method, func.OpCode == OpCode.LdVirtFtn, false)));

            return(oce);
        }
示例#28
0
        public IList <ICompletionItem> CreateElementList(XamlCompletionContext context, bool includeAbstract)
        {
            if (context.ParseInformation == null)
            {
                return(EmptyList <ICompletionItem> .Instance);
            }

            List <ICompletionItem> result = new List <ICompletionItem>();
            AXmlElement            last   = context.ParentElement;
            ITextEditor            editor = context.Editor;

            compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
            IUnresolvedFile file = context.ParseInformation.UnresolvedFile;

            foreach (string item in XamlConst.GetAllowedItems(context))
            {
                result.Add(new XamlCompletionItem(item));
            }

            IType rt = null;

            if (last != null)
            {
                if (string.Equals(last.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    if (string.Equals(last.LocalName, "Members", StringComparison.OrdinalIgnoreCase))
                    {
                        return(result);
                    }
                    if (string.Equals(last.LocalName, "Code", StringComparison.OrdinalIgnoreCase))
                    {
                        return(result);
                    }
                }
                // If we have an element that is not a property or an incomplete
                // definition => interpret element as a type.
                XamlResolver resolver = new XamlResolver(compilation);
                int          dotIndex = last.LocalName.IndexOf(".", StringComparison.Ordinal) + 1;
                if (dotIndex < 1 || dotIndex == last.LocalName.Length)
                {
                    rt = resolver.ResolveType(last.Namespace, last.LocalName.Trim('.'));
                    string contentPropertyName = GetContentPropertyName(rt.GetDefinition());
                    // If the type has a content property specified, use its type for completion.
                    if (!string.IsNullOrEmpty(contentPropertyName))
                    {
                        IProperty p = rt.GetProperties(m => m.Name == contentPropertyName).FirstOrDefault();
                        if (p != null)
                        {
                            rt = p.ReturnType;
                        }
                    }
                }
                else
                {
                    string typeName   = last.LocalName.Substring(0, dotIndex - 1);
                    string memberName = last.LocalName.Substring(dotIndex);
                    rt = resolver.ResolveType(last.Namespace, typeName);
                    IMember member = rt.GetMembers(m => m.Name == memberName).FirstOrDefault();
                    if (member != null)
                    {
                        rt = member.ReturnType;
                    }
                }
            }

            bool            parentAdded    = false;
            var             utd            = file.GetInnermostTypeDefinition(editor.Caret.Location);
            ITypeDefinition currentTypeDef = null;

            if (utd != null)
            {
                currentTypeDef = utd.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
            }
            MemberLookup memberLookup = new MemberLookup(currentTypeDef, compilation.MainAssembly);

            IList <ITypeDefinition> possibleTypesInCollection = EmptyList <ITypeDefinition> .Instance;

            if (rt != null && Extensions.IsListType(rt))
            {
                possibleTypesInCollection = rt.GetMethods(m => m.Parameters.Count == 1 && "Add".Equals(m.Name, StringComparison.Ordinal))
                                            .Select(m => m.Parameters[0].Type.GetDefinition())
                                            .Where(t => t != null)
                                            .ToList();
            }

            var items = GetClassesFromContext(context);

            foreach (var ns in items)
            {
                foreach (ITypeDefinition td in ns.Value)
                {
                    if (td.Kind != TypeKind.Class && (!includeAbstract || td.Kind != TypeKind.Interface))
                    {
                        continue;
                    }
                    if (td.IsStatic || (!includeAbstract && td.IsAbstract) || td.IsDerivedFrom(KnownTypeCode.Attribute))
                    {
                        continue;
                    }
                    if (td.Kind == TypeKind.Class && !td.GetConstructors().Any(m => memberLookup.IsAccessible(m, false)))
                    {
                        continue;
                    }
                    if (possibleTypesInCollection.Count > 0 && !possibleTypesInCollection.Any(td.IsDerivedFrom))
                    {
                        continue;
                    }
                    string fullName = td.Name;
                    if (!string.IsNullOrEmpty(ns.Key))
                    {
                        fullName = ns.Key + ":" + fullName;
                    }
                    XamlCompletionItem item = new XamlCompletionItem(fullName, td);
                    parentAdded = parentAdded || (last != null && item.Text == last.Name);
                    result.Add(item);
                }
            }

            // TODO reimplement this if it is really necessary.
//			if (!parentAdded && last != null && !last.Name.Contains(".")) {
//				IClass itemClass = cu.CreateType(last.Namespace, last.LocalName.Trim('.')).GetUnderlyingClass();
//				if (itemClass != null)
//					result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix));
//			}

            return(result);
        }
        static IEnumerable <PossibleNamespace> GetPossibleNamespaces(Document doc, AstNode node, ResolveResult resolveResult, DocumentLocation location)
        {
            var unit = doc.ParsedDocument.GetAst <SyntaxTree> ();

            if (unit == null)
            {
                yield break;
            }
            var project = doc.Project;

            if (project == null)
            {
                yield break;
            }

            int  tc                    = GetTypeParameterCount(node);
            var  attribute             = unit.GetNodeAt <ICSharpCode.NRefactory.CSharp.Attribute> (location);
            bool isInsideAttributeType = attribute != null && attribute.Type.Contains(location);

            var compilations = new List <Tuple <ICompilation, MonoDevelop.Projects.ProjectReference> > ();

            compilations.Add(Tuple.Create(doc.Compilation, (MonoDevelop.Projects.ProjectReference)null));
            var referencedItems = IdeApp.Workspace != null?project.GetReferencedItems(IdeApp.Workspace.ActiveConfiguration).ToList() : (IEnumerable <SolutionItem>) new SolutionItem[0];

            var solution = project != null ? project.ParentSolution : null;

            if (solution != null)
            {
                foreach (var curProject in solution.GetAllProjects())
                {
                    if (curProject == project || referencedItems.Contains(curProject))
                    {
                        continue;
                    }
                    var comp = TypeSystemService.GetCompilation(curProject);
                    if (comp == null)
                    {
                        continue;
                    }
                    compilations.Add(Tuple.Create(comp, new MonoDevelop.Projects.ProjectReference(curProject)));
                }
            }

            var netProject = project as DotNetProject;

            if (netProject == null)
            {
                yield break;
            }
            var frameworkLookup = TypeSystemService.GetFrameworkLookup(netProject);

            if (resolveResult is UnknownMemberResolveResult)
            {
                var umResult = (UnknownMemberResolveResult)resolveResult;
                foreach (var r in frameworkLookup.LookupExtensionMethod(umResult.MemberName))
                {
                    var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName(r.FullName, r.Package, netProject.TargetFramework);
                    if (systemAssembly == null)
                    {
                        continue;
                    }
                    compilations.Add(Tuple.Create(TypeSystemService.GetCompilation(systemAssembly, doc.Compilation), new MonoDevelop.Projects.ProjectReference(systemAssembly)));
                }
            }
            bool foundIdentifier = false;
            var  lookup          = new MemberLookup(null, doc.Compilation.MainAssembly);

            foreach (var comp in compilations)
            {
                var compilation       = comp.Item1;
                var requiredReference = comp.Item2;
                if (resolveResult is AmbiguousTypeResolveResult)
                {
                    if (compilation != doc.Compilation)
                    {
                        continue;
                    }
                    var aResult = resolveResult as AmbiguousTypeResolveResult;
                    var file    = doc.ParsedDocument.ParsedFile as CSharpUnresolvedFile;
                    var scope   = file.GetUsingScope(location).Resolve(compilation);
                    while (scope != null)
                    {
                        foreach (var u in scope.Usings)
                        {
                            foreach (var typeDefinition in u.Types)
                            {
                                if (typeDefinition.Name == aResult.Type.Name &&
                                    typeDefinition.TypeParameterCount == tc &&
                                    lookup.IsAccessible(typeDefinition, false))
                                {
                                    yield return(new PossibleNamespace(typeDefinition.Namespace, true, requiredReference));
                                }
                            }
                        }
                        scope = scope.Parent;
                    }
                }

                var allTypes = compilation == doc.Compilation ? compilation.GetAllTypeDefinitions() : compilation.MainAssembly.GetAllTypeDefinitions();
                if (resolveResult is UnknownIdentifierResolveResult)
                {
                    var    uiResult = resolveResult as UnknownIdentifierResolveResult;
                    string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : uiResult.Identifier;
                    foreach (var typeDefinition in allTypes)
                    {
                        if (typeDefinition.Name == possibleAttributeName && typeDefinition.TypeParameterCount == tc &&
                            lookup.IsAccessible(typeDefinition, false))
                        {
                            if (typeDefinition.DeclaringTypeDefinition != null)
                            {
                                var builder = new TypeSystemAstBuilder(new CSharpResolver(doc.Compilation));
                                foundIdentifier = true;
                                yield return(new PossibleNamespace(builder.ConvertType(typeDefinition.DeclaringTypeDefinition).ToString(), false, requiredReference));
                            }
                            else
                            {
                                foundIdentifier = true;
                                yield return(new PossibleNamespace(typeDefinition.Namespace, true, requiredReference));
                            }
                        }
                    }
                }

                if (resolveResult is UnknownMemberResolveResult)
                {
                    var    umResult = (UnknownMemberResolveResult)resolveResult;
                    string possibleAttributeName = isInsideAttributeType ? umResult.MemberName + "Attribute" : umResult.MemberName;
                    foreach (var typeDefinition in allTypes.Where(t => t.HasExtensionMethods))
                    {
                        foreach (var method in typeDefinition.Methods.Where(m => m.IsExtensionMethod && m.Name == possibleAttributeName))
                        {
                            IType[] inferredTypes;
                            if (CSharpResolver.IsEligibleExtensionMethod(
                                    compilation.Import(umResult.TargetType),
                                    method,
                                    true,
                                    out inferredTypes
                                    ))
                            {
                                yield return(new PossibleNamespace(typeDefinition.Namespace, true, requiredReference));

                                goto skipType;
                            }
                        }
skipType:
                        ;
                    }
                }

                if (resolveResult is ErrorResolveResult)
                {
                    var identifier = unit != null?unit.GetNodeAt <Identifier> (location) : null;

                    if (identifier != null)
                    {
                        var uiResult = resolveResult as UnknownIdentifierResolveResult;
                        if (uiResult != null)
                        {
                            string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : uiResult.Identifier;
                            foreach (var typeDefinition in allTypes)
                            {
                                if ((identifier.Name == possibleAttributeName) &&
                                    typeDefinition.TypeParameterCount == tc &&
                                    lookup.IsAccessible(typeDefinition, false))
                                {
                                    yield return(new PossibleNamespace(typeDefinition.Namespace, true, requiredReference));
                                }
                            }
                        }
                    }
                }
            }
            // Try to search framework types
            if (!foundIdentifier && resolveResult is UnknownIdentifierResolveResult)
            {
                var    uiResult = resolveResult as UnknownIdentifierResolveResult;
                string possibleAttributeName = isInsideAttributeType ? uiResult.Identifier + "Attribute" : uiResult.Identifier;
                foreach (var r in frameworkLookup.LookupIdentifier(possibleAttributeName, tc))
                {
                    var systemAssembly = netProject.AssemblyContext.GetAssemblyFromFullName(r.FullName, r.Package, netProject.TargetFramework);
                    if (systemAssembly == null)
                    {
                        continue;
                    }
                    yield return(new PossibleNamespace(r.Namespace, true, new MonoDevelop.Projects.ProjectReference(systemAssembly)));
                }
            }
        }
示例#30
0
        TranslatedExpression HandleDelegateConstruction(CallInstruction inst)
        {
            ILInstruction func = inst.Arguments[1];
            IMethod       method;

            switch (func.OpCode)
            {
            case OpCode.LdFtn:
                method = ((LdFtn)func).Method;
                break;

            case OpCode.LdVirtFtn:
                method = ((LdVirtFtn)func).Method;
                break;

            default:
                throw new ArgumentException($"Unknown instruction type: {func.OpCode}");
            }
            var invokeMethod = inst.Method.DeclaringType.GetDelegateInvokeMethod();
            TranslatedExpression target;
            IType targetType;

            if (method.IsExtensionMethod && invokeMethod != null && method.Parameters.Count - 1 == invokeMethod.Parameters.Count)
            {
                target     = expressionBuilder.Translate(inst.Arguments[0]);
                targetType = method.Parameters[0].Type;
            }
            else
            {
                target     = expressionBuilder.TranslateTarget(method, inst.Arguments[0], func.OpCode == OpCode.LdFtn);
                targetType = method.DeclaringType;
            }
            var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
            var or     = new OverloadResolution(resolver.Compilation, method.Parameters.SelectArray(p => new TypeResolveResult(p.Type)));
            var result = lookup.Lookup(target.ResolveResult, method.Name, method.TypeArguments, false);

            bool needsCast = true;

            if (result is MethodGroupResolveResult mgrr)
            {
                or.AddMethodLists(mgrr.MethodsGroupedByDeclaringType.ToArray());
                var expectedTargetDetails = new ExpectedTargetDetails {
                    CallOpCode = inst.OpCode
                };
                needsCast = (or.BestCandidateErrors != OverloadResolutionErrors.None || !IsAppropriateCallTarget(expectedTargetDetails, method, or.BestCandidate));
            }
            if (needsCast)
            {
                target = target.ConvertTo(targetType, expressionBuilder);
                result = lookup.Lookup(target.ResolveResult, method.Name, method.TypeArguments, false);
            }

            var mre = new MemberReferenceExpression(target, method.Name);

            mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
            mre.WithRR(result);
            var oce = new ObjectCreateExpression(expressionBuilder.ConvertType(inst.Method.DeclaringType), mre)
                      .WithILInstruction(inst)
                      .WithRR(new ConversionResolveResult(
                                  inst.Method.DeclaringType,
                                  new MemberResolveResult(target.ResolveResult, method),
                                  Conversion.MethodGroupConversion(method, func.OpCode == OpCode.LdVirtFtn, false)));

            return(oce);
        }