private static void TestIsEmpty(SourceText text) { Assert.Equal(0, text.Length); Assert.Same(string.Empty, text.ToString()); Assert.Equal(1, text.Lines.Count); Assert.Equal(0, text.Lines[0].Span.Length); }
public override IReadOnlyList<TextChangeRange> GetChangeRanges(SourceText oldText) { if (oldText == null) { throw new ArgumentNullException(nameof(oldText)); } if (ReferenceEquals(_oldText, oldText)) { // check whether the bases are same one return _changes; } if (_oldText.GetChangeRanges(oldText).Count == 0) { // okay, the bases are different, but the contents might be same. return _changes; } if (this == oldText) { return TextChangeRange.NoChanges; } return ImmutableArray.Create(new TextChangeRange(new TextSpan(0, oldText.Length), _newText.Length)); }
private static List<SymbolDisplayPart> ConvertClassifications( SourceText sourceText, IEnumerable<ClassifiedSpan> classifiedSpans) { var parts = new List<SymbolDisplayPart>(); ClassifiedSpan? lastSpan = null; foreach (var span in classifiedSpans) { // If there is space between this span and the last one, then add a space. if (lastSpan != null && lastSpan.Value.TextSpan.End != span.TextSpan.Start) { parts.AddRange(Space()); } var kind = GetClassificationKind(span.ClassificationType); if (kind != null) { parts.Add(new SymbolDisplayPart(kind.Value, null, sourceText.ToString(span.TextSpan))); lastSpan = span; } } return parts; }
public async Task<IEnumerable<Range>> Classify(Document document, SourceText text) { var span = TextSpan.FromBounds(0, text.Length); IEnumerable<ClassifiedSpan> classifiedSpans = null; try { classifiedSpans = await Classifier.GetClassifiedSpansAsync(document, span); } catch (Exception ex) { Log.Exception(ex, "Exception during Classification of document: " + document.FilePath); return null; } var ranges = classifiedSpans.Select(classifiedSpan => new Range { ClassifiedSpan = classifiedSpan, Text = text.GetSubText(classifiedSpan.TextSpan).ToString() }); ranges = Merge(text, ranges); ranges = FilterByClassification(ranges); ranges = FillGaps(text, ranges); return ranges; }
internal override bool IsInsertionTrigger(SourceText text, int characterPosition, OptionSet options) { var ch = text[characterPosition]; return ch == ' ' || (CompletionUtilities.IsStartingNewWord(text, characterPosition) && options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp)); }
internal static CacheIndentEngine CreateEngine(string text, out SourceText sourceText, OptionSet options = null) { if (options == null) { options = FormattingOptionsFactory.CreateMono (); // options.AlignToFirstIndexerArgument = formatOptions.AlignToFirstMethodCallArgument = true; } var sb = new StringBuilder (); int offset = 0; for (int i = 0; i < text.Length; i++) { var ch = text [i]; if (ch == '$') { offset = i; continue; } sb.Append (ch); } sourceText = SourceText.From (sb.ToString ()); var result = new CacheIndentEngine (new CSharpIndentEngine (options)); result.Update (sourceText, offset); return result; }
private static List<SymbolDisplayPart> ConvertClassifications( SourceText sourceText, int startPosition, IEnumerable<ClassifiedSpan> classifiedSpans, bool insertSourceTextInGaps = false) { var parts = new List<SymbolDisplayPart>(); foreach (var span in classifiedSpans) { // If there is space between this span and the last one, then add a space. if (startPosition != span.TextSpan.Start) { if (insertSourceTextInGaps) { parts.Add(new SymbolDisplayPart(SymbolDisplayPartKind.Text, null, sourceText.ToString(TextSpan.FromBounds( startPosition, span.TextSpan.Start)))); } else { parts.AddRange(Space()); } } var kind = GetClassificationKind(span.ClassificationType); if (kind != null) { parts.Add(new SymbolDisplayPart(kind.Value, null, sourceText.ToString(span.TextSpan))); startPosition = span.TextSpan.End; } } return parts; }
private IEnumerable<IEnumerable<TextChange>> PartitionChangesForDocument(IEnumerable<TextChange> changes, SourceText originalSourceText) { var partitionedChanges = new List<IEnumerable<TextChange>>(); var currentPartition = new List<TextChange>(); currentPartition.Add(changes.First()); var currentPartitionEndLine = originalSourceText.Lines.GetLineFromPosition(changes.First().Span.End); foreach (var change in changes.Skip(1)) { // If changes are on adjacent lines, consider them part of the same change. var changeStartLine = originalSourceText.Lines.GetLineFromPosition(change.Span.Start); if (changeStartLine.LineNumber >= currentPartitionEndLine.LineNumber + 2) { partitionedChanges.Add(currentPartition); currentPartition = new List<TextChange>(); } currentPartition.Add(change); currentPartitionEndLine = originalSourceText.Lines.GetLineFromPosition(change.Span.End); } if (currentPartition.Any()) { partitionedChanges.Add(currentPartition); } return partitionedChanges; }
public void UpdateText(SourceText newText) { _updatding = true; _editor.Document.BeginUpdate(); try { var changes = newText.GetTextChanges(_currentText); var offset = 0; foreach (var change in changes) { _editor.Document.Replace(change.Span.Start + offset, change.Span.Length, new StringTextSource(change.NewText)); offset += change.NewText.Length - change.Span.Length; } _currentText = newText; } finally { _updatding = false; _editor.Document.EndUpdate(); } }
public AvalonEditTextContainer(TextEditor editor) { _editor = editor; _currentText = SourceText.From(_editor.Text); _editor.Document.Changed += DocumentOnChanged; }
public AddAdditionalDocumentUndoUnit( VisualStudioWorkspaceImpl workspace, DocumentInfo docInfo, SourceText text) : base(workspace, docInfo, text) { }
private List<TextChange> GetCommentChangesForDocument(IEnumerable<IEnumerable<TextChange>> partitionedChanges, string projectName, SourceText oldDocumentText, SourceText newDocumentText) { var commentChanges = new List<TextChange>(); foreach (var changePartition in partitionedChanges) { var startPosition = changePartition.First().Span.Start; var endPosition = changePartition.Last().Span.End; var startLineStartPosition = oldDocumentText.Lines.GetLineFromPosition(startPosition).Start; var endLineEndPosition = oldDocumentText.Lines.GetLineFromPosition(endPosition).End; var oldText = oldDocumentText.GetSubText(TextSpan.FromBounds(startLineStartPosition, endLineEndPosition)); var adjustedChanges = changePartition.Select(c => new TextChange(TextSpan.FromBounds(c.Span.Start - startLineStartPosition, c.Span.End - startLineStartPosition), c.NewText)); var newText = oldText.WithChanges(adjustedChanges); var warningText = GetConflictCommentText( string.Format(WorkspacesResources.UnmergedChangeFromProject, projectName), TrimBlankLines(oldText), TrimBlankLines(newText)); if (warningText != null) { commentChanges.Add(new TextChange(TextSpan.FromBounds(startLineStartPosition, startLineStartPosition), warningText)); } } return commentChanges; }
private TextChange Collapse(SourceText newText, List<TextChange> changes) { if (changes.Count == 0) { return new TextChange(new TextSpan(0, 0), ""); } else if (changes.Count == 1) { return changes[0]; } // The span we want to replace goes from the start of the first span to the end of // the last span. var totalOldSpan = TextSpan.FromBounds(changes.First().Span.Start, changes.Last().Span.End); // We figure out the text we're replacing with by actually just figuring out the // new span in the newText and grabbing the text out of that. The newSpan will // start from the same position as the oldSpan, but it's length will be the old // span's length + all the deltas we accumulate through each text change. i.e. // if the first change adds 2 characters and the second change adds 4, then // the newSpan will be 2+4=6 characters longer than the old span. var sumOfDeltas = changes.Sum(c => c.NewText.Length - c.Span.Length); var totalNewSpan = new TextSpan(totalOldSpan.Start, totalOldSpan.Length + sumOfDeltas); return new TextChange(totalOldSpan, newText.ToString(totalNewSpan)); }
internal ApiLine(string text, TextSpan span, SourceText sourceText, string path) { Text = text; Span = span; SourceText = sourceText; Path = path; }
public void UpdateActiveStatementSpans(SourceText source, IEnumerable<KeyValuePair<ActiveStatementId, TextSpan>> spans) { foreach (var span in spans) { TrackingSpans[span.Key.Ordinal] = span.Value.Length > 0 ? span.Value : (TextSpan?)null; } }
private string GetPathThroughLastSlash(SourceText text, int position, Group quotedPathGroup) { return PathCompletionUtilities.GetPathThroughLastSlash( quotedPath: quotedPathGroup.Value, quotedPathStart: GetQuotedPathStart(text, position, quotedPathGroup), position: position); }
private TextSpan GetTextChangeSpan(SourceText text, int position, Group quotedPathGroup) { return PathCompletionUtilities.GetTextChangeSpan( quotedPath: quotedPathGroup.Value, quotedPathStart: GetQuotedPathStart(text, position, quotedPathGroup), position: position); }
private static IEnumerable<Range> FillGaps(SourceText text, IEnumerable<Range> ranges) { const string WhitespaceClassification = null; int current = 0; Range previous = null; foreach (Range range in ranges) { int start = range.TextSpan.Start; if (start > current) { yield return new Range(WhitespaceClassification, TextSpan.FromBounds(current, start), text); } if (previous == null || range.TextSpan != previous.TextSpan) { yield return range; } previous = range; current = range.TextSpan.End; } if (current < text.Length) { yield return new Range(WhitespaceClassification, TextSpan.FromBounds(current, text.Length), text); } }
internal static bool IsTriggerCharacter(SourceText text, int characterPosition, OptionSet options) { var ch = text[characterPosition]; if (ch == '.') { return true; } // Trigger for directive if (ch == '#') { return true; } // Trigger on pointer member access if (ch == '>' && characterPosition >= 1 && text[characterPosition - 1] == '-') { return true; } // Trigger on alias name if (ch == ':' && characterPosition >= 1 && text[characterPosition - 1] == ':') { return true; } if (options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp) && IsStartingNewWord(text, characterPosition)) { return true; } return false; }
internal static bool IsTriggerAfterSpaceOrStartOfWordCharacter(SourceText text, int characterPosition, OptionSet options) { // Bring up on space or at the start of a word. var ch = text[characterPosition]; return SpaceTypedNotBeforeWord(ch, text, characterPosition) || (IsStartingNewWord(text, characterPosition) && options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp)); }
internal ApiLine(string text, TextSpan span, SourceText sourceText, string path) { this.Text = text; this.Span = span; this.SourceText = sourceText; this.Path = path; }
protected SyntacticDocument(Document document, SourceText text, SyntaxTree tree, SyntaxNode root) { this.Document = document; this.Text = text; this.SyntaxTree = tree; this.Root = root; }
private async Task<Document> DetermineNewDocumentAsync(CompletionItem completionItem, SourceText sourceText, CancellationToken cancellationToken) { // The span we're going to replace var line = sourceText.Lines[MemberInsertionCompletionItem.GetLine(completionItem)]; //var line = textSnapshot.GetLineFromLineNumber(MemberInsertionCompletionItem.GetLine(completionItem)); //var sourceText = textSnapshot.AsText(); var document = sourceText.GetOpenDocumentInCurrentContextWithChanges(); Contract.ThrowIfNull(document); // Annotate the line we care about so we can find it after adding usings var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = GetToken(completionItem, tree, cancellationToken); var annotatedRoot = tree.GetRoot(cancellationToken).ReplaceToken(token, token.WithAdditionalAnnotations(_otherAnnotation)); document = document.WithSyntaxRoot(annotatedRoot); var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false); var insertionRoot = await PrepareTreeForMemberInsertionAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false); var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false); var destinationSpan = ComputeDestinationSpan(insertionRoot, insertionText); var finalText = insertionRoot.GetText(sourceText.Encoding).Replace(destinationSpan, insertionText.Trim()); document = document.WithText(finalText); var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End)); document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation))); return Formatter.FormatAsync(document, _annotation, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken); }
private RazorSyntaxTree ParseSourceText(string filePath, SourceText sourceText) { var sourceDocument = sourceText.GetRazorSourceDocument(filePath, filePath); var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, ParserOptions); return(syntaxTree); }
/// <summary> /// Return startLineBreak = index-1, lengthLineBreak = 2 if there is a \r\n at index-1 /// Return startLineBreak = index, lengthLineBreak = 1 if there is a 1-char newline at index /// Return startLineBreak = index+1, lengthLineBreak = 0 if there is no newline at index. /// </summary> public static void GetStartAndLengthOfLineBreakEndingAt(SourceText text, int index, out int startLinebreak, out int lengthLinebreak) { char c = text[index]; if (c == '\n') { if (index > 0 && text[index - 1] == '\r') { // "\r\n" is the only 2-character line break. startLinebreak = index - 1; lengthLinebreak = 2; } else { startLinebreak = index; lengthLinebreak = 1; } } else if (IsAnyLineBreakCharacter(c)) { startLinebreak = index; lengthLinebreak = 1; } else { startLinebreak = index + 1; lengthLinebreak = 0; } }
public static TextSpan GetWordSpan(SourceText text, int position, Func<char, bool> isWordStartCharacter, Func<char, bool> isWordCharacter) { int start = position; while (start > 0 && isWordStartCharacter(text[start - 1])) { start--; } // If we're brought up in the middle of a word, extend to the end of the word as well. // This means that if a user brings up the completion list at the start of the word they // will "insert" the text before what's already there (useful for qualifying existing // text). However, if they bring up completion in the "middle" of a word, then they will // "overwrite" the text. Useful for correcting misspellings or just replacing unwanted // code with new code. int end = position; if (start != position) { while (end < text.Length && isWordCharacter(text[end])) { end++; } } return TextSpan.FromBounds(start, end); }
public static StringSplitter Create( Document document, int position, SyntaxTree syntaxTree, SyntaxNode root, SourceText sourceText, bool useTabs, int tabSize, CancellationToken cancellationToken) { var token = root.FindToken(position); if (token.IsKind(SyntaxKind.StringLiteralToken)) { return new SimpleStringSplitter( document, position, syntaxTree, root, sourceText, token, useTabs, tabSize, cancellationToken); } var interpolatedStringExpression = TryGetInterpolatedStringExpression(token, position); if (interpolatedStringExpression != null) { return new InterpolatedStringSplitter( document, position, syntaxTree, root, sourceText, interpolatedStringExpression, useTabs, tabSize, cancellationToken); } return null; }
protected AbstractMethodXmlBuilder(IMethodSymbol symbol, SemanticModel semanticModel) { _builder = new StringBuilder(); this.Symbol = symbol; this.SemanticModel = semanticModel; this.Text = semanticModel.SyntaxTree.GetText(); }
public void UpdateActiveStatementSpans(SourceText source, IEnumerable<KeyValuePair<ActiveStatementId, TextSpan>> spans) { TrackingSession session = _session; if (session != null) { session.UpdateActiveStatementSpans(source, spans); } }
public override bool IsTriggerCharacter(Microsoft.CodeAnalysis.Text.SourceText text, int position) { var ch = text [position]; return(ch == '#' || ch == ' ' && position >= 1 && !char.IsWhiteSpace(text [position - 1]) || IsStartingNewWord(text, position)); }
public static DocumentId AddDocument(this Workspace workspace, ProjectId projectId, IEnumerable<string> folders, string name, SourceText initialText, SourceCodeKind sourceCodeKind = SourceCodeKind.Regular) { var id = projectId.CreateDocumentId(name, folders); var oldSolution = workspace.CurrentSolution; var newSolution = oldSolution.AddDocument(id, name, initialText, folders).GetDocument(id).WithSourceCodeKind(sourceCodeKind).Project.Solution; workspace.TryApplyChanges(newSolution); return id; }
private TextBufferContainer(ITextBuffer editorBuffer, Encoding encoding) { Contract.ThrowIfNull(editorBuffer); Contract.ThrowIfNull(encoding); _weakEditorBuffer = new WeakReference<ITextBuffer>(editorBuffer); _currentText = new SnapshotSourceText(TextBufferMapper.ToRoslyn(editorBuffer.CurrentSnapshot), encoding, this); }
private static List <PropertyDeclarationSyntax> ExtractCSharpProperties(SourceText newText, IReadOnlyList <RazorDirectiveSyntax> codeBlocks) { var propertyList = new List <PropertyDeclarationSyntax>(); for (var i = 0; i < codeBlocks.Count; i++) { var bodyRange = ((RazorDirectiveBodySyntax)codeBlocks[i].Body).CSharpCode.Span; var bodyTextSpan = TextSpan.FromBounds(bodyRange.Start, bodyRange.End); var subText = newText.GetSubText(bodyTextSpan); var parsedText = CSharpSyntaxTree.ParseText(subText); var root = parsedText.GetRoot(); var childNodes = root.ChildNodes(); var properties = childNodes.Where(node => node.Kind() == CodeAnalysis.CSharp.SyntaxKind.PropertyDeclaration).OfType <PropertyDeclarationSyntax>(); propertyList.AddRange(properties); } return(propertyList); }
private bool TryGetSyntaxTreeAndSource(DocumentSnapshot document, out RazorSyntaxTree syntaxTree, out SourceText sourceText) { if (!document.TryGetText(out sourceText)) { // Can't get the source text synchronously syntaxTree = null; return(false); } if (document.TryGetGeneratedOutput(out var codeDocument)) { syntaxTree = codeDocument.GetSyntaxTree(); return(true); } syntaxTree = ParseSourceText(document.FilePath, sourceText); return(true); }
public override bool IsTriggerCharacter(Microsoft.CodeAnalysis.Text.SourceText text, int characterPosition) { return(base.IsTriggerCharacter(text, characterPosition) || text [characterPosition] == ' '); }
public LineInfo(SourceText text, int[] lineStarts) { _text = text; _lineStarts = lineStarts; }
public StaticContainer(SourceText text) { _text = text; }
public override bool IsTriggerCharacter(Microsoft.CodeAnalysis.Text.SourceText text, int position) { var ch = text [position]; return(ch == ':' || ch == '"'); }
/// <summary> /// Initializes an instance of <see cref="TextChangeEventArgs"/>. /// </summary> /// <param name="oldText">The text before the change.</param> /// <param name="newText">The text after the change.</param> /// <param name="changes">A set of ranges for the change.</param> public TextChangeEventArgs(SourceText oldText, SourceText newText, params TextChangeRange[] changes) : this(oldText, newText, (IEnumerable <TextChangeRange>)changes) { }