コード例 #1
0
        /// <summary>
        /// Determines whether a specified C# using directive can be removed.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="usingDirective">The using directive.</param>
        /// <returns><c>true</c> if the specified using directive can be removed; otherwise, <c>false</c>.</returns>
        /// <remarks>As long as the using is represented as a T4 import directive in the root file, it can be removed.</remarks>
        public bool CanRemoveUsing(IDocument document, IUsingDirective usingDirective)
        {
            TreeTextRange nameRange = GetNameRange(usingDirective);

            if (!nameRange.IsValid())
            {
                return(false);
            }

            IFile containingFile = usingDirective.GetContainingFile();

            if (containingFile == null)
            {
                return(false);
            }

            DocumentRange documentRange = containingFile.GetDocumentRange(nameRange);

            return(documentRange.IsValid() && documentRange.Document == document);

//			IReferenceName namespaceNode = usingDirective.GetUsedNamespaceNode();
//			if (namespaceNode == null)
//				return false;
//
//			var directive = namespaceNode.GetT4ContainerFromCSharpNode<IT4Directive>();
//			return directive != null && directive.GetContainingNode<IT4Include>() == null;
        }
コード例 #2
0
        /// <summary>
        /// The process of generated document commit (in the case of primary document incremental reparse) can be overridden in this method.
        /// Returns null if full regeneration is required.
        /// This method is not allowed to do destructive changes due to interruptibility!
        /// </summary>
        public override ICollection <IPreCommitResult> ExecuteSecondaryDocumentCommitWork(PrimaryFileModificationInfo primaryFileModificationInfo,
                                                                                          CachedPsiFile cachedPsiFile, TreeTextRange oldTreeRange, string newText)
        {
            var rangeTranslator = (RangeTranslatorWithGeneratedRangeMap)cachedPsiFile.PsiFile.SecondaryRangeTranslator;

            if (rangeTranslator == null)
            {
                return(null);
            }

            TreeTextRange range         = rangeTranslator.OriginalToGenerated(oldTreeRange, JetPredicate <IUserDataHolder> .True);
            DocumentRange documentRange = cachedPsiFile.PsiFile.DocumentRangeTranslator.Translate(range);

            if (!documentRange.IsValid())
            {
                return(null);
            }

            var documentChange = new DocumentChange(documentRange.Document, documentRange.TextRange.StartOffset, documentRange.TextRange.Length, newText,
                                                    documentRange.Document.LastModificationStamp, TextModificationSide.NotSpecified);

            return(new IPreCommitResult[] {
                new PreCommitResult(cachedPsiFile.WorkIncrementalParse(documentChange), null, documentChange, null, TextRange.InvalidRange, string.Empty),
                new FixRangeTranslatorsOnSharedRangeCommitResult(rangeTranslator, null, new TreeTextRange <Original>(oldTreeRange),
                                                                 new TreeTextRange <Generated>(range), newText)
            });
        }
