private DParameterDataProvider(Document doc, ArgumentsResolutionResult argsResult, int startOffset)
     : base(startOffset)
 {
     this.doc = doc;
     args = argsResult;
     selIndex = args.CurrentlyCalledMethod;
 }
 private ParameterInsightResolution(IEditorData ed, ResolutionContext c, ArgumentsResolutionResult r, IBlockNode cs)
 {
     Editor   = ed;
     ctxt     = c;
     res      = r;
     curScope = cs;
 }
Beispiel #3
0
 static void CalculateCurrentArgument(NewExpression nex,
                                      ArgumentsResolutionResult res,
                                      CodeLocation caretLocation,
                                      ResolverContextStack ctxt,
                                      IEnumerable <AbstractType> resultBases = null)
 {
     if (nex.Arguments != null)
     {
         int i = 0;
         foreach (var arg in nex.Arguments)
         {
             if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation)
             {
                 res.CurrentlyTypedArgumentIndex = i;
                 break;
             }
             i++;
         }
     }
 }
Beispiel #4
0
        static void HandleTemplateInstance(TemplateInstanceExpression tix,
                                           ArgumentsResolutionResult res,
                                           IEditorData Editor,
                                           ResolutionContext ctxt,
                                           IBlockNode curBlock,
                                           IEnumerable <AbstractType> resultBases = null)
        {
            res.IsTemplateInstanceArguments = true;

            res.MethodIdentifier       = tix;
            res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, resultBases, false);

            if (tix.Arguments != null)
            {
                res.CurrentlyTypedArgumentIndex = tix.Arguments.Length;
            }
            else
            {
                res.CurrentlyTypedArgumentIndex = 0;
            }
        }
        static void CalculateCurrentArgument(NewExpression nex,
                                             ArgumentsResolutionResult res,
                                             CodeLocation caretLocation,
                                             ResolutionContext ctxt,
                                             IEnumerable <AbstractType> resultBases = null)
        {
            if (nex.Arguments != null)
            {
                res.CurrentlyTypedArgumentIndex = nex.Arguments.Length;
            }

            /*{
             * int i = 0;
             * foreach (var arg in nex.Arguments)
             * {
             *      if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation)
             *      {
             *              res.CurrentlyTypedArgumentIndex = i;
             *              break;
             *      }
             *      i++;
             * }
             * }*/
        }
        static void CalculateCurrentArgument(NewExpression nex, 
			ArgumentsResolutionResult res, 
			CodeLocation caretLocation, 
			ResolutionContext ctxt,
			IEnumerable<AbstractType> resultBases=null)
        {
            if (nex.Arguments != null)
                res.CurrentlyTypedArgumentIndex = nex.Arguments.Length;
                /*{
                int i = 0;
                foreach (var arg in nex.Arguments)
                {
                    if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation)
                    {
                        res.CurrentlyTypedArgumentIndex = i;
                        break;
                    }
                    i++;
                }
            }*/
        }
        /// <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)
        {
            IBlockNode curBlock = null;
            bool       inNonCode;
            var        sr = CodeCompletion.FindCurrentCaretContext(Editor, ref curBlock, out inNonCode);

            IExpression lastParamExpression = null;

            var paramInsightVis = new ParamInsightVisitor();

            if (sr is INode)
            {
                (sr as INode).Accept(paramInsightVis);
            }
            else if (sr is IStatement)
            {
                (sr as IStatement).Accept(paramInsightVis);
            }
            else if (sr is IExpression)
            {
                (sr as IExpression).Accept(paramInsightVis);
            }

            lastParamExpression = paramInsightVis.LastCallExpression;

            /*
             * 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
            };

            var ctxt = ResolutionContext.Create(Editor, false);

            CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () =>
            {
                ctxt.Push(Editor);

                ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveAliases;

                if (lastParamExpression != null)
                {
                    lastParamExpression.Accept(new ParameterInsightResolution(Editor, ctxt, res, 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!
             */

            return(res);
        }
        /// <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,
			ResolverContextStack ctxt)
        {
            ParserTrackerVariables trackVars = null;
            IStatement curStmt = null;
            IExpression lastParamExpression = null;

            // Get the currently scoped block
            var curBlock = DResolver.SearchBlockAt(Editor.SyntaxTree, Editor.CaretLocation, out curStmt);

            if (curBlock == null)
                return null;

            // Get an updated abstract view on the module's code
            var parsedStmtBlock = CtrlSpaceCompletionProvider.FindCurrentCaretContext(
                Editor.ModuleCode, curBlock ,Editor.CaretOffset,	Editor.CaretLocation, out trackVars) as StatementContainingStatement;

            if (parsedStmtBlock == null)
                return null;

            // Search the returned statement block (i.e. function body) for the current statement
            var exStmt = BlockStatement.SearchBlockStatement(parsedStmtBlock, Editor.CaretLocation) as IExpressionContainingStatement;

            lastParamExpression = ExpressionHelper.SearchForMethodCallsOrTemplateInstances(exStmt, 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.TryGetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call);

                if (call.Arguments != null)
                {
                    int i = 0;
                    foreach (var arg in call.Arguments)
                    {
                        if (Editor.CaretLocation >= arg.Location && Editor.CaretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }

            }
            // 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)
                {
                    int i = 0;
                    foreach (var arg in templ.Arguments)
                    {
                        if (Editor.CaretLocation >= arg.Location && Editor.CaretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }
            }
            else if (lastParamExpression is PostfixExpression_Access)
            {
                var acc = (PostfixExpression_Access)lastParamExpression;

                res.MethodIdentifier = acc.PostfixForeExpression;
                res.ResolvedTypesOrMethods = Evaluation.TryGetUnfilteredMethodOverloads(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;
        }
Beispiel #9
0
        public static ArgumentsResolutionResult ResolveArgumentContext(
			string code,
			int caretOffset,
			CodeLocation caretLocation,
			DMethod MethodScope,
			IEnumerable<IAbstractSyntaxTree> parseCache, IEnumerable<IAbstractSyntaxTree> ImportCache)
        {
            var ctxt = new ResolverContext { ScopedBlock = MethodScope, ParseCache = parseCache, ImportCache=ImportCache };

            #region Parse the code between the last block opener and the caret

            var curMethodBody = MethodScope.GetSubBlockAt(caretLocation);

            if (curMethodBody == null && MethodScope.Parent is DMethod)
            {
                MethodScope = MethodScope.Parent as DMethod;
                curMethodBody = MethodScope.GetSubBlockAt(caretLocation);
            }

            if (curMethodBody == null)
                return null;

            var blockOpenerLocation = curMethodBody.StartLocation;
            var blockOpenerOffset = blockOpenerLocation.Line <= 0 ? blockOpenerLocation.Column :
                DocumentHelper.LocationToOffset(code, blockOpenerLocation);

            if (blockOpenerOffset >= 0 && caretOffset - blockOpenerOffset > 0)
            {
                var codeToParse = code.Substring(blockOpenerOffset, caretOffset - blockOpenerOffset);

                curMethodBody = DParser.ParseBlockStatement(codeToParse, blockOpenerLocation, MethodScope);

                if (curMethodBody != null)
                    ctxt.ScopedStatement = curMethodBody.SearchStatementDeeply(caretLocation);
            }

            if (curMethodBody == null || ctxt.ScopedStatement == null)
                return null;
            #endregion

            // Scan statement for method calls or template instantiations
            var e = DResolver.SearchForMethodCallsOrTemplateInstances(ctxt.ScopedStatement, caretLocation);

            /*
             * 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 = e };

            ITypeDeclaration methodIdentifier = null;

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

                if (call.Arguments != null)
                {
                    int i = 0;
                    foreach (var arg in call.Arguments)
                    {
                        if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }

                methodIdentifier = call.PostfixForeExpression.ExpressionTypeRepresentation;

            }
            // 3)
            else if (e is TemplateInstanceExpression)
            {
                var templ = e as TemplateInstanceExpression;

                res.IsTemplateInstanceArguments = true;

                if (templ.Arguments != null)
                {
                    int i = 0;
                    foreach (var arg in templ.Arguments)
                    {
                        if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }

                methodIdentifier = new IdentifierDeclaration(templ.TemplateIdentifier.Value) { InnerDeclaration=templ.InnerDeclaration };
            }
            else if (e is NewExpression)
            {
                var ne = e as NewExpression;

                if (ne.Arguments != null)
                {
                    int i = 0;
                    foreach (var arg in ne.Arguments)
                    {
                        if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }

                methodIdentifier = ne.ExpressionTypeRepresentation;
            }

            if (methodIdentifier == null)
                return null;

            // Resolve all types, methods etc. which belong to the methodIdentifier
            res.ResolvedTypesOrMethods = ResolveType(methodIdentifier, ctxt);

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

            // 4),5),6)
            if (e is NewExpression)
            {
                var substitutionList = new List<ResolveResult>();
                foreach (var rr in res.ResolvedTypesOrMethods)
                    if (rr is TypeResult)
                    {
                        var classDef = (rr as TypeResult).ResolvedTypeDefinition as DClassLike;

                        if (classDef == null)
                            continue;

                        //TODO: Regard protection attributes for ctor members
                        foreach (var i in classDef)
                            if (i is DMethod && (i as DMethod).SpecialType == DMethod.MethodType.Constructor)
                                substitutionList.Add(HandleNodeMatch(i, ctxt, resultBase: rr));
                    }

                if (substitutionList.Count > 0)
                    res.ResolvedTypesOrMethods = substitutionList.ToArray();
            }

            // 7)
            else if (e is PostfixExpression_MethodCall)
            {
                var substitutionList = new List<ResolveResult>();

                var nonAliases=TryRemoveAliasesFromResult(res.ResolvedTypesOrMethods);

                foreach (var rr in nonAliases)
                    if (rr is TypeResult)
                    {
                        var classDef = (rr as TypeResult).ResolvedTypeDefinition as DClassLike;

                        if (classDef == null)
                            continue;

                        //TODO: Regard protection attributes for opCall members
                        foreach (var i in classDef)
                            if (i is DMethod && i.Name == "opCall")
                                substitutionList.Add(HandleNodeMatch(i, ctxt, resultBase: rr));
                    }

                if (substitutionList.Count > 0)
                    nonAliases = substitutionList.ToArray();

                res.ResolvedTypesOrMethods = nonAliases;
            }

            return res;
        }
        /// <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)
        {
            IBlockNode curBlock = null;
            IStatement stmt;
            bool inNonCode;
            var sr = CodeCompletion.FindCurrentCaretContext(Editor, ref curBlock, out stmt, out inNonCode);

            IExpression lastParamExpression = null;

            var paramInsightVis = new ParamInsightVisitor ();
            if (sr is INode)
                (sr as INode).Accept (paramInsightVis);
            else if (sr is IStatement)
                (sr as IStatement).Accept (paramInsightVis);
            else if (sr is IExpression)
                (sr as IExpression).Accept (paramInsightVis);

            lastParamExpression = paramInsightVis.LastCallExpression;

            /*
             * 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
            };

            ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveAliases;

            CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () =>
            {
                // 1), 2)
                if (lastParamExpression is PostfixExpression_MethodCall)
                {
                    res.IsMethodArguments = true;
                    var call = (PostfixExpression_MethodCall)lastParamExpression;

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

                    if (call.Arguments != null)
                        res.CurrentlyTypedArgumentIndex = call.ArgumentCount;
                }
                // 3)
                else if (lastParamExpression is TemplateInstanceExpression)
                    HandleTemplateInstance(lastParamExpression as TemplateInstanceExpression, res, Editor, ctxt, curBlock);
                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!
             */

            return res;
        }
		/// <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)
		{
			IBlockNode curBlock = null;
			bool inNonCode;
			var sr = CodeCompletion.FindCurrentCaretContext(Editor, ref curBlock, out inNonCode);

			IExpression lastParamExpression = null;

			var paramInsightVis = new ParamInsightVisitor ();
			if (sr is INode)
				(sr as INode).Accept (paramInsightVis);
			else if (sr is IStatement)
				(sr as IStatement).Accept (paramInsightVis);
			else if (sr is IExpression)
				(sr as IExpression).Accept (paramInsightVis);

			lastParamExpression = paramInsightVis.LastCallExpression;

			/*
			 * 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
			};

			var ctxt = ResolutionContext.Create(Editor, false);				

			CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () =>
			{
				ctxt.Push(Editor);

				// ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveAliases;

				if (lastParamExpression != null)
					lastParamExpression.Accept(new ParameterInsightResolution(Editor, ctxt, res, 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!
			 */

			return res;
		}
Beispiel #12
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)
        {
            IBlockNode curBlock = null;
            IStatement stmt;
            bool       inNonCode;
            var        sr = CodeCompletion.FindCurrentCaretContext(Editor, ref curBlock, out stmt, out inNonCode);

            IExpression lastParamExpression = null;

            var paramInsightVis = new ParamInsightVisitor();

            if (sr is INode)
            {
                (sr as INode).Accept(paramInsightVis);
            }
            else if (sr is IStatement)
            {
                (sr as IStatement).Accept(paramInsightVis);
            }
            else if (sr is IExpression)
            {
                (sr as IExpression).Accept(paramInsightVis);
            }

            lastParamExpression = paramInsightVis.LastCallExpression;

            /*
             * 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 = ExpressionTypeEvaluation.GetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call);

                if (call.Arguments != null)
                {
                    res.CurrentlyTypedArgumentIndex = call.ArgumentCount;
                }
            }
            // 3)
            else if (lastParamExpression is TemplateInstanceExpression)
            {
                HandleTemplateInstance(lastParamExpression as TemplateInstanceExpression, res, Editor, ctxt, curBlock);
            }
            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);
        }
Beispiel #13
0
        static void HandleNewExpression(NewExpression nex,
                                        ArgumentsResolutionResult res,
                                        IEditorData Editor,
                                        ResolutionContext ctxt,
                                        IBlockNode curBlock,
                                        IEnumerable <AbstractType> resultBases = null)
        {
            res.MethodIdentifier = nex;
            CalculateCurrentArgument(nex, res, Editor.CaretLocation, ctxt);

            var type = TypeDeclarationResolver.Resolve(nex.Type, ctxt);

            if (type != null)
            {
                var _ctors = new List <AbstractType>();

                foreach (var t in type)
                {
                    //TODO: Inform the user that only classes can be instantiated
                    if (t is ClassType || t is StructType)
                    {
                        var  udt = t as TemplateIntermediateType;
                        bool explicitCtorFound = false;
                        var  constructors      = new List <DMethod>();

                        foreach (var member in udt.Definition)
                        {
                            var dm = member as DMethod;

                            if (dm != null && dm.SpecialType == DMethod.MethodType.Constructor)
                            {
                                explicitCtorFound = true;
                                if (!dm.IsPublic)
                                {
                                    var  curNode = curBlock;
                                    bool pass    = false;
                                    do
                                    {
                                        if (curNode == udt.Definition)
                                        {
                                            pass = true;
                                            break;
                                        }
                                    }while ((curNode = curNode.Parent as IBlockNode) != curNode);

                                    if (!pass)
                                    {
                                        continue;
                                    }
                                }

                                constructors.Add(dm);
                            }
                        }

                        if (constructors.Count == 0)
                        {
                            if (explicitCtorFound)
                            {
                                // TODO: Somehow inform the user that the current class can't be instantiated
                            }
                            else
                            {
                                // Introduce default constructor
                                constructors.Add(new DMethod(DMethod.MethodType.Constructor)
                                {
                                    Description = "Default constructor for " + udt.Name,
                                    Parent      = udt.Definition
                                });
                            }
                        }

                        // Wrapp all ctor members in MemberSymbols
                        foreach (var ctor in constructors)
                        {
                            _ctors.Add(new MemberSymbol(ctor, t, nex.Type));
                        }
                    }
                }

                res.ResolvedTypesOrMethods = _ctors.ToArray();

                //TODO: Probably pre-select the current ctor by handling previously typed arguments etc.
            }
        }
        /// <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;
        }
Beispiel #15
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,
            ResolverContextStack ctxt)
        {
            ParserTrackerVariables trackVars           = null;
            IStatement             curStmt             = null;
            IExpression            lastParamExpression = null;

            // Get the currently scoped block
            var curBlock = DResolver.SearchBlockAt(Editor.SyntaxTree, Editor.CaretLocation, out curStmt);

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

            // Get an updated abstract view on the module's code
            var parsedStmtBlock = CtrlSpaceCompletionProvider.FindCurrentCaretContext(
                Editor.ModuleCode, curBlock, Editor.CaretOffset, Editor.CaretLocation, out trackVars) as StatementContainingStatement;

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

            // Search the returned statement block (i.e. function body) for the current statement
            var exStmt = BlockStatement.SearchBlockStatement(parsedStmtBlock, Editor.CaretLocation) as IExpressionContainingStatement;

            lastParamExpression = ExpressionHelper.SearchForMethodCallsOrTemplateInstances(exStmt, 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.TryGetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call);

                if (call.Arguments != null)
                {
                    int i = 0;
                    foreach (var arg in call.Arguments)
                    {
                        if (Editor.CaretLocation >= arg.Location && Editor.CaretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }
            }
            // 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)
                {
                    int i = 0;
                    foreach (var arg in templ.Arguments)
                    {
                        if (Editor.CaretLocation >= arg.Location && Editor.CaretLocation <= arg.EndLocation)
                        {
                            res.CurrentlyTypedArgumentIndex = i;
                            break;
                        }
                        i++;
                    }
                }
            }
            else if (lastParamExpression is PostfixExpression_Access)
            {
                var acc = (PostfixExpression_Access)lastParamExpression;

                res.MethodIdentifier       = acc.PostfixForeExpression;
                res.ResolvedTypesOrMethods = Evaluation.TryGetUnfilteredMethodOverloads(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);
        }
        static void HandleNewExpression(NewExpression nex, 
			ArgumentsResolutionResult res, 
			IEditorData Editor, 
			ResolutionContext ctxt,
			IBlockNode curBlock,
			IEnumerable<AbstractType> resultBases = null)
        {
            res.MethodIdentifier = nex;
            CalculateCurrentArgument(nex, res, Editor.CaretLocation, ctxt);

            var type = TypeDeclarationResolver.ResolveSingle(nex.Type, ctxt);

            var _ctors = new List<AbstractType>();

            if (type is AmbiguousType)
                foreach (var t in (type as AmbiguousType).Overloads)
                    HandleNewExpression_Ctor(nex, curBlock, _ctors, t);
            else
                HandleNewExpression_Ctor(nex, curBlock, _ctors, type);

            res.ResolvedTypesOrMethods = _ctors.ToArray();
        }
        static void HandleTemplateInstance(TemplateInstanceExpression tix,
			ArgumentsResolutionResult res,
			IEditorData Editor,
			ResolutionContext ctxt,
			IBlockNode curBlock,
			IEnumerable<AbstractType> resultBases = null)
        {
            res.IsTemplateInstanceArguments = true;

            res.MethodIdentifier = tix;
            res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, resultBases, false);

            if (tix.Arguments != null)
                res.CurrentlyTypedArgumentIndex = tix.Arguments.Length;
            else
                res.CurrentlyTypedArgumentIndex = 0;
        }
		private ParameterInsightResolution(IEditorData ed, ResolutionContext c, ArgumentsResolutionResult r, IBlockNode cs) {
			Editor = ed;
			ctxt = c;
			res = r;
			curScope = cs;
		}
        static void HandleNewExpression(NewExpression nex, 
			ArgumentsResolutionResult res, 
			IEditorData Editor, 
			ResolverContextStack ctxt,
			IBlockNode curBlock)
        {
            res.MethodIdentifier = nex;
            CalculateCurrentArgument(nex, res, Editor.CaretLocation, ctxt);

            var type = TypeDeclarationResolver.ResolveSingle(nex.Type, ctxt) as ClassType;

            //TODO: Inform the user that only classes can be instantiated
            if (type != null)
            {
                var constructors = new List<DMethod>();
                bool explicitCtorFound = false;

                foreach (var member in type.Definition)
                {
                    var dm = member as DMethod;

                    if (dm != null && dm.SpecialType == DMethod.MethodType.Constructor)
                    {
                        explicitCtorFound = true;
                        if (!dm.IsPublic)
                        {
                            var curNode = curBlock;
                            bool pass = false;
                            do
                            {
                                if (curNode == type.Definition)
                                {
                                    pass = true;
                                    break;
                                }
                            }
                            while ((curNode = curNode.Parent as IBlockNode) != curNode);

                            if (!pass)
                                continue;
                        }

                        constructors.Add(dm);
                    }
                }

                if (constructors.Count == 0)
                {
                    if (explicitCtorFound)
                    {
                        // TODO: Somehow inform the user that the current class can't be instantiated
                    }
                    else
                    {
                        // Introduce default constructor
                        constructors.Add(new DMethod(DMethod.MethodType.Constructor)
                        {
                            Description = "Default constructor for " + type.Name,
                            Parent = type.Definition
                        });
                    }
                }

                // Wrapp all ctor members in MemberSymbols
                var _ctors = new List<AbstractType>();
                foreach (var ctor in constructors)
                    _ctors.Add(new MemberSymbol(ctor, type, nex.Type));
                res.ResolvedTypesOrMethods = _ctors.ToArray();

                //TODO: Probably pre-select the current ctor by handling previously typed arguments etc.
            }
        }
		DMethodOverloadProvider(ArgumentsResolutionResult argsResult)
		{
			ParameterData = argsResult;
			SelectedIndex = ParameterData.CurrentlyCalledMethod;
		}