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