Ejemplo n.º 1
0
        public IParameterDataProvider GetParameterDataProvider(int offset, char completionChar)
        {
            //Ignoring completionChar == '\0' because it usually means moving with arrow keys, tab or enter
            //we don't want to trigger on those events but it probably should be handled somewhere else
            //since our job is to resolve method and not to decide when to display tooltip or not
            if (offset <= 0 || completionChar == '\0')
            {
                return(null);
            }
            SetOffset(offset);
            int    startOffset;
            string text;

            if (currentMember == null && currentType == null)
            {
                //In case of attributes parse all file
                startOffset = 0;
                text        = document.Text;
            }
            else
            {
                var memberText = GetMemberTextToCaret();
                text        = memberText.Item1;
                startOffset = document.GetOffset(memberText.Item2);
            }

            var parenStack   = new Stack <int> ();
            var chevronStack = new Stack <int> ();
            var squareStack  = new Stack <int> ();
            var bracketStack = new Stack <int> ();

            var  lex    = new MiniLexer(text);
            bool failed = lex.Parse((ch, off) => {
                if (lex.IsInString || lex.IsInChar || lex.IsInVerbatimString || lex.IsInSingleComment || lex.IsInMultiLineComment || lex.IsInPreprocessorDirective)
                {
                    return(false);
                }
                switch (ch)
                {
                case '(':
                    parenStack.Push(startOffset + off);
                    break;

                case ')':
                    if (parenStack.Count == 0)
                    {
                        return(true);
                    }
                    parenStack.Pop();
                    break;

                case '<':
                    chevronStack.Push(startOffset + off);
                    break;

                case '>':
                    //Don't abort if we don't have macthing '<' for '>' it could be if (i > 0) Foo($
                    if (chevronStack.Count == 0)
                    {
                        return(false);
                    }
                    chevronStack.Pop();
                    break;

                case '[':
                    squareStack.Push(startOffset + off);
                    break;

                case ']':
                    if (squareStack.Count == 0)
                    {
                        return(true);
                    }
                    squareStack.Pop();
                    break;

                case '{':
                    bracketStack.Push(startOffset + off);
                    break;

                case '}':
                    if (bracketStack.Count == 0)
                    {
                        return(true);
                    }
                    bracketStack.Pop();
                    break;
                }
                return(false);
            });

            if (failed)
            {
                return(null);
            }
            int result = -1;

            if (parenStack.Count > 0)
            {
                result = parenStack.Pop();
            }
            if (squareStack.Count > 0)
            {
                result = Math.Max(result, squareStack.Pop());
            }
            if (chevronStack.Count > 0)
            {
                result = Math.Max(result, chevronStack.Pop());
            }

            //If we are inside { bracket we don't want to display anything
            if (bracketStack.Count > 0 && bracketStack.Pop() > result)
            {
                return(null);
            }
            if (result == -1)
            {
                return(null);
            }
            SetOffset(result + 1);
            ResolveResult resolveResult;

            switch (document.GetCharAt(result))
            {
            case '(':
                var invoke = GetInvocationBeforeCursor(true) ?? GetConstructorInitializerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                if (invoke.Node is ConstructorInitializer)
                {
                    var init = (ConstructorInitializer)invoke.Node;
                    if (init.ConstructorInitializerType == ConstructorInitializerType.This)
                    {
                        return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), ctx.CurrentTypeDefinition, init));
                    }
                    else
                    {
                        var baseType = ctx.CurrentTypeDefinition.DirectBaseTypes.FirstOrDefault(bt => bt.Kind != TypeKind.Interface);
                        if (baseType == null)
                        {
                            return(null);
                        }
                        return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), baseType));
                    }
                }
                if (invoke.Node is ObjectCreateExpression)
                {
                    var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
                    if (createType.Result.Type.Kind == TypeKind.Unknown)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Result.Type));
                }

                if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute)
                {
                    var attribute = ResolveExpression(invoke);
                    if (attribute == null || attribute.Result == null)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Result.Type));
                }
                var invocationExpression = ResolveExpression(invoke);
                if (invocationExpression == null || invocationExpression.Result == null || invocationExpression.Result.IsError)
                {
                    return(null);
                }
                resolveResult = invocationExpression.Result;
                if (resolveResult is MethodGroupResolveResult)
                {
                    return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult)));
                }
                if (resolveResult is MemberResolveResult)
                {
                    var mr = resolveResult as MemberResolveResult;
                    if (mr.Member is IMethod)
                    {
                        return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member }));
                    }
                }

                if (resolveResult.Type.Kind == TypeKind.Delegate)
                {
                    return(factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type));
                }

                //
                //				if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) {
                //					if (resolveResult is ThisResolveResult)
                //						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult);
                //					if (resolveResult is BaseResolveResult)
                //						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult);
                //				}
                //				IType resolvedType = resolver.SearchType (resolveResult.ResolvedType);
                //				if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) {
                //					return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType);
                //				}
                break;

            case '<':
                invoke = GetMethodTypeArgumentInvocationBeforeCursor();
                if (invoke != null)
                {
                    var tExpr2 = ResolveExpression(invoke);
                    if (tExpr2 != null && tExpr2.Result is MethodGroupResolveResult && !tExpr2.Result.IsError)
                    {
                        return(factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, tExpr2.Result as MethodGroupResolveResult)));
                    }
                }
                invoke = GetTypeBeforeCursor();
                if (invoke == null || invoke.Node.StartLocation.IsEmpty)
                {
                    return(null);
                }
                var tExpr = ResolveExpression(invoke);
                if (tExpr == null || tExpr.Result == null || tExpr.Result.IsError)
                {
                    return(null);
                }

                return(factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(tExpr.Result.Type)));

            case '[':
                invoke = GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                if (invoke.Node is ArrayCreateExpression)
                {
                    return(null);
                }
                var indexerExpression = ResolveExpression(invoke);
                if (indexerExpression == null || indexerExpression.Result == null || indexerExpression.Result.IsError)
                {
                    return(null);
                }
                return(factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), indexerExpression.Result.Type, GetAccessibleIndexers(indexerExpression.Result.Type), invoke.Node));
            }
            return(null);
        }
