/// <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); }
public static AbstractCompletionProvider Create(ICompletionDataGenerator dataGen, IEditorData Editor, string EnteredText) { if (PropertyAttributeCompletionProvider.CompletesEnteredText(EnteredText)) { return(new PropertyAttributeCompletionProvider(dataGen)); } ParserTrackerVariables trackVars = null; IStatement curStmt = null; var curBlock = DResolver.SearchBlockAt(Editor.SyntaxTree, Editor.CaretLocation, out curStmt); if (curBlock == null) { return(null); } var parsedBlock = CtrlSpaceCompletionProvider.FindCurrentCaretContext( Editor.ModuleCode, curBlock, Editor.CaretOffset, Editor.CaretLocation, out trackVars); if (trackVars != null) { if (trackVars.LastParsedObject is PostfixExpression_Access) { return new MemberCompletionProvider(dataGen) { AccessExpression = trackVars.LastParsedObject as PostfixExpression_Access, ScopedBlock = curBlock, ScopedStatement = curStmt } } ; 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)); } } if (EnteredText == "(") { return(null); } } return(new CtrlSpaceCompletionProvider(dataGen) { trackVars = trackVars, curBlock = curBlock, parsedBlock = parsedBlock }); }