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; //var realStartLocation = data.OffsetToLocation (offset); var model = parsedDocument.GetAst <SemanticModel> (); return(GetInsertionPoints(data, model, type, part)); }
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); }