Ejemplo n.º 2
0
        public IParameterDataProvider GetParameterDataProvider(int offset, char completionChar)
        {
            if (offset <= 0)
            {
                return(null);
            }
            if (completionChar != '(' && completionChar != '<' && completionChar != '[' && completionChar != ',')
            {
                return(null);
            }

            SetOffset(offset);
            if (IsInsideCommentStringOrDirective())
            {
                return(null);
            }

            ResolveResult resolveResult;

            switch (completionChar)
            {
            case '(':
                var invoke = GetInvocationBeforeCursor(true) ?? GetConstructorInitializerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                if (invoke.Node is ConstructorInitializer)
                {
                    var init = (ConstructorInitializer)invoke.Node;
                    if (init.ConstructorInitializerType == ConstructorInitializerType.This)
                    {
                        return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), ctx.CurrentTypeDefinition));
                    }
                    else
                    {
                        var baseType = ctx.CurrentTypeDefinition.DirectBaseTypes.FirstOrDefault(bt => bt.Kind != TypeKind.Interface);
                        if (baseType == null)
                        {
                            return(null);
                        }
                        return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), baseType));
                    }
                }
                if (invoke.Node is ObjectCreateExpression)
                {
                    var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
                    if (createType.Item1.Type.Kind == TypeKind.Unknown)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type));
                }

                if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute)
                {
                    var attribute = ResolveExpression(invoke);
                    if (attribute == null || attribute.Item1 == null)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Item1.Type));
                }
                var invocationExpression = ResolveExpression(invoke);
                if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError)
                {
                    return(null);
                }
                resolveResult = invocationExpression.Item1;
                if (resolveResult is MethodGroupResolveResult)
                {
                    return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult)));
                }
                if (resolveResult is MemberResolveResult)
                {
                    var mr = resolveResult as MemberResolveResult;
                    if (mr.Member is IMethod)
                    {
                        return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member }));
                    }
                }

                if (resolveResult.Type.Kind == TypeKind.Delegate)
                {
                    return(factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type));
                }

