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