Example #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;
        }
        public DocumentRange Translate(TreeTextRange range)
        {
            if (!range.IsValid())
                return DocumentRange.InvalidRange;
            if (_sourceFile == null || !_sourceFile.IsValid())
                return DocumentRange.InvalidRange;

            IncludeWithOffset atStart = FindIncludeAtOffset(range.StartOffset, true);
            IncludeWithOffset atEnd = FindIncludeAtOffset(range.EndOffset, atStart.Include == null);

            // two different parts are overlapping
            IT4Include include = atStart.Include;
            if (include != atEnd.Include)
                return DocumentRange.InvalidRange;

            // recursive includes
            if (include != null) {
                if (include.DocumentRangeTranslator != null)
                    return include.DocumentRangeTranslator.Translate(range);
                return DocumentRange.InvalidRange;
            }

            int rootStartOffset = _root.GetTreeStartOffset().Offset;
            return new DocumentRange(_sourceFile.Document, new TextRange(atStart.Offset - rootStartOffset, atEnd.Offset - rootStartOffset));
        }
        private static void ProcessT4FeatureBlock(
            [NotNull] IT4FeatureBlock featureBlock,
            [NotNull] CodeStructureElement parentElement,
            [NotNull] ICSharpFile cSharpFile,
            [NotNull] ISecondaryRangeTranslator secondaryRangeTranslator,
            [NotNull] CSharpCodeStructureProcessingState state
            )
        {
            TreeTextRange t4Range     = featureBlock.Code.GetTreeTextRange();
            TreeTextRange cSharpRange = secondaryRangeTranslator.OriginalToGenerated(t4Range);

            if (!cSharpRange.IsValid())
            {
                return;
            }

            TreeOffset cSharpStart = cSharpRange.StartOffset;
            TreeOffset cSharpEnd   = cSharpRange.EndOffset;

            ITreeNode containingNode = cSharpFile.FindNodeAt(cSharpRange);

            if (containingNode == null)
            {
                return;
            }

            for (ITreeNode node = containingNode.FirstChild; node != null; node = node.NextSibling)
            {
                TreeOffset nodeStart = node.GetTreeStartOffset();
                if (nodeStart >= cSharpStart && nodeStart < cSharpEnd)
                {
                    ProcessCSharpNode(node, parentElement, state);
                }
            }
        }
Example #4
0
        private static DeclaredElementInfo FindDeclaredElement(DocumentRange range, [NotNull] IFile file)
        {
            if (!file.IsValid())
            {
                return(null);
            }

            TreeTextRange treeTextRange = file.Translate(range);

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

            IReference[] references = file.FindReferencesAt(treeTextRange);
            if (references.Length > 0)
            {
                return(GetBestReference(references, file));
            }

            // FindNodeAt seems to return the previous node on single-char literals (eg '0'). FindNodesAt is fine.
            var node = file.FindNodesAt <ITreeNode>(treeTextRange).FirstOrDefault();

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

            return(FindDeclaration(node, file)
                   ?? FindConstant(node, file)
                   ?? FindSpecialElement(node, file));
        }
Example #5
0
        public DocumentRange Translate(TreeTextRange range)
        {
            if (!range.IsValid() || !_sourceFile.IsValid())
            {
                return(DocumentRange.InvalidRange);
            }

            IncludeWithOffset atStart = FindIncludeAtOffset(range.StartOffset, true);
            IncludeWithOffset atEnd   = FindIncludeAtOffset(range.EndOffset, atStart.Include == null);

            // two different parts are overlapping
            IT4Include include = atStart.Include;

            if (include != atEnd.Include)
            {
                return(DocumentRange.InvalidRange);
            }

            // recursive includes
            if (include != null)
            {
                if (include.DocumentRangeTranslator != null)
                {
                    return(include.DocumentRangeTranslator.Translate(range));
                }
                return(DocumentRange.InvalidRange);
            }

            int rootStartOffset = _root.GetTreeStartOffset().Offset;

            return(new DocumentRange(_sourceFile.Document, new TextRange(atStart.Offset - rootStartOffset, atEnd.Offset - rootStartOffset)));
        }
        public DocumentRange Translate(TreeTextRange range)
        {
            if (!range.IsValid() || !SourceFile.IsValid())
            {
                return(DocumentRange.InvalidRange);
            }
            var sector = FindSectorAtRange(range);

            if (!sector.IsValid())
            {
                return(DocumentRange.InvalidRange);
            }

            // Let the included file handle the request
            if (sector.Include != null)
            {
                return(sector.Include.DocumentRangeTranslator.Translate(range));
            }

            // The range is in the current document

            // The includes that appear before do not contribute to document offset
            int extraIncludeOffset = sector.PrecedingIncludeLength;

            // Neither do the other includes in the tree
            // (the ones that are included before the current file)
            int extraRootOffset = FileLikeNode.GetTreeStartOffset().Offset;

            var start = range.StartOffset - extraIncludeOffset - extraRootOffset;
            var end   = range.EndOffset - extraIncludeOffset - extraRootOffset;
            var resultingTextRange = new TextRange(start.Offset, end.Offset);

            resultingTextRange.AssertValid();
            return(new DocumentRange(SourceFile.Document, resultingTextRange));
        }
Example #7
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));
        }
Example #8
0
        private static DocumentRange GetDocumentRange([NotNull] IFile file, TreeTextRange range)
        {
            // The whole purpose of this class is to remove the following line:
            // Assertion.Assert(file.IsValid(), "file.IsValid()");

            if (!range.IsValid())
            {
                return(DocumentRange.InvalidRange);
            }

            var tmpFile    = (IFileImpl)file;
            var translator = tmpFile.SecondaryRangeTranslator;
            var tmpRange   = range;

            while (translator != null)
            {
                tmpRange = translator.GeneratedToOriginal(tmpRange);
                if (!tmpRange.IsValid())
                {
                    return(DocumentRange.InvalidRange);
                }

                tmpFile = (IFileImpl)translator.OriginalFile;
                if (tmpFile == null)
                {
                    return(DocumentRange.InvalidRange);
                }

                translator = tmpFile.SecondaryRangeTranslator;
            }

            var parsedDocumentRange = tmpFile.DocumentRangeTranslator.Translate(tmpRange);

            if (!parsedDocumentRange.IsValid())
            {
                return(DocumentRange.InvalidRange);
            }

            return(parsedDocumentRange);
        }
Example #9
0
        private static DeclaredElementInstance FindElement([NotNull] IFile file, DocumentRange range)
        {
            TreeTextRange treeTextRange = file.Translate(range);

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

            // First finds a reference.
            IReference[] references = file.FindReferencesAt(treeTextRange);
            if (references.Length > 0)
            {
                return(GetBestReference(references));
            }

            // Or a declaration.
            ITreeNode nodeAt = file.FindNodeAt(treeTextRange);

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

            var containingNode = nodeAt.GetContainingNode <IDeclaration>(true);

            if (containingNode != null && containingNode.GetNameDocumentRange() == range)
            {
                IDeclaredElement declaredElement = containingNode.DeclaredElement;
                if (declaredElement != null)
                {
                    return(new DeclaredElementInstance(declaredElement, EmptySubstitution.INSTANCE));
                }
            }

            return(null);
        }
        /*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);
        }