//
//				if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) {
//					if (resolveResult is ThisResolveResult)
//						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult);
//					if (resolveResult is BaseResolveResult)
//						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult);
//				}
//				IType resolvedType = resolver.SearchType (resolveResult.ResolvedType);
//				if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) {
//					return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType);
//				}
                break;

            case ',':
                invoke = GetInvocationBeforeCursor(true) ?? GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    invoke = GetTypeBeforeCursor();
                    if (invoke != null)
                    {
                        if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
                        {
                            return(null);
                        }
                        var typeExpression = ResolveExpression(invoke);
                        if (typeExpression == null || typeExpression.Item1 == null || typeExpression.Item1.IsError)
                        {
                            return(null);
                        }

                        return(factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(typeExpression.Item1.Type)));
                    }
                    return(null);
                }
                if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
                {
                    return(null);
                }
                if (invoke.Node is ObjectCreateExpression)
                {
                    var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type));
                }

                if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute)
                {
                    var attribute = ResolveExpression(invoke);
                    if (attribute == null || attribute.Item1 == null)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Item1.Type));
                }

                invocationExpression = ResolveExpression(invoke);

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

                resolveResult = invocationExpression.Item1;
                if (resolveResult is MethodGroupResolveResult)
                {
                    return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult)));
                }
                if (resolveResult is MemberResolveResult)
                {
                    if (resolveResult.Type.Kind == TypeKind.Delegate)
                    {
                        return(factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type));
                    }
                    var mr = resolveResult as MemberResolveResult;
                    if (mr.Member is IMethod)
                    {
                        return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member }));
                    }
                }
                if (resolveResult != null)
                {
                    return(factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type, invoke.Node));
                }
                break;

            case '<':
                invoke = GetTypeBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                var tExpr = ResolveExpression(invoke);
                if (tExpr == null || tExpr.Item1 == null || tExpr.Item1.IsError)
                {
                    return(null);
                }

                return(factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(tExpr.Item1.Type)));

            case '[':
                invoke = GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                var indexerExpression = ResolveExpression(invoke);
                if (indexerExpression == null || indexerExpression.Item1 == null || indexerExpression.Item1.IsError)
                {
                    return(null);
                }
                return(factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), indexerExpression.Item1.Type, invoke.Node));
            }
            return(null);
        }
        public IParameterDataProvider GetParameterDataProvider(int offset, char completionChar)
        {
            if (offset <= 0)
            {
                return(null);
            }
            if (completionChar != '(' && completionChar != '<' && completionChar != '[' && completionChar != ',')
            {
                return(null);
            }

            SetOffset(offset);
            if (IsInsideCommentOrString())
            {
                return(null);
            }


            ResolveResult resolveResult;

            switch (completionChar)
            {
            case '(':
                var invoke = GetInvocationBeforeCursor(true) ?? GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                if (invoke.Item2 is ObjectCreateExpression)
                {
                    var createType = ResolveExpression(invoke.Item1, ((ObjectCreateExpression)invoke.Item2).Type, invoke.Item3);
                    return(factory.CreateConstructorProvider(createType.Item1.Type));
                }

                if (invoke.Item2 is ICSharpCode.NRefactory.Cpp.Attribute)
                {
                    var attribute = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);
                    if (attribute == null || attribute.Item1 == null)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(attribute.Item1.Type));
                }
                var invocationExpression = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);
                if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError)
                {
                    return(null);
                }
                resolveResult = invocationExpression.Item1;
                if (resolveResult is MethodGroupResolveResult)
                {
                    return(factory.CreateMethodDataProvider(resolveResult as MethodGroupResolveResult));
                }
                if (resolveResult is MemberResolveResult)
                {
                    var mr = resolveResult as MemberResolveResult;
                    if (mr.Member is IMethod)
                    {
                        return(factory.CreateMethodDataProvider((IMethod)mr.Member));
                    }
                }

                if (resolveResult.Type.Kind == TypeKind.Delegate)
                {
                    return(factory.CreateDelegateDataProvider(resolveResult.Type));
                }

//
//				if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) {
//					if (resolveResult is ThisResolveResult)
//						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult);
//					if (resolveResult is BaseResolveResult)
//						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult);
//				}
//				IType resolvedType = resolver.SearchType (resolveResult.ResolvedType);
//				if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) {
//					return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType);
//				}
                break;

            case ',':
                invoke = GetInvocationBeforeCursor(true) ?? GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    invoke = GetTypeBeforeCursor();
                    if (invoke != null)
                    {
                        var typeExpression = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);
                        if (typeExpression == null || typeExpression.Item1 == null || typeExpression.Item1.IsError)
                        {
                            return(null);
                        }

                        return(factory.CreateTypeParameterDataProvider(CollectAllTypes(typeExpression.Item1.Type)));
                    }
                    return(null);
                }
                if (invoke.Item2 is ObjectCreateExpression)
                {
                    var createType = ResolveExpression(invoke.Item1, ((ObjectCreateExpression)invoke.Item2).Type, invoke.Item3);
                    return(factory.CreateConstructorProvider(createType.Item1.Type));
                }

                if (invoke.Item2 is ICSharpCode.NRefactory.Cpp.Attribute)
                {
                    var attribute = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);
                    if (attribute == null || attribute.Item1 == null)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(attribute.Item1.Type));
                }

                invocationExpression = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);

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

                resolveResult = invocationExpression.Item1;
                if (resolveResult is MethodGroupResolveResult)
                {
                    return(factory.CreateMethodDataProvider(resolveResult as MethodGroupResolveResult));
                }
                if (resolveResult is MemberResolveResult)
                {
                    if (resolveResult.Type.Kind == TypeKind.Delegate)
                    {
                        return(factory.CreateDelegateDataProvider(resolveResult.Type));
                    }
                    var mr = resolveResult as MemberResolveResult;
                    if (mr.Member is IMethod)
                    {
                        return(factory.CreateMethodDataProvider((IMethod)mr.Member));
                    }
                }
                if (resolveResult != null)
                {
                    return(factory.CreateIndexerParameterDataProvider(resolveResult.Type, invoke.Item2));
                }
                break;

            case '<':
                invoke = GetTypeBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                var tExpr = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);
                if (tExpr == null || tExpr.Item1 == null || tExpr.Item1.IsError)
                {
                    return(null);
                }

                return(factory.CreateTypeParameterDataProvider(CollectAllTypes(tExpr.Item1.Type)));

            case '[':
                invoke = GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                var indexerExpression = ResolveExpression(invoke.Item1, invoke.Item2, invoke.Item3);
                if (indexerExpression == null || indexerExpression.Item1 == null || indexerExpression.Item1.IsError)
                {
                    return(null);
                }
                return(factory.CreateIndexerParameterDataProvider(indexerExpression.Item1.Type, invoke.Item2));
            }
            return(null);
        }