Example #1
0
 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);
 }
Example #2
0
        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));
        }
Example #3
0
        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;
		}
Example #7
0
        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);
 }
Example #18
0
    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);
        }
    }
Example #19
0
        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;
        }
Example #20
0
 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);
        }
Example #25
0
 /// <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;
            }
Example #28
0
        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));
        }
Example #31
0
 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] == ' ');
 }
Example #36
0
 public LineInfo(SourceText text, int[] lineStarts)
 {
     _text       = text;
     _lineStarts = lineStarts;
 }
Example #37
0
 public StaticContainer(SourceText text)
 {
     _text = text;
 }
        public override bool IsTriggerCharacter(Microsoft.CodeAnalysis.Text.SourceText text, int position)
        {
            var ch = text [position];

            return(ch == ':' || ch == '"');
        }
Example #39
0
 /// <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)
 {
 }