/// <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); } } }
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)); }
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)); }
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)); }
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); }
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); }