Пример #1
0
        /// <summary>
        /// Reparses the given method's fucntion body until the cursor position,
        /// searches the last occurring method call or template instantiation,
        /// counts its already typed arguments
        /// and returns a wrapper containing all the information.
        /// </summary>
        public static ArgumentsResolutionResult ResolveArgumentContext(
            IEditorData Editor,
            ResolutionContext ctxt)
        {
            ParserTrackerVariables trackVars;
            IBlockNode             curBlock = null;
            IStatement             curStmt;

            var sr = CtrlSpaceCompletionProvider.FindCurrentCaretContext(Editor, out trackVars, ref curBlock, out curStmt);

            IExpression lastParamExpression = null;

            var parsedStmtBlock = sr as IStatement;

            if (parsedStmtBlock != null)
            {
                // Search the returned statement block (i.e. function body) for the current statement;
                if (parsedStmtBlock is StatementContainingStatement)
                {
                    parsedStmtBlock = (parsedStmtBlock as StatementContainingStatement).SearchStatementDeeply(Editor.CaretLocation);
                }

                lastParamExpression = ExpressionHelper.SearchForMethodCallsOrTemplateInstances(parsedStmtBlock, Editor.CaretLocation);
            }
            else if (trackVars != null && trackVars.IsParsingInitializer)
            {
                if (trackVars.InitializedNode is DVariable)
                {
                    lastParamExpression =
                        ExpressionHelper.SearchExpressionDeeply((trackVars.InitializedNode as DVariable).Initializer, Editor.CaretLocation);
                }
            }

            if (lastParamExpression == null)
            {
                // Give it a last chance by handling the lastly parsed object
                // - which is a TemplateInstanceExpression in quite all cases
                lastParamExpression = trackVars.LastParsedObject as IExpression;
            }

            /*
             * Then handle the lastly found expression regarding the following points:
             *
             * 1) foo(			-- normal arguments only
             * 2) foo!(...)(	-- normal arguments + template args
             * 3) foo!(		-- template args only
             * 4) new myclass(  -- ctor call
             * 5) new myclass!( -- ditto
             * 6) new myclass!(...)(
             * 7) mystruct(		-- opCall call
             */

            var res = new ArgumentsResolutionResult()
            {
                ParsedExpression = lastParamExpression
            };

            // 1), 2)
            if (lastParamExpression is PostfixExpression_MethodCall)
            {
                res.IsMethodArguments = true;
                var call = (PostfixExpression_MethodCall)lastParamExpression;

                res.MethodIdentifier       = call.PostfixForeExpression;
                res.ResolvedTypesOrMethods = Evaluation.GetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call);

                if (call.Arguments != null)
                {
                    res.CurrentlyTypedArgumentIndex = call.ArgumentCount;
                }
            }
            // 3)
            else if (lastParamExpression is TemplateInstanceExpression)
            {
                var templ = (TemplateInstanceExpression)lastParamExpression;

                res.IsTemplateInstanceArguments = true;

                res.MethodIdentifier       = templ;
                res.ResolvedTypesOrMethods = Evaluation.GetOverloads(templ, ctxt, null, false);

                if (templ.Arguments != null)
                {
                    res.CurrentlyTypedArgumentIndex = templ.Arguments.Length;
                }
                else
                {
                    res.CurrentlyTypedArgumentIndex = 0;
                }
            }
            else if (lastParamExpression is PostfixExpression_Access)
            {
                var acc = (PostfixExpression_Access)lastParamExpression;

                res.MethodIdentifier       = acc.PostfixForeExpression;
                res.ResolvedTypesOrMethods = Evaluation.GetUnfilteredMethodOverloads(acc.PostfixForeExpression, ctxt, acc);

                if (res.ResolvedTypesOrMethods == null)
                {
                    return(res);
                }

                if (acc.AccessExpression is NewExpression)
                {
                    CalculateCurrentArgument(acc.AccessExpression as NewExpression, res, Editor.CaretLocation, ctxt, res.ResolvedTypesOrMethods);
                }
            }
            else if (lastParamExpression is NewExpression)
            {
                HandleNewExpression((NewExpression)lastParamExpression, res, Editor, ctxt, curBlock);
            }

            /*
             * alias int function(int a, bool b) myDeleg;
             * alias myDeleg myDeleg2;
             *
             * myDeleg dg;
             *
             * dg( -- it's not needed to have myDeleg but the base type for what it stands for
             *
             * ISSUE:
             * myDeleg( -- not allowed though
             * myDeleg2( -- allowed neither!
             */
            if (res.ResolvedTypesOrMethods != null)
            {
                res.ResolvedTypesOrMethods = DResolver.StripAliasSymbols(res.ResolvedTypesOrMethods);
            }

            return(res);
        }
