static int GetLastSourceCodePosition(IReadonlyTextDocument document, int lineOffset) { var line = document.GetLineByOffset(lineOffset); bool isInBlockComment = false; bool isInLineComment = false; int curStringQuote = -1; var lang = TextMateLanguage.Create(SyntaxHighlightingService.GetScopeForFileName(document.FileName)); var lineComments = lang.LineComments.ToArray(); var blockCommentStarts = lang.BlockComments.Select(b => b.Item1).ToList(); var blockCommentEnds = lang.BlockComments.Select(b => b.Item2).ToList(); var stringQuotes = new string [] { "\"", "'" }; for (int i = 0; i < line.Length; i++) { int offset = line.Offset + i; // check line comments if (!isInBlockComment && curStringQuote < 0) { isInLineComment = StartsWithListMember(document, lineComments, offset) >= 0; if (isInLineComment) { return(System.Math.Min(offset, lineOffset)); } } // check block comments if (!isInLineComment && curStringQuote < 0) { if (!isInBlockComment) { isInBlockComment = StartsWithListMember(document, blockCommentStarts, offset) >= 0; } else { isInBlockComment = StartsWithListMember(document, blockCommentEnds, offset) < 0; } } if (!isInBlockComment && !isInLineComment) { int j = StartsWithListMember(document, stringQuotes, offset); if (j >= 0) { if (curStringQuote >= 0) { if (curStringQuote == j) { curStringQuote = -1; } } else { curStringQuote = j; } } } } return(lineOffset); }
static string GetIndent(IReadonlyTextDocument data, ISymbol member, out int offset) { var line = data.GetLineByOffset(member.Locations.First().SourceSpan.Start); offset = line.Offset; return(data.GetLineIndent(line)); }
static int GetLastSourceCodePosition(IReadonlyTextDocument document, int lineOffset) { var line = document.GetLineByOffset(lineOffset); bool isInBlockComment = false; bool isInLineComment = false; int curStringQuote = -1; IList <string> lineComments = GetList(document, "LineComment"); IList <string> blockCommentStarts = GetList(document, "BlockCommentStart"); IList <string> blockCommentEnds = GetList(document, "BlockCommentEnd"); IList <string> stringQuotes = GetList(document, "StringQuote"); for (int i = 0; i < line.Length; i++) { int offset = line.Offset + i; // check line comments if (!isInBlockComment && curStringQuote < 0) { isInLineComment = StartsWithListMember(document, lineComments, offset) >= 0; if (isInLineComment) { return(System.Math.Min(offset, lineOffset)); } } // check block comments if (!isInLineComment && curStringQuote < 0) { if (!isInBlockComment) { isInBlockComment = StartsWithListMember(document, blockCommentStarts, offset) >= 0; } else { isInBlockComment = StartsWithListMember(document, blockCommentEnds, offset) < 0; } } if (!isInBlockComment && !isInLineComment) { int j = StartsWithListMember(document, stringQuotes, offset); if (j >= 0) { if (curStringQuote >= 0) { if (curStringQuote == j) { curStringQuote = -1; } } else { curStringQuote = j; } } } } return(lineOffset); }
static bool StartsInLineComment(IReadonlyTextDocument document, int offset) { IList <string> lineComments = GetList(document, "LineComment"); var line = document.GetLineByOffset(offset); for (int i = line.Offset; i < offset; i++) { if (StartsWithListMember(document, lineComments, i) >= 0) { return(true); } } return(false); }
static bool StartsInLineComment(IReadonlyTextDocument document, int offset) { var lang = TextMateLanguage.Create(SyntaxHighlightingService.GetScopeForFileName(document.FileName)); var lineComments = lang.LineComments.ToArray(); var blockCommentStarts = lang.BlockComments.Select(b => b.Item1).ToList(); var blockCommentEnds = lang.BlockComments.Select(b => b.Item2).ToList(); var line = document.GetLineByOffset(offset); for (int i = line.Offset; i < offset; i++) { if (StartsWithListMember(document, lineComments, i) >= 0) { return(true); } } return(false); }
public override TextLine GetLineFromPosition(int position) { var line = textDoc.GetLineByOffset(position); return(TextLine.FromSpan(parent, new TextSpan(line.Offset, line.Length))); }
static int GetLastSourceCodePosition (IReadonlyTextDocument document, int lineOffset) { var line = document.GetLineByOffset (lineOffset); bool isInBlockComment = false; bool isInLineComment = false; int curStringQuote = -1; IList<string> lineComments = GetList (document, "LineComment"); IList<string> blockCommentStarts = GetList (document, "BlockCommentStart"); IList<string> blockCommentEnds = GetList (document, "BlockCommentEnd"); IList<string> stringQuotes = GetList (document, "StringQuote"); for (int i = 0; i < line.Length; i++) { int offset = line.Offset + i; // check line comments if (!isInBlockComment && curStringQuote < 0) { isInLineComment = StartsWithListMember (document, lineComments, offset) >= 0; if (isInLineComment) return System.Math.Min (offset, lineOffset); } // check block comments if (!isInLineComment && curStringQuote < 0) { if (!isInBlockComment) { isInBlockComment = StartsWithListMember (document, blockCommentStarts, offset) >= 0; } else { isInBlockComment = StartsWithListMember (document, blockCommentEnds, offset) < 0; } } if (!isInBlockComment && !isInLineComment) { int j = StartsWithListMember (document, stringQuotes, offset); if (j >= 0) { if (curStringQuote >= 0) { if (curStringQuote == j) curStringQuote = -1; } else { curStringQuote = j; } } } } return lineOffset; }
static bool StartsInLineComment (IReadonlyTextDocument document, int offset) { IList<string> lineComments = GetList (document, "LineComment"); var line = document.GetLineByOffset (offset); for (int i = line.Offset; i < offset; i++) { if (StartsWithListMember (document, lineComments, i) >= 0) return true; } return false; }
public static List <InsertionPoint> GetInsertionPoints(IReadonlyTextDocument data, MonoDevelop.Ide.TypeSystem.ParsedDocument parsedDocument, ITypeSymbol type, int part) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (parsedDocument == null) { throw new ArgumentNullException(nameof(parsedDocument)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (!type.IsDefinedInSource()) { throw new ArgumentException("The given type needs to be defined in source code.", nameof(type)); } // update type from parsed document, since this is always newer. //type = parsedDocument.GetInnermostTypeDefinition (type.GetLocation ()) ?? type; List <InsertionPoint> result = new List <InsertionPoint> (); //var realStartLocation = data.OffsetToLocation (offset); var model = parsedDocument.GetAst <SemanticModel> (); type = model.GetEnclosingNamedType(part, default(CancellationToken)) as ITypeSymbol ?? type; var sourceSpan = new TextSpan(part, 0); var filePath = data.FileName; var declaringType = type.DeclaringSyntaxReferences.FirstOrDefault(dsr => dsr.SyntaxTree.FilePath == filePath && dsr.Span.Contains(sourceSpan)) ?? type.DeclaringSyntaxReferences.FirstOrDefault(); if (declaringType == null) { return(result); } var openBraceToken = declaringType.GetSyntax().ChildTokens().FirstOrDefault(t => t.IsKind(SyntaxKind.OpenBraceToken)); if (!openBraceToken.IsMissing) { var domLocation = data.OffsetToLocation(openBraceToken.SpanStart); result.Add(GetInsertionPosition(data, domLocation.Line, domLocation.Column)); // result.Add (GetInsertionPosition (data, realStartLocation.Line, realStartLocation.Column)); result [0].LineBefore = NewLineInsertion.None; } foreach (var member in type.GetMembers()) { if (member.IsImplicitlyDeclared || !member.IsDefinedInSource()) { continue; } //var domLocation = member.BodyRegion.End; foreach (var loc in member.DeclaringSyntaxReferences) { if (loc.SyntaxTree.FilePath != declaringType.SyntaxTree.FilePath || !declaringType.Span.Contains(sourceSpan)) { continue; } var domLocation = data.OffsetToLocation(loc.Span.End); if (domLocation.Line <= 0) { var lineSegment = data.GetLineByOffset(loc.Span.Start); if (lineSegment == null) { continue; } domLocation = new DocumentLocation(lineSegment.LineNumber, lineSegment.Length + 1); } result.Add(GetInsertionPosition(data, domLocation.Line, domLocation.Column)); break; } } result [result.Count - 1].LineAfter = NewLineInsertion.None; CheckStartPoint(data, result [0], result.Count == 1); if (result.Count > 1) { result.RemoveAt(result.Count - 1); NewLineInsertion insertLine; var typeSyntaxReference = type.DeclaringSyntaxReferences.FirstOrDefault(r => r.Span.Contains(sourceSpan)); var lineBefore = data.GetLineByOffset(typeSyntaxReference.Span.End).PreviousLine; if (lineBefore != null && lineBefore.Length == lineBefore.GetIndentation(data).Length) { insertLine = NewLineInsertion.None; } else { insertLine = NewLineInsertion.Eol; } // search for line start var line = data.GetLineByOffset(typeSyntaxReference.Span.End); int col = typeSyntaxReference.Span.End - line.Offset; if (line != null) { var lineOffset = line.Offset; col = Math.Min(line.Length, col); while (lineOffset + col - 2 >= 0 && col > 1 && char.IsWhiteSpace(data.GetCharAt(lineOffset + col - 2))) { col--; } } result.Add(new InsertionPoint(new DocumentLocation(line.LineNumber, col), insertLine, NewLineInsertion.Eol)); CheckEndPoint(data, result [result.Count - 1], result.Count == 1); } // foreach (var region in parsedDocument.UserRegions.Where (r => type.BodyRegion.IsInside (r.Region.Begin))) { // result.Add (new InsertionPoint (new DocumentLocation (region.Region.BeginLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // } result.Sort((left, right) => left.Location.CompareTo(right.Location)); //foreach (var res in result) // Console.WriteLine (res); return(result); }
static List<InsertionPoint> GetInsertionPoints (IReadonlyTextDocument data, ITypeSymbol type, List<InsertionPoint> result, TextSpan sourceSpan, SyntaxReference declaringType) { var openBraceToken = declaringType.GetSyntax ().ChildTokens ().FirstOrDefault (t => t.IsKind (SyntaxKind.OpenBraceToken)); if (!openBraceToken.IsMissing) { var domLocation = data.OffsetToLocation (openBraceToken.SpanStart); result.Add (GetInsertionPosition (data, domLocation.Line, domLocation.Column)); // result.Add (GetInsertionPosition (data, realStartLocation.Line, realStartLocation.Column)); result [0].LineBefore = NewLineInsertion.None; } foreach (var member in type.GetMembers ()) { if (member.IsImplicitlyDeclared || !member.IsDefinedInSource ()) continue; //var domLocation = member.BodyRegion.End; foreach (var loc in member.DeclaringSyntaxReferences) { if (loc.SyntaxTree.FilePath != declaringType.SyntaxTree.FilePath || !declaringType.Span.Contains (sourceSpan)) continue; var domLocation = data.OffsetToLocation (loc.Span.End); if (domLocation.Line <= 0) { var lineSegment = data.GetLineByOffset (loc.Span.Start); if (lineSegment == null) continue; domLocation = new DocumentLocation (lineSegment.LineNumber, lineSegment.Length + 1); } result.Add (GetInsertionPosition (data, domLocation.Line, domLocation.Column)); break; } } result [result.Count - 1].LineAfter = NewLineInsertion.None; CheckStartPoint (data, result [0], result.Count == 1); if (result.Count > 1) { result.RemoveAt (result.Count - 1); NewLineInsertion insertLine; var typeSyntaxReference = type.DeclaringSyntaxReferences.FirstOrDefault (r => r.Span.Contains (sourceSpan)); var lineBefore = data.GetLineByOffset (typeSyntaxReference.Span.End).PreviousLine; if (lineBefore != null && lineBefore.Length == lineBefore.GetIndentation (data).Length) { insertLine = NewLineInsertion.None; } else { insertLine = NewLineInsertion.Eol; } // search for line start var line = data.GetLineByOffset (typeSyntaxReference.Span.End); int col = typeSyntaxReference.Span.End - line.Offset; if (line != null) { var lineOffset = line.Offset; col = Math.Min (line.Length, col); while (lineOffset + col - 2 >= 0 && col > 1 && char.IsWhiteSpace (data.GetCharAt (lineOffset + col - 2))) col--; } result.Add (new InsertionPoint (new DocumentLocation (line.LineNumber, col), insertLine, NewLineInsertion.Eol)); CheckEndPoint (data, result [result.Count - 1], result.Count == 1); } // foreach (var region in parsedDocument.UserRegions.Where (r => type.BodyRegion.IsInside (r.Region.Begin))) { // result.Add (new InsertionPoint (new DocumentLocation (region.Region.BeginLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // } result.Sort ((left, right) => left.Location.CompareTo (right.Location)); //foreach (var res in result) // Console.WriteLine (res); return result; }
public static List<InsertionPoint> GetInsertionPoints (IReadonlyTextDocument data, MonoDevelop.Ide.TypeSystem.ParsedDocument parsedDocument, ITypeSymbol type, int part) { if (data == null) throw new ArgumentNullException (nameof (data)); if (parsedDocument == null) throw new ArgumentNullException (nameof (parsedDocument)); if (type == null) throw new ArgumentNullException (nameof (type)); if (!type.IsDefinedInSource ()) throw new ArgumentException ("The given type needs to be defined in source code.", nameof (type)); // update type from parsed document, since this is always newer. //type = parsedDocument.GetInnermostTypeDefinition (type.GetLocation ()) ?? type; List<InsertionPoint> result = new List<InsertionPoint> (); //var realStartLocation = data.OffsetToLocation (offset); var model = parsedDocument.GetAst<SemanticModel> (); type = model.GetEnclosingNamedType (part, default(CancellationToken)) as ITypeSymbol ?? type; var sourceSpan = new TextSpan (part, 0); var filePath = data.FileName; var declaringType = type.DeclaringSyntaxReferences.FirstOrDefault (dsr => dsr.SyntaxTree.FilePath == filePath && dsr.Span.Contains (sourceSpan)) ?? type.DeclaringSyntaxReferences.FirstOrDefault (); if (declaringType == null) return result; var openBraceToken = declaringType.GetSyntax ().ChildTokens ().FirstOrDefault (t => t.IsKind (SyntaxKind.OpenBraceToken)); if (!openBraceToken.IsMissing) { var domLocation = data.OffsetToLocation (openBraceToken.SpanStart); result.Add (GetInsertionPosition (data, domLocation.Line, domLocation.Column)); // result.Add (GetInsertionPosition (data, realStartLocation.Line, realStartLocation.Column)); result [0].LineBefore = NewLineInsertion.None; } foreach (var member in type.GetMembers ()) { if (member.IsImplicitlyDeclared || !member.IsDefinedInSource()) continue; //var domLocation = member.BodyRegion.End; foreach (var loc in member.DeclaringSyntaxReferences) { if (loc.SyntaxTree.FilePath != declaringType.SyntaxTree.FilePath || !declaringType.Span.Contains (sourceSpan)) continue; var domLocation = data.OffsetToLocation (loc.Span.End); if (domLocation.Line <= 0) { var lineSegment = data.GetLineByOffset (loc.Span.Start); if (lineSegment == null) continue; domLocation = new DocumentLocation (lineSegment.LineNumber, lineSegment.Length + 1); } result.Add (GetInsertionPosition (data, domLocation.Line, domLocation.Column)); break; } } result [result.Count - 1].LineAfter = NewLineInsertion.None; CheckStartPoint (data, result [0], result.Count == 1); if (result.Count > 1) { result.RemoveAt (result.Count - 1); NewLineInsertion insertLine; var typeSyntaxReference = type.DeclaringSyntaxReferences.FirstOrDefault (r => r.Span.Contains (sourceSpan)); var lineBefore = data.GetLineByOffset (typeSyntaxReference.Span.End).PreviousLine; if (lineBefore != null && lineBefore.Length == lineBefore.GetIndentation (data).Length) { insertLine = NewLineInsertion.None; } else { insertLine = NewLineInsertion.Eol; } // search for line start var line = data.GetLineByOffset (typeSyntaxReference.Span.End); int col = typeSyntaxReference.Span.End - line.Offset; if (line != null) { var lineOffset = line.Offset; col = Math.Min (line.Length, col); while (lineOffset + col - 2 >= 0 && col > 1 && char.IsWhiteSpace (data.GetCharAt (lineOffset + col - 2))) col--; } result.Add (new InsertionPoint (new DocumentLocation (line.LineNumber, col), insertLine, NewLineInsertion.Eol)); CheckEndPoint (data, result [result.Count - 1], result.Count == 1); } // foreach (var region in parsedDocument.UserRegions.Where (r => type.BodyRegion.IsInside (r.Region.Begin))) { // result.Add (new InsertionPoint (new DocumentLocation (region.Region.BeginLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // } result.Sort ((left, right) => left.Location.CompareTo (right.Location)); //foreach (var res in result) // Console.WriteLine (res); return result; }
static List <InsertionPoint> GetInsertionPoints(IReadonlyTextDocument data, ITypeSymbol type, List <InsertionPoint> result, TextSpan sourceSpan, SyntaxReference declaringType) { var openBraceToken = declaringType.GetSyntax().ChildTokens().FirstOrDefault(t => t.IsKind(SyntaxKind.OpenBraceToken)); if (!openBraceToken.IsMissing) { var domLocation = data.OffsetToLocation(openBraceToken.SpanStart); result.Add(GetInsertionPosition(data, domLocation.Line, domLocation.Column)); // result.Add (GetInsertionPosition (data, realStartLocation.Line, realStartLocation.Column)); result [0].LineBefore = NewLineInsertion.None; } foreach (var member in type.GetMembers()) { if (member.IsImplicitlyDeclared || !member.IsDefinedInSource()) { continue; } //var domLocation = member.BodyRegion.End; foreach (var loc in member.DeclaringSyntaxReferences) { if (loc.SyntaxTree.FilePath != declaringType.SyntaxTree.FilePath || !declaringType.Span.Contains(sourceSpan)) { continue; } var domLocation = data.OffsetToLocation(loc.Span.End); if (domLocation.Line <= 0) { var lineSegment = data.GetLineByOffset(loc.Span.Start); if (lineSegment == null) { continue; } domLocation = new DocumentLocation(lineSegment.LineNumber, lineSegment.Length + 1); } result.Add(GetInsertionPosition(data, domLocation.Line, domLocation.Column)); break; } } result [result.Count - 1].LineAfter = NewLineInsertion.None; CheckStartPoint(data, result [0], result.Count == 1); if (result.Count > 1) { result.RemoveAt(result.Count - 1); NewLineInsertion insertLine; var typeSyntaxReference = type.DeclaringSyntaxReferences.FirstOrDefault(r => r.SyntaxTree.FilePath == data.FileName && r.Span.Contains(sourceSpan)); var lineBefore = data.GetLineByOffset(typeSyntaxReference.Span.End).PreviousLine; if (lineBefore != null && lineBefore.Length == lineBefore.GetIndentation(data).Length) { insertLine = NewLineInsertion.None; } else { insertLine = NewLineInsertion.Eol; } // search for line start var line = data.GetLineByOffset(typeSyntaxReference.Span.End); int col = typeSyntaxReference.Span.End - line.Offset; if (line != null) { var lineOffset = line.Offset; col = Math.Min(line.Length, col); while (lineOffset + col - 2 >= 0 && col > 1 && char.IsWhiteSpace(data.GetCharAt(lineOffset + col - 2))) { col--; } } result.Add(new InsertionPoint(new DocumentLocation(line.LineNumber, col), insertLine, NewLineInsertion.Eol)); CheckEndPoint(data, result [result.Count - 1], result.Count == 1); } // foreach (var region in parsedDocument.UserRegions.Where (r => type.BodyRegion.IsInside (r.Region.Begin))) { // result.Add (new InsertionPoint (new DocumentLocation (region.Region.BeginLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); // } result.Sort((left, right) => left.Location.CompareTo(right.Location)); //foreach (var res in result) // Console.WriteLine (res); return(result); }
static string GetIndent (IReadonlyTextDocument data, ISymbol member, out int offset) { var line = data.GetLineByOffset (member.Locations.First().SourceSpan.Start); offset = line.Offset; return data.GetLineIndent (line); }
static bool IsSingleLine(IReadonlyTextDocument editor, BlockSpan blockSpan) { var startLine = editor.GetLineByOffset(blockSpan.TextSpan.Start); return(blockSpan.TextSpan.End <= startLine.EndOffsetIncludingDelimiter); }
void TrackDocument_TextChanged(object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) { if (lineStates == null || e.TextChanges.Count == 0) { return; } for (int i = e.TextChanges.Count - 1; i >= 0; i--) { var change = e.TextChanges [i]; if (change.RemovalLength == 0) { continue; } var startLine = trackDocumentSnapshot.GetLineByOffset(change.Offset); var endRemoveLine = trackDocumentSnapshot.GetLineByOffset(change.Offset + change.RemovalLength); if (startLine == null || endRemoveLine == null) { continue; } try { var lineNumber = startLine.LineNumber; lineStates.RemoveRange(lineNumber, endRemoveLine.LineNumber - lineNumber); } catch (Exception ex) { LoggingService.LogError("error while DiffTracker.TrackDocument_TextChanged changing update", ex); } } for (int i = 0; i < e.TextChanges.Count; ++i) { var change = e.TextChanges[i]; var startLine = trackDocument.GetLineByOffset(change.NewOffset); var endLine = trackDocument.GetLineByOffset(change.NewOffset + change.InsertionLength); var lineNumber = startLine.LineNumber; var insertedLines = endLine.LineNumber - lineNumber; if (insertedLines == 0) { var oldState = lineNumber < lineStates.Count ? lineStates [lineNumber] : null; if (oldState != null && oldState.state == TextDocument.LineState.Dirty) { continue; } lineStates[lineNumber] = LineChangeInfo.Dirty; if (trackDocument != null) { trackDocument.CommitMultipleLineUpdate(lineNumber, lineNumber + insertedLines); } continue; } try { lineStates.InsertRange(lineNumber, insertedLines, LineChangeInfo.Dirty); if (trackDocument != null) { trackDocument.CommitMultipleLineUpdate(lineNumber, lineNumber + insertedLines); } } catch (Exception ex) { LoggingService.LogError("error while DiffTracker.TrackDocument_TextChanged changed update", ex); } } trackDocumentSnapshot = trackDocument.CreateDocumentSnapshot(); }