public string GetExpression (Mono.TextEditor.TextEditorData data, int offset) { if (offset < 0) return ""; var doc = IdeApp.Workbench.ActiveDocument; if (doc == null) return ""; var loc = RefactoringService.GetCorrectResolveLocation (doc, data.OffsetToLocation (offset)); var unit = doc.ParsedDocument.GetAst<CompilationUnit> (); var parsedFile = doc.ParsedDocument.ParsedFile as CSharpParsedFile; var node = unit.GetNodeAt<Expression> (loc.Line, loc.Column); if (unit == null || parsedFile == null || node == null) return ""; return data.GetTextBetween (node.StartLocation, node.EndLocation); }
// string expression; /* IMember GetLanguageItem (Mono.TextEditor.Document document, LineSegment line, int offset, string expression) { string txt = document.Text; ExpressionResult expressionResult = new ExpressionResult (expression); // ExpressionResult expressionResult = expressionFinder.FindFullExpression (txt, offset); int lineNumber = document.OffsetToLineNumber (offset); expressionResult.Region = new DomRegion (lineNumber, offset - line.Offset, lineNumber, offset + expression.Length - line.Offset); expressionResult.ExpressionContext = ExpressionContext.IdentifierExpected; resolver = new NRefactoryResolver (ctx, doc.CompilationUnit, doc.TextEditor, document.FileName); ResolveResult result = resolver.Resolve (expressionResult, expressionResult.Region.Start); if (result is MemberResolveResult) return ((MemberResolveResult)result).ResolvedMember; return null; }*/ public override void Analyze (Mono.TextEditor.Document doc, LineSegment line, Chunk startChunk, int startOffset, int endOffset) { if (!MonoDevelop.Core.PropertyService.Get ("EnableSemanticHighlighting", false) || doc == null || line == null || startChunk == null) return; ctx = GetParserContext (doc); int lineNumber = doc.OffsetToLineNumber (line.Offset); ParsedDocument parsedDocument = ProjectDomService.GetParsedDocument (ctx, doc.FileName); ICompilationUnit unit = parsedDocument != null ? parsedDocument.CompilationUnit : null; if (unit == null) return; for (Chunk chunk = startChunk; chunk != null; chunk = chunk.Next) { if (chunk.Style != "text") continue; for (int i = chunk.Offset; i < chunk.EndOffset; i++) { char charBefore = i > 0 ? doc.GetCharAt (i - 1) : '}'; if (Char.IsLetter (doc.GetCharAt (i)) && !Char.IsLetterOrDigit (charBefore)) { } else { continue; } int start = i; bool wasWhitespace = false; bool wasDot = false; int bracketCount = 0; while (start > 0) { char ch = doc.GetCharAt (start); if (ch == '\n' || ch == '\r') break; if (wasWhitespace && IsNamePart(ch)) { start++; if (start < chunk.Offset) start = Int32.MaxValue; break; } if (ch == '<') { bracketCount--; if (bracketCount < 0) { start++; break; } start--; wasWhitespace = false; continue; } if (ch == '>') { if (wasWhitespace && !wasDot) break; bracketCount++; start--; wasWhitespace = false; continue; } if (!IsNamePart(ch) && !Char.IsWhiteSpace (ch) && ch != '.') { start++; break; } wasWhitespace = Char.IsWhiteSpace (ch); wasDot = ch == '.' || wasDot && wasWhitespace; start--; } int end = i; int genericCount = 0; wasWhitespace = false; List<Segment> nameSegments = new List<Segment> (); while (end < chunk.EndOffset) { char ch = doc.GetCharAt (end); if (wasWhitespace && IsNamePart(ch)) break; if (ch == '<') { genericCount = 1; while (end < doc.Length) { ch = doc.GetCharAt (end); if (ch == ',') genericCount++; if (ch == '>') { nameSegments.Add (new Segment (end, 1)); break; } end++; } break; } if (!IsNamePart(ch) && !Char.IsWhiteSpace (ch)) break; wasWhitespace = Char.IsWhiteSpace (ch); end++; } if (start >= end) continue; string typeString = doc.GetTextBetween (start, end); IReturnType returnType = NRefactoryResolver.ParseReturnType (new ExpressionResult (typeString)); int nameEndOffset = start; for (; nameEndOffset < end; nameEndOffset++) { char ch = doc.GetCharAt (nameEndOffset); if (nameEndOffset >= i && ch == '<') { nameEndOffset++; break; } } nameSegments.Add (new Segment (i, nameEndOffset - i)); int column = i - line.Offset; IType callingType = unit.GetTypeAt (lineNumber, column); List<IReturnType> genericParams = null; if (genericCount > 0) { genericParams = new List<IReturnType> (); for (int n = 0; n < genericCount; n++) genericParams.Add (new DomReturnType ("A")); } IType type = null; if (ctx != null) type = ctx.SearchType ((MonoDevelop.Projects.Dom.INode)callingType ?? unit, returnType); if (type == null && unit != null && returnType != null) type = unit.GetType (returnType.FullName, returnType.GenericArguments.Count); if (ctx != null && type == null && returnType != null) { returnType.Name += "Attribute"; type = ctx.SearchType ((MonoDevelop.Projects.Dom.INode)callingType ?? unit, returnType); } if (type != null) nameSegments.ForEach (segment => HighlightSegment (startChunk, segment, "keyword.semantic.type")); } } }