ExpressionResult FindExpression (ProjectDom dom, CodeCompletionContext ctx, int offset) { NewCSharpExpressionFinder expressionFinder = new NewCSharpExpressionFinder (dom); try { return expressionFinder.FindExpression (Editor.Text, Math.Max (ctx.TriggerOffset + offset, 0)); } catch (Exception ex) { LoggingService.LogWarning (ex.Message, ex); return null; } }
ExpressionResult FindExpression (ProjectDom dom, CodeCompletionContext ctx) { NewCSharpExpressionFinder expressionFinder = new NewCSharpExpressionFinder (dom); try { return expressionFinder.FindExpression (textEditorData, ctx.TriggerOffset); } catch (Exception ex) { LoggingService.LogWarning (ex.Message, ex); return null; } }
public MonoDevelop.Projects.Dom.ResolveResult GetLanguageItem (ProjectDom dom, Mono.TextEditor.TextEditorData data, int offset) { if (offset < 0) return null; string fileName = data.Document.FileName; IParser parser = ProjectDomService.GetParser (fileName); if (parser == null) return null; MonoDevelop.Ide.Gui.Document doc = IdeApp.Workbench.ActiveDocument; if (doc == null) return null; IResolver resolver = parser.CreateResolver (dom, doc, fileName); if (resolver == null) return null; var expressionFinder = new NewCSharpExpressionFinder (dom); int wordEnd = Math.Min (offset, data.Length - 1); if (data.GetCharAt (wordEnd) == '@') wordEnd++; while (wordEnd < data.Length && (Char.IsLetterOrDigit (data.GetCharAt (wordEnd)) || data.GetCharAt (wordEnd) == '_')) wordEnd++; while (wordEnd < data.Length - 1 && Char.IsWhiteSpace (data.GetCharAt (wordEnd))) wordEnd++; /* is checked at the end. int saveEnd = wordEnd; if (wordEnd < data.Length && data.GetCharAt (wordEnd) == '<') { int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd); if (matchingBracket > 0) wordEnd = matchingBracket; while (wordEnd < data.Length - 1 && Char.IsWhiteSpace (data.GetCharAt (wordEnd))) wordEnd++; } bool wasMethodCall = false; if (data.GetCharAt (wordEnd) == '(') { int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd); if (matchingBracket > 0) { wordEnd = matchingBracket; wasMethodCall = true; } } if (!wasMethodCall) wordEnd = saveEnd;*/ ExpressionResult expressionResult = expressionFinder.FindExpression (data, wordEnd); if (expressionResult == null) return null; ResolveResult resolveResult; DocumentLocation loc = data.Document.OffsetToLocation (offset); string savedExpression = null; // special handling for 'var' "keyword" if (expressionResult.ExpressionContext == ExpressionContext.IdentifierExpected && expressionResult.Expression != null && expressionResult.Expression.Trim () == "var") { int endOffset = data.Document.LocationToOffset (expressionResult.Region.End.Line, expressionResult.Region.End.Column); StringBuilder identifer = new StringBuilder (); for (int i = endOffset; i >= 0 && i < data.Document.Length; i++) { char ch = data.Document.GetCharAt (i); if (Char.IsWhiteSpace (ch)) continue; if (ch == '=') break; if (Char.IsLetterOrDigit (ch) || ch =='_') { identifer.Append (ch); continue; } identifer.Length = 0; break; } if (identifer.Length > 0) { expressionResult.Expression = identifer.ToString (); resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line, loc.Column)); if (resolveResult != null) { resolveResult = new MemberResolveResult (dom.GetType (resolveResult.ResolvedType)); resolveResult.ResolvedExpression = expressionResult; return resolveResult; } } } if (expressionResult.ExpressionContext == ExpressionContext.Attribute) { savedExpression = expressionResult.Expression; expressionResult.Expression = expressionResult.Expression.Trim () + "Attribute"; expressionResult.ExpressionContext = ExpressionContext.ObjectCreation; } resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line, loc.Column)); if (savedExpression != null && resolveResult == null) { expressionResult.Expression = savedExpression; resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line, loc.Column)); } // Search for possible generic parameters. // if (this.resolveResult == null || this.resolveResult.ResolvedType == null || String.IsNullOrEmpty (this.resolveResult.ResolvedType.Name)) { if (!expressionResult.Region.IsEmpty) { int j = data.Document.LocationToOffset (expressionResult.Region.End.Line, expressionResult.Region.End.Column); int bracket = 0; for (int i = j; i >= 0 && i < data.Document.Length; i++) { char ch = data.Document.GetCharAt (i); if (Char.IsWhiteSpace (ch)) continue; if (ch == '<') { bracket++; } else if (ch == '>') { bracket--; if (bracket == 0) { expressionResult.Expression += data.Document.GetTextBetween (j, i + 1); expressionResult.ExpressionContext = ExpressionContext.ObjectCreation; resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line, loc.Column)); break; } } else { if (bracket == 0) break; } } } // To resolve method overloads the full expression must be parsed. // ex.: Overload (1)/ Overload("one") - parsing "Overload" gives just a MethodResolveResult // and for constructor initializers it's tried too to to resolve constructor overloads. if (resolveResult is ThisResolveResult || resolveResult is BaseResolveResult || resolveResult is MethodResolveResult && ((MethodResolveResult)resolveResult).Methods.Count > 1) { // put the search offset at the end of the invocation to be able to find the full expression // the resolver finds it itself if spaces are between the method name and the argument opening parentheses. while (wordEnd < data.Length - 1 && Char.IsWhiteSpace (data.GetCharAt (wordEnd))) wordEnd++; if (data.GetCharAt (wordEnd) == '(') { int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd); if (matchingBracket > 0) wordEnd = matchingBracket; } //Console.WriteLine (expressionFinder.FindFullExpression (txt, wordEnd)); ResolveResult possibleResult = resolver.Resolve (expressionFinder.FindFullExpression (data, wordEnd), new DomLocation (loc.Line, loc.Column)) ?? resolveResult; //Console.WriteLine ("possi:" + resolver.Resolve (expressionFinder.FindFullExpression (txt, wordEnd), new DomLocation (loc.Line, loc.Column))); if (possibleResult is MethodResolveResult) resolveResult = possibleResult; } return resolveResult; }