コード例 #3
0
        /// <summary>
        /// Finds a valid presentable element represented at a given <see cref="DocumentRange"/>.
        /// </summary>
        /// <param name="documentRange">The document range where to find a <see cref="IDeclaredElement"/> or a <see cref="ILiteralExpression"/>.</param>
        /// <returns>A <see cref="PresentableInfo"/> which may not be valid if nothing was found.</returns>
        private PresentableInfo FindPresentable(DocumentRange documentRange)
        {
            IDocument document = documentRange.Document;

            if (document == null || !documentRange.IsValid())
            {
                return(default);
コード例 #4
0
ファイル: T4TreeExtensions.cs プロジェクト: troshko111/ForTea
        internal static T GetT4ContainerFromCSharpNode <T>([CanBeNull] this ITreeNode cSharpNode)
            where T : ITreeNode
        {
            if (cSharpNode == null)
            {
                return(default(T));
            }

            var cSharpFile = cSharpNode.GetContainingFile() as IFileImpl;

            if (cSharpFile == null || cSharpFile.SecondaryRangeTranslator == null)
            {
                return(default(T));
            }

            DocumentRange range = cSharpNode.GetDocumentRange();

            if (!range.IsValid())
            {
                return(default(T));
            }

            ITreeNode t4Node = cSharpFile.SecondaryRangeTranslator.OriginalFile.FindNodeAt(range);

            if (t4Node == null)
            {
                return(default(T));
            }

            return(t4Node.GetContainingNode <T>(true));
        }
コード例 #5
0
        private void DoFormatStatementOnSemicolon(ITextControl textControl)
        {
            IFile file = CommitPsi(textControl);

            if (file == null)
            {
                return;
            }
            int charPos = TextControlToLexer(textControl, textControl.Caret.Offset());

            if (charPos < 0)
            {
                return;
            }

            var tokenNode = file.FindTokenAt(textControl.Document, charPos - 1) as ITokenNode;

            if (tokenNode == null || tokenNode.GetTokenType() != PsiTokenType.SEMICOLON)
            {
                return;
            }

            var node = tokenNode.Parent;

            // do format if semicolon finished the statement
            if (node == null || tokenNode.NextSibling != null)
            {
                return;
            }

            // Select the correct start node for formatting
            ITreeNode startNode = node.FindFormattingRangeToLeft();

            if (startNode == null)
            {
                startNode = node.FirstChild;
            }

            PsiCodeFormatter codeFormatter = GetCodeFormatter(tokenNode);

            using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(PsiServices, "Format code"))
            {
                using (WriteLockCookie.Create())
                {
                    codeFormatter.Format(startNode, tokenNode, CodeFormatProfile.DEFAULT);
                }
            }

            DocumentRange newPosition = tokenNode.GetDocumentRange();

            if (newPosition.IsValid())
            {
                textControl.Caret.MoveTo(newPosition.TextRange.EndOffset, CaretVisualPlacement.DontScrollIfVisible);
            }
        }
コード例 #6
0
        public TreeTextRange Translate(DocumentRange documentRange)
        {
            if (!documentRange.IsValid() ||
                _sourceFile == null ||
                !_sourceFile.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }

            if (documentRange.Document != _sourceFile.Document)
            {
                foreach (IT4Include include in _includes)
                {
                    if (include.DocumentRangeTranslator != null)
                    {
                        TreeTextRange textRange = include.DocumentRangeTranslator.Translate(documentRange);
                        if (textRange.IsValid())
                        {
                            return(textRange);
                        }
                    }
                }
                return(TreeTextRange.InvalidRange);
            }

            TextRange  range           = documentRange.TextRange;
            TreeOffset rootStartOffset = _root.GetTreeStartOffset();

            // no includes, tree and document are matching
            if (_includes.Count == 0)
            {
                return(new TreeTextRange(rootStartOffset + range.StartOffset, rootStartOffset + range.EndOffset));
            }

            TreeOffset startOffset = Translate(range.StartOffset);

            if (!startOffset.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }

            TreeOffset endOffset = Translate(range.EndOffset);

            if (!endOffset.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }

            return(new TreeTextRange(startOffset, endOffset));
        }
コード例 #7
0
        //------------------------------------------------------------------------------------------------------------------------
        private static IList <IProjectFile> GetProjectFiles(DocumentManager documentManager, IDeclaredElement declaredElement)
        {
            IList <IProjectFile> results = new List <IProjectFile>();

            foreach (var declaration in declaredElement.GetDeclarations())
            {
                DocumentRange documentRange = declaration.GetNavigationRange();
                if (!documentRange.IsValid())
                {
                    documentRange = TreeNodeExtensions.GetDocumentRange(declaration);
                }

                if (documentRange.IsValid())
                {
                    IProjectFile projectFile = documentManager.TryGetProjectFile(documentRange.Document);
                    if (projectFile != null)
                    {
                        results.Add(projectFile);
                    }
                }
            }
            return(results);
        }
コード例 #8
0
        public override ISpecificCodeCompletionContext GetCompletionContext(CodeCompletionContext context)
        {
            TreeOffset startOffset = context.SelectedTreeRange.StartOffset;
            ITokenNode tokenNode   = GetTokenNode(context);

            if (tokenNode == null)
            {
                return(null);
            }

            int offset = tokenNode.GetTreeStartOffset().Offset;
            int start  = startOffset.Offset - offset;

            if (start <= 2)
            {
                return(null);
            }

            string text = tokenNode.GetText();

            if (start > text.Length)
            {
                return(null);
            }

            string commentText = text.Substring(2, start - 2);
            int    emojiStart  = commentText.LastIndexOf(':');

            if (emojiStart < 0)
            {
                return(null);
            }
            for (int index = emojiStart + 1; index < commentText.Length; ++index)
            {
                if ((index != emojiStart + 1 || !IsEmojiChar(commentText[index])) && (index <= emojiStart + 1 || !IsEmojiChar(commentText[index])))
                {
                    return(null);
                }
            }
            DocumentRange documentRange = context.File.GetDocumentRange(new TreeTextRange(new TreeOffset(offset + emojiStart + 2), new TreeOffset(offset + start)));

            if (!documentRange.IsValid())
            {
                return(null);
            }
            return(new ContextInDocComment(context, documentRange, new TextLookupRanges(documentRange.TextRange, documentRange.TextRange)));
        }
コード例 #9
0
        public TreeTextRange Translate(DocumentRange documentRange)
        {
            if (!documentRange.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }
            if (!SourceFile.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }
            if (!FileLikeNode.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }

            if (documentRange.Document != SourceFile.Document)
            {
                // That document might appear among the includes
                var rangeFromIncludes = Includes
                                        .Select(include => include.DocumentRangeTranslator.Translate(documentRange))
                                        .Where(textRange => textRange.IsValid())
                                        // Allow FirstOrDefault to return null
                                        .Select <TreeTextRange, TreeTextRange?>(it => it)
                                        .FirstOrDefault();
                return(rangeFromIncludes ?? TreeTextRange.InvalidRange);
            }

            // The range is in the same document as the source file we are responsible for,
            // so we have no choice but to handle the request ourselves
            (int documentStartOffset, int documentEndOffset) = documentRange.TextRange;
            var rootStartOffset = FileLikeNode.GetTreeStartOffset();

            // No includes, tree and document are matching
            if (!Includes.Any())
            {
                return(new TreeTextRange(rootStartOffset + documentStartOffset, rootStartOffset + documentEndOffset));
            }

            var treeStartOffset = Translate(documentStartOffset);

            if (!treeStartOffset.IsValid())
            {
                return(TreeTextRange.InvalidRange);
            }
            return(TreeTextRange.FromLength(treeStartOffset, documentRange.Length));
        }
コード例 #10
0
        private DeclaredElementInfo FindDeclaredElement(DocumentRange documentRange)
        {
            IDocument document = documentRange.Document;

            if (document == null || !documentRange.IsValid())
            {
                return(null);
            }

            IPsiServices psiServices = _solution.GetPsiServices();

            if (!psiServices.Files.AllDocumentsAreCommitted || psiServices.Caches.HasDirtyFiles)
            {
                return(null);
            }

            return(document
                   .GetPsiSourceFiles(_solution)
                   .SelectMany(
                       psiSourceFile => psiServices.Files.GetPsiFiles(psiSourceFile, documentRange),
                       (psiSourceFile, file) => FindDeclaredElement(documentRange, file))
                   .FirstOrDefault(info => info != null && info.DeclaredElement.IsValid()));
        }
コード例 #11
0
        /// <summary>
        ///     Too lazy to implement full ITemplateScopePoint
        /// </summary>
        public IEnumerable <string> ProvideScopePoints(TemplateAcceptanceContext tacContext)
        {
            var solution = tacContext.Solution;
            var document = tacContext.SelectionRange.Document;

            if (document == null)
            {
                yield break;
            }
            var psiSource = tacContext.SourceFile;

            if (psiSource == null)
            {
                yield break;
            }

            using (ReadLockCookie.Create())
            {
                var psiFiles = solution.GetPsiServices().Files;
                if (!psiFiles.AllDocumentsAreCommitted)
                {
                    psiFiles.CommitAllDocuments();
                }
                int    caretOffset   = tacContext.CaretOffset.Offset;
                string prefix        = LiveTemplatesManager.GetPrefix(document, caretOffset);
                var    documentRange = new DocumentRange(document, caretOffset - prefix.Length);
                if (!documentRange.IsValid())
                {
                    yield break;
                }

                yield return(psiSource.PrimaryPsiLanguage.Name);

                var file = psiSource.GetPsiFile <CSharpLanguage>(documentRange);
                if (file == null || !Equals(file.Language, CSharpLanguage.Instance))
                {
                    yield break;
                }
                var element = file.FindTokenAt(document, caretOffset - prefix.Length);
                if (element == null)
                {
                    yield break;
                }

                yield return("InCSharpFile");

                var treeNode = element;

                if (treeNode.GetContainingNode <IDocCommentNode>(true) != null)
                {
                    yield break;
                }

                if (treeNode is ICSharpCommentNode || treeNode is IPreprocessorDirective)
                {
                    treeNode = treeNode.PrevSibling;
                }
                if (treeNode == null)
                {
                    yield break;
                }

                var context = CSharpReparseContext.FindContext(treeNode);
                if (context == null)
                {
                    yield break;
                }

                if (treeNode.GetContainingNode <IEnumDeclaration>() != null)
                {
                    yield return("InCSharpEnum");
                }

                var containingType = treeNode.GetContainingNode <ICSharpTypeDeclaration>(true);
                if (containingType == null && TestNode <ICSharpNamespaceDeclaration>(context, "namespace N {}", false))
                {
                    yield return("InCSharpTypeAndNamespace");
                }
                else if (TestNode <IMethodDeclaration>(context, "void foo() {}", false))
                {
                    yield return("InCSharpTypeMember");

                    // Extend here:
                    // Already in type member,
                    if (treeNode.GetContainingNode <IInterfaceDeclaration>() != null)
                    {
                        yield return("InCSharpInterface");
                    }
                    if (treeNode.GetContainingNode <IClassDeclaration>() != null)
                    {
                        yield return("InCSharpClass");
                    }
                    if (treeNode.GetContainingNode <IStructDeclaration>() != null)
                    {
                        yield return("InCSharpStruct");
                    }
                }
                else
                {
                    bool acceptsExpression = TestNode <IPostfixOperatorExpression>(context, "a++", true);
                    if (TestNode <IBreakStatement>(context, "break;", false))
                    {
                        yield return("InCSharpStatement");
                    }
                    else if (acceptsExpression)
                    {
                        yield return("InCSharpExpression");
                    }
                    if (!acceptsExpression && TestNode <IQuerySelectClause>(context, "select x", false))
                    {
                        yield return("InCSharpQuery");
                    }
                }
            }
        }
		private DeclaredElementInfo FindDeclaredElement(DocumentRange documentRange) {
			IDocument document = documentRange.Document;
			if (document == null || !documentRange.IsValid())
				return null;
			
			IPsiServices psiServices = _solution.GetPsiServices();
			if (!psiServices.Files.AllDocumentsAreCommitted || psiServices.Caches.HasDirtyFiles)
				return null;

			return document
				.GetPsiSourceFiles(_solution)
				.SelectMany(
					psiSourceFile => psiServices.Files.GetPsiFiles(psiSourceFile, documentRange),
					(psiSourceFile, file) => FindDeclaredElement(documentRange, file))
				.FirstOrDefault(info => info != null && info.DeclaredElement.IsValid());
		}
コード例 #13
0
        /*private bool HandleRightBraceTyped(ITypingContext typingContext)
         * {
         * var textControl = typingContext.TextControl;
         * using (CommandProcessor.UsingCommand("Smart LBRACE"))
         * {
         *  typingContext.CallNext();
         *
         *  // check if typed char is a token
         *  int charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1);
         *  CachingLexer lexer = GetCachingLexer(textControl);
         *  if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos)
         *    return true;
         *
         *  if (NeedAutoinsertCloseBracket(lexer))
         *  {
         *    if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
         *      return true;
         *
         *    AutoinsertRBrace(textControl, lexer);
         *    var position = charPos + 1;
         *    if (position >= 0)
         *      textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible);
         *  }
         * }
         * return true;
         * }*/

        private bool AutoinsertRBrace(ITextControl textControl, CachingLexer lexer)
        {
            int charPos   = lexer.TokenEnd;
            int lBracePos = charPos - 1;

            if (lexer.TokenType != PsiTokenType.LBRACE)
            {
                return(false);
            }

            if (!NeedAutoinsertCloseBracket(lexer))
            {
                return(false);
            }

            // insert RBRACE next to the LBRACE
            IDocument document = textControl.Document;
            int       position = lBracePos;

            if (position < 0)
            {
                return(false);
            }

            document.InsertText(position + 1, "}");

            // Commit PSI
            IFile file = CommitPsi(textControl);

            if (file == null)
            {
                return(false);
            }

            TreeTextRange treeLBraceRange = file.Translate(new DocumentRange(document, new TextRange(lBracePos + 1)));

            if (!treeLBraceRange.IsValid())
            {
                return(false);
            }

            var rBraceToken = file.FindTokenAt(treeLBraceRange.StartOffset) as ITokenNode;

            if (rBraceToken == null || rBraceToken.GetTokenType() != PsiTokenType.RBRACE)
            {
                return(false);
            }
            TreeOffset positionForRBrace = rBraceToken.GetTreeTextRange().EndOffset;


            // move RBRACE to another position, if necessary
            DocumentRange documentRangeForRBrace = file.GetDocumentRange(positionForRBrace);

            if (documentRangeForRBrace.IsValid() && documentRangeForRBrace.TextRange.StartOffset != lBracePos + 1)
            {
                int pos = documentRangeForRBrace.TextRange.StartOffset;
                if (pos >= 0)
                {
                    document.InsertText(pos, "}");
                    document.DeleteText(new TextRange(lBracePos + 1, lBracePos + 2));
                }
            }

            return(true);
        }
コード例 #14
0
        public PostfixTemplateAcceptanceContext([NotNull] ITreeNode reference,
      [NotNull] ICSharpExpression expression, DocumentRange replaceRange,
      bool forceMode, [NotNull] PostfixExecutionContext context)
        {
            myReparsedContext = context.ReparsedContext;
              myMostInnerExpression = expression;
              PostfixReferenceNode = reference;
              ForceMode = forceMode;
              PsiModule = context.PsiModule;
              LookupItemsOwner = context.LookupItemsOwner;
              MostInnerReplaceRange = replaceRange;

              if (!replaceRange.IsValid())
              {
            var referenceExpression = reference as IReferenceExpression;
            if (referenceExpression != null)
            {
              MostInnerReplaceRange =
            ToDocumentRange(referenceExpression.QualifierExpression.NotNull()).SetEndTo(
              ToDocumentRange(referenceExpression.Delimiter.NotNull()).TextRange.EndOffset);
            }

            var referenceName = reference as IReferenceName;
            if (referenceName != null)
            {
              MostInnerReplaceRange =
            ToDocumentRange(referenceName.Qualifier).SetEndTo(
              ToDocumentRange(referenceName.Delimiter).TextRange.EndOffset);
            }
              }

              // build expression contexts
              var expressionContexts = new List<PrefixExpressionContext>();
              var endOffset = Math.Max(
            MostInnerReplaceRange.TextRange.EndOffset,
            ToDocumentRange(reference).TextRange.EndOffset);

              for (ITreeNode node = expression; node != null; node = node.Parent)
              {
            if (node is ICSharpStatement) break;

            var expr = node as ICSharpExpression;
            if (expr == null || expr == reference) continue;

            var exprRange = myReparsedContext.ToDocumentRange(expr);
            if (!exprRange.IsValid())
              break; // stop when out of generated
            if (exprRange.TextRange.EndOffset > endOffset)
              break; // stop when 'a.var + b'

            // skip relational expressions like this: 'List<int.{here}>'
            if (CommonUtils.IsRelationalExpressionWithTypeOperand(expr)) continue;

            var expressionContext = new PrefixExpressionContext(this, expr);
            if (expressionContext.ReferencedElement is ITypeElement)
            {
              // skip types that are parts of 'List<T.>'-like expressions
              if (!CommonUtils.CanTypeBecameExpression(expression)) continue;
            }

            expressionContexts.Add(expressionContext);
            if (expressionContext.CanBeStatement) break;
              }

              Expressions = (expressionContexts.Count == 0)
            ? EmptyList<PrefixExpressionContext>.InstanceList
            : expressionContexts.AsReadOnly();
        }
コード例 #15
0
        private bool ReformatForSmartEnter(string dummyText, ITextControl textControl, IFile file, TreeTextRange reparseTreeOffset, TreeOffset lBraceTreePos, TreeOffset rBraceTreePos, bool insertEnterAfter = false)
        {
            // insert dummy text and reformat
            TreeOffset newCaretPos;
            var        codeFormatter = GetCodeFormatter(file);

            using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(PsiServices, "Typing assist"))
            {
                string newLine      = Environment.NewLine;
                string textToInsert = newLine + dummyText;
                if (insertEnterAfter)
                {
                    textToInsert = textToInsert + newLine;
                }
                file = file.ReParse(reparseTreeOffset, textToInsert);
                if (file == null)
                {
                    return(false);
                }

                ITreeNode lBraceNode = file.FindTokenAt(lBraceTreePos);
                if (lBraceNode == null)
                {
                    return(false);
                }

                var dummyNode = file.FindTokenAt(reparseTreeOffset.StartOffset + newLine.Length) as ITokenNode;

                var languageService = file.Language.LanguageService();
                if (languageService == null)
                {
                    return(false);
                }

                while (dummyNode != null && languageService.IsFilteredNode(dummyNode))
                {
                    dummyNode = dummyNode.GetNextToken();
                }

                if (dummyNode == null)
                {
                    return(false);
                }

                var rBraceNode = file.FindTokenAt(rBraceTreePos + newLine.Length + dummyText.Length + (insertEnterAfter ? newLine.Length : 0));

                var boundSettingsStore = SettingsStore.BindToContextTransient(textControl.ToContextRange());

                codeFormatter.Format(lBraceNode, CodeFormatProfile.DEFAULT, null, boundSettingsStore);
                codeFormatter.Format(
                    rBraceNode.FindFormattingRangeToLeft(),
                    rBraceNode,
                    CodeFormatProfile.DEFAULT,
                    null,
                    boundSettingsStore);
                codeFormatter.Format(lBraceNode.Parent, CodeFormatProfile.INDENT, null);

                newCaretPos = dummyNode.GetTreeStartOffset();
                file        = file.ReParse(new TreeTextRange(newCaretPos, newCaretPos + dummyText.Length), "");
                Assertion.Assert(file != null, "file != null");
            }

            // dposition cursor
            DocumentRange newCaretPosition = file.GetDocumentRange(newCaretPos);

            if (newCaretPosition.IsValid())
            {
                textControl.Caret.MoveTo(newCaretPosition.TextRange.StartOffset, CaretVisualPlacement.DontScrollIfVisible);
            }

            return(true);
        }
