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, 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); }
static void HandleNewExpression(NewExpression nex, ArgumentsResolutionResult res, IEditorData Editor, ResolutionContext ctxt, IBlockNode curBlock) { 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 = "Конструктор по умолчанию для " + 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; }
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 HandleNewExpression(NewExpression nex, ArgumentsResolutionResult res, IEditorData Editor, ResolutionContext ctxt, IBlockNode curBlock) { 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 = "Конструктор по умолчанию для " + 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. } }