Пример #2
0
        internal static AbstractCompletionProvider Create(ICompletionDataGenerator dataGen, IEditorData Editor, char ch)
        {
            if (ch == '@')
            {
                return(new PropertyAttributeCompletionProvider(dataGen));
            }

            ParserTrackerVariables trackVars;
            IBlockNode             curBlock = null;
            IStatement             curStmt;

            var parsedBlock = CtrlSpaceCompletionProvider.FindCurrentCaretContext(Editor, out trackVars, ref curBlock, out curStmt);

            if (trackVars != null)
            {
                if (trackVars.ExpectingNodeName)
                {
                    return(null);
                }

                PostfixExpression_Access pfa;

                // if( asdf == E.| )
                var ex = trackVars.LastParsedObject as IExpression;
                while (ex is OperatorBasedExpression)
                {
                    var opEx = ex as OperatorBasedExpression;
                    var rop  = opEx.RightOperand;
                    if (rop != null && Editor.CaretLocation >= rop.Location)
                    {
                        ex = rop;
                    }
                    else if ((rop = opEx.LeftOperand) != null && Editor.CaretLocation <= rop.EndLocation)
                    {
                        ex = rop;
                    }
                    else
                    {
                        break;
                    }
                }

                if (ex is PostfixExpression_Access)
                {
                    pfa = ex as PostfixExpression_Access;
                }
                else if (trackVars.LastParsedObject is ITypeDeclaration && !(trackVars.LastParsedObject is TemplateInstanceExpression))
                {
                    pfa = TryConvertTypeDeclaration(trackVars.LastParsedObject as ITypeDeclaration) as PostfixExpression_Access;
                }
                else if (ex is UnaryExpression_Type)
                {
                    pfa = null;
                    //TODO: (Type). -- lookup static properties, fields and methods.
                }
                else
                {
                    pfa = null;
                }

                if (pfa != null)
                {
                    // myObj. <-- AccessExpression will be null there,
                    // this.fileName | <-- AccessExpression will be 'fileName' - no trigger wished
                    if (pfa.AccessExpression == null)
                    {
                        var mcp = new MemberCompletionProvider(dataGen)
                        {
                            AccessExpression = pfa,
                            ScopedBlock      = curBlock,
                            ScopedStatement  = curStmt,
                        };
                        if (trackVars.IsParsingBaseClassList)
                        {
                            if (trackVars.InitializedNode is DClassLike &&
                                (trackVars.InitializedNode as DClassLike).ClassType == DTokens.Interface)
                            {
                                mcp.MemberFilter = MemberFilter.Interfaces | MemberFilter.Templates;
                            }
                            else
                            {
                                mcp.MemberFilter = MemberFilter.Classes | MemberFilter.Interfaces | MemberFilter.Templates;
                            }
                        }
                        return(mcp);
                    }
                    else
                    {
                        return(null);
                    }
                }

                if (trackVars.ExpectingIdentifier)
                {
                    if (trackVars.LastParsedObject is DAttribute)
                    {
                        return new AttributeCompletionProvider(dataGen)
                               {
                                   Attribute = trackVars.LastParsedObject as DAttribute
                               }
                    }
                    ;
                    else if (trackVars.LastParsedObject is ScopeGuardStatement)
                    {
                        return new ScopeAttributeCompletionProvider(dataGen)
                               {
                                   //ScopeStmt = trackVars.LastParsedObject as ScopeGuardStatement
                               }
                    }
                    ;
                    else if (trackVars.LastParsedObject is PragmaStatement)
                    {
                        return new AttributeCompletionProvider(dataGen)
                               {
                                   Attribute = (trackVars.LastParsedObject as PragmaStatement).Pragma
                               }
                    }
                    ;
                    else if (trackVars.LastParsedObject is TraitsExpression)
                    {
                        return new TraitsExpressionCompletionProvider(dataGen)
                               {
                                   //TraitsExpr=trackVars.LastParsedObject as TraitsExpression
                               }
                    }
                    ;
                    else if (trackVars.LastParsedObject is ImportStatement.Import)
                    {
                        return(new ImportStatementCompletionProvider(dataGen, (ImportStatement.Import)trackVars.LastParsedObject));
                    }
                    else if (trackVars.LastParsedObject is ImportStatement.ImportBindings)
                    {
                        return(new ImportStatementCompletionProvider(dataGen, (ImportStatement.ImportBindings)trackVars.LastParsedObject));
                    }
                    else if (trackVars.LastParsedObject is ModuleStatement)
                    {
                        return(new ModuleStatementCompletionProvider(dataGen));
                    }
                    else if ((trackVars.LastParsedObject is TemplateParameter ||
                              trackVars.LastParsedObject is ForeachStatement) && ch != '\0')
                    {
                        return(null);
                    }
                }

                if (ch == '(')
                {
                    return(null);
                }
            }

            return(new CtrlSpaceCompletionProvider(dataGen)
            {
                trackVars = trackVars,
                curBlock = curBlock,
                curStmt = curStmt,
                parsedBlock = parsedBlock
            });
        }