コード例 #16
0
        DocumentRange[] IMemberNavigationAspect.GetNavigationRanges()
        {
            DocumentRange navigationRange = NavigationRange;

            return(navigationRange.IsValid() ? new[] { navigationRange } : EmptyArray <DocumentRange> .Instance);
        }
コード例 #17
0
 public bool IsValid()
 {
     return(_range.IsValid());
 }
コード例 #18
0
 public bool IsValid()
 {
     return(_documentRange.IsValid());
 }
コード例 #19
0
 public override bool IsAvailable(IUserDataHolder cache)
 {
     return(_range.IsValid());
 }
コード例 #20
0
		public TreeTextRange Translate(DocumentRange documentRange) {
			if (!documentRange.IsValid()
			|| _sourceFile == null
			|| !_sourceFile.IsValid())
				return TreeTextRange.InvalidRange;

			if (documentRange.Document != _sourceFile.Document) {
				foreach (IT4Include include in _includes) {
					if (include.DocumentRangeTranslator != null) {
						TreeTextRange textRange = include.DocumentRangeTranslator.Translate(documentRange);
						if (textRange.IsValid())
							return textRange;
					}
				}
				return TreeTextRange.InvalidRange;
			}

			TextRange range = documentRange.TextRange;
			TreeOffset rootStartOffset = _root.GetTreeStartOffset();

			// no includes, tree and document are matching
			if (_includes.Count == 0)
				return new TreeTextRange(rootStartOffset + range.StartOffset, rootStartOffset + range.EndOffset);

			TreeOffset startOffset = Translate(range.StartOffset);
			if (!startOffset.IsValid())
				return TreeTextRange.InvalidRange;

			TreeOffset endOffset = Translate(range.EndOffset);
			if (!endOffset.IsValid())
				return TreeTextRange.InvalidRange;
			
			return new TreeTextRange(startOffset, endOffset);
		}
コード例 #21
0
        public static bool IsNotEmptyNormalized(this DocumentRange range)
        {
            var textRange = range.TextRange;

            return(range.IsValid() && (textRange.StartOffset < textRange.EndOffset));
        }