下面列出了com.intellij.psi.search.LocalSearchScope#com.intellij.lang.injection.InjectedLanguageManager 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@NotNull
private PsiElement findInjectedBashReference(String fileName, String lookupText) {
PsiElement javaLiteral = configurePsiAtCaret(fileName);
Assert.assertTrue(javaLiteral instanceof PsiLanguageInjectionHost);
//inject bash into the literal
InjectLanguageAction.invokeImpl(getProject(), myFixture.getEditor(), javaLiteral.getContainingFile(), Injectable.fromLanguage(BashFileType.BASH_LANGUAGE));
String fileContent = javaLiteral.getContainingFile().getText();
PsiElement bashPsiLeaf = InjectedLanguageManager.getInstance(getProject()).findInjectedElementAt(myFixture.getFile(), fileContent.indexOf(lookupText) + 1);
Assert.assertNotNull(bashPsiLeaf);
PsiElement reference = PsiTreeUtil.findFirstParent(bashPsiLeaf, psiElement -> psiElement.getReference() != null);
Assert.assertNotNull(reference);
return reference;
}
/**
* Resolve PHP language injection in Blade
*
* @see BladeVariableTypeProvider#getHostPhpFileForInjectedIfExists
*/
@Nullable
private static BladeFileImpl getHostBladeFileForInjectionIfExists(PsiElement element) {
PsiFile file = element.getContainingFile();
InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(element.getProject());
if (injectedLanguageManager.isInjectedFragment(file)) {
PsiLanguageInjectionHost host = injectedLanguageManager.getInjectionHost(element);
if (host instanceof BladePsiLanguageInjectionHost && host.isValidHost()) {
PsiFile bladeFile = host.getContainingFile();
if (bladeFile instanceof BladeFileImpl) {
return (BladeFileImpl) bladeFile;
}
}
}
return null;
}
@Nonnull
private static Pair<PsiElement, CharTable> doFindWhiteSpaceNode(@Nonnull PsiFile file, int offset) {
ASTNode astNode = SourceTreeToPsiMap.psiElementToTree(file);
if (!(astNode instanceof FileElement)) {
return new Pair<>(null, null);
}
PsiElement elementAt = InjectedLanguageManager.getInstance(file.getProject()).findInjectedElementAt(file, offset);
final CharTable charTable = ((FileElement)astNode).getCharTable();
if (elementAt == null) {
elementAt = findElementInTreeWithFormatterEnabled(file, offset);
}
if (elementAt == null) {
return new Pair<>(null, charTable);
}
ASTNode node = elementAt.getNode();
if (node == null || node.getElementType() != TokenType.WHITE_SPACE) {
return new Pair<>(null, charTable);
}
return Pair.create(elementAt, charTable);
}
/**
* Crazy shit to find component directive for a given slot
* Blade Plugin do not provide a nested tree!
*
* "@component('layouts.app')"
* "@slot('title')"
* Home Page
* "@endslot"
* "@endcomponent"
*/
@Nullable
public static String findComponentForSlotScope(@NotNull PsiElement psiDirectiveParameter) {
PsiElement bladeHost;
if(psiDirectiveParameter.getNode().getElementType() == BladeTokenTypes.DIRECTIVE_PARAMETER_CONTENT) {
bladeHost = psiDirectiveParameter.getParent();
} else {
bladeHost = InjectedLanguageManager
.getInstance(psiDirectiveParameter.getProject())
.getInjectionHost(psiDirectiveParameter);
}
if(!(bladeHost instanceof BladePsiDirectiveParameter)) {
return null;
}
return findComponentForSlotScope((BladePsiDirectiveParameter) bladeHost);
}
@Override
public int getLineNumber() {
if (myLineNumber == -1) {
PsiElement psiElement = getPsiElement();
if (psiElement == null) return -1;
if (!psiElement.isValid()) return -1;
LOG.assertTrue(psiElement.isPhysical());
InjectedLanguageManager manager = InjectedLanguageManager.getInstance(psiElement.getProject());
PsiFile containingFile = manager.getTopLevelFile(psiElement);
Document document = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(containingFile);
if (document == null) return -1;
TextRange textRange = getTextRange();
if (textRange == null) return -1;
textRange = manager.injectedToHost(psiElement, textRange);
final int startOffset = textRange.getStartOffset();
final int textLength = document.getTextLength();
LOG.assertTrue(startOffset <= textLength, getDescriptionTemplate() + " at " + startOffset + ", " + textLength);
myLineNumber = document.getLineNumber(startOffset) + 1;
}
return myLineNumber;
}
public static String getUnescapedText(@Nonnull PsiFile file, @Nullable final PsiElement startElement, @Nullable final PsiElement endElement) {
final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
if (manager.getInjectionHost(file) == null) {
return file.getText().substring(startElement == null ? 0 : startElement.getTextRange().getStartOffset(), endElement == null ? file.getTextLength() : endElement.getTextRange().getStartOffset());
}
final StringBuilder sb = new StringBuilder();
file.accept(new PsiRecursiveElementWalkingVisitor() {
Boolean myState = startElement == null ? Boolean.TRUE : null;
@Override
public void visitElement(PsiElement element) {
if (element == startElement) myState = Boolean.TRUE;
if (element == endElement) myState = Boolean.FALSE;
if (Boolean.FALSE == myState) return;
if (Boolean.TRUE == myState && element.getFirstChild() == null) {
sb.append(getUnescapedLeafText(element, false));
}
else {
super.visitElement(element);
}
}
});
return sb.toString();
}
@Override
@Nullable
public ProblemDescriptor[] checkFile(@Nonnull PsiFile file, @Nonnull InspectionManager manager, boolean isOnTheFly) {
if (InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) return null;
if (!file.isPhysical()) return null;
FileViewProvider viewProvider = file.getViewProvider();
if (viewProvider.getBaseLanguage() != file.getLanguage()) return null;
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) return null;
if (!virtualFile.isInLocalFileSystem()) return null;
CharSequence text = viewProvider.getContents();
Charset charset = LoadTextUtil.extractCharsetFromFileContent(file.getProject(), virtualFile, text);
// no sense in checking transparently decoded file: all characters there are already safely encoded
if (charset instanceof Native2AsciiCharset) return null;
List<ProblemDescriptor> descriptors = new SmartList<ProblemDescriptor>();
boolean ok = checkFileLoadedInWrongEncoding(file, manager, isOnTheFly, virtualFile, charset, descriptors);
if (ok) {
checkIfCharactersWillBeLostAfterSave(file, manager, isOnTheFly, text, charset, descriptors);
}
return descriptors.toArray(new ProblemDescriptor[descriptors.size()]);
}
static OffsetsInFile toInjectedIfAny(PsiFile originalFile, OffsetsInFile hostCopyOffsets) {
CompletionAssertions.assertHostInfo(hostCopyOffsets.getFile(), hostCopyOffsets.getOffsets());
int hostStartOffset = hostCopyOffsets.getOffsets().getOffset(CompletionInitializationContext.START_OFFSET);
OffsetsInFile translatedOffsets = hostCopyOffsets.toInjectedIfAny(hostStartOffset);
if (translatedOffsets != hostCopyOffsets) {
PsiFile injected = translatedOffsets.getFile();
if (originalFile != injected && injected instanceof PsiFileImpl && InjectedLanguageManager.getInstance(originalFile.getProject()).isInjectedFragment(originalFile)) {
((PsiFileImpl)injected).setOriginalFile(originalFile);
}
DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injected);
CompletionAssertions.assertInjectedOffsets(hostStartOffset, injected, documentWindow);
if (injected.getTextRange().contains(translatedOffsets.getOffsets().getOffset(CompletionInitializationContext.START_OFFSET))) {
return translatedOffsets;
}
}
return hostCopyOffsets;
}
@Nonnull
private static PsiFile getInjectedFileIfAny(@Nonnull final Editor editor,
@Nonnull final Project project,
int offset,
@Nonnull PsiFile psiFile,
@Nonnull final Alarm alarm) {
Document document = editor.getDocument();
// when document is committed, try to highlight braces in injected lang - it's fast
if (PsiDocumentManager.getInstance(project).isCommitted(document)) {
final PsiElement injectedElement = InjectedLanguageManager.getInstance(psiFile.getProject()).findInjectedElementAt(psiFile, offset);
if (injectedElement != null /*&& !(injectedElement instanceof PsiWhiteSpace)*/) {
final PsiFile injected = injectedElement.getContainingFile();
if (injected != null) {
return injected;
}
}
}
else {
PsiDocumentManager.getInstance(project).performForCommittedDocument(document, () -> {
if (!project.isDisposed() && !editor.isDisposed()) {
BraceHighlighter.updateBraces(editor, alarm);
}
});
}
return psiFile;
}
/**
* Finds injected language in expression
*
* @param expression where to find
* @param classToFind class that represents language we look for
* @param <T> class that represents language we look for
* @return instance of class that represents language we look for or null of not found
*/
@Nullable
@SuppressWarnings("unchecked") // We check types dynamically (using isAssignableFrom)
public static <T extends PsiFileBase> T findInjectedFile(@Nonnull final PsiElement expression, @Nonnull final Class<T> classToFind) {
final List<Pair<PsiElement, TextRange>> files = InjectedLanguageManager.getInstance(expression.getProject()).getInjectedPsiFiles(expression);
if (files == null) {
return null;
}
for (final Pair<PsiElement, TextRange> fileInfo : files) {
final PsiElement injectedFile = fileInfo.first;
if (classToFind.isAssignableFrom(injectedFile.getClass())) {
return (T)injectedFile;
}
}
return null;
}
@Override
public void addOccurrenceHighlights(@Nonnull Editor editor,
@Nonnull PsiElement[] elements,
@Nonnull TextAttributes attributes,
boolean hideByTextChange,
Collection<RangeHighlighter> outHighlighters) {
if (elements.length == 0) return;
int flags = HIDE_BY_ESCAPE;
if (hideByTextChange) {
flags |= HIDE_BY_TEXT_CHANGE;
}
Color scrollmarkColor = getScrollMarkColor(attributes);
if (editor instanceof EditorWindow) {
editor = ((EditorWindow)editor).getDelegate();
}
for (PsiElement element : elements) {
TextRange range = element.getTextRange();
range = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, range);
addOccurrenceHighlight(editor, range.getStartOffset(), range.getEndOffset(), attributes, flags, outHighlighters, scrollmarkColor);
}
}
/**
* @deprecated use {@link InjectedLanguageManager#enumerateEx(PsiElement, PsiFile, boolean, PsiLanguageInjectionHost.InjectedPsiVisitor)} instead
*/
@Deprecated
public static boolean enumerate(@Nonnull PsiElement host, @Nonnull PsiFile containingFile, boolean probeUp, @Nonnull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
//do not inject into nonphysical files except during completion
if (!containingFile.isPhysical() && containingFile.getOriginalFile() == containingFile) {
final PsiElement context = InjectedLanguageManager.getInstance(containingFile.getProject()).getInjectionHost(containingFile);
if (context == null) return false;
final PsiFile file = context.getContainingFile();
if (file == null || !file.isPhysical() && file.getOriginalFile() == file) return false;
}
if (containingFile.getViewProvider() instanceof InjectedFileViewProvider) return false; // no injection inside injection
PsiElement inTree = loadTree(host, containingFile);
if (inTree != host) {
host = inTree;
containingFile = host.getContainingFile();
}
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(containingFile.getProject());
Document document = documentManager.getDocument(containingFile);
if (document == null || documentManager.isCommitted(document)) {
probeElementsUp(host, containingFile, probeUp, visitor);
}
return true;
}
@Override
public boolean canClosePopup() {
if (myAdditionalPanels.isEmpty()) {
return true;
}
if (myAdditionalPanels.stream().allMatch(p -> p.canClose())) {
PsiFile psiFile = getPsiFile();
if (myAdditionalPanels.stream().filter(p -> p.isModified()).peek(TrafficLightRenderer::applyPanel).count() > 0) {
if (psiFile != null) {
InjectedLanguageManager.getInstance(getProject()).dropFileCaches(psiFile);
}
myDaemonCodeAnalyzer.restart();
}
return true;
}
return false;
}
@Nonnull
public static Editor injectedEditorIfCharTypedIsSignificant(final int charTyped, @Nonnull Editor editor, @Nonnull PsiFile oldFile) {
int offset = editor.getCaretModel().getOffset();
// even for uncommitted document try to retrieve injected fragment that has been there recently
// we are assuming here that when user is (even furiously) typing, injected language would not change
// and thus we can use its lexer to insert closing braces etc
List<DocumentWindow> injected = InjectedLanguageManager.getInstance(oldFile.getProject()).getCachedInjectedDocumentsInRange(oldFile, ProperTextRange.create(offset, offset));
for (DocumentWindow documentWindow : injected) {
if (documentWindow.isValid() && documentWindow.containsRange(offset, offset)) {
PsiFile injectedFile = PsiDocumentManager.getInstance(oldFile.getProject()).getPsiFile(documentWindow);
if (injectedFile != null) {
Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
// IDEA-52375/WEB-9105 fix: last quote in editable fragment should be handled by outer language quote handler
TextRange hostRange = documentWindow.getHostRange(offset);
CharSequence sequence = editor.getDocument().getCharsSequence();
if (sequence.length() > offset && charTyped != Character.codePointAt(sequence, offset) || hostRange != null && hostRange.contains(offset)) {
return injectedEditor;
}
}
}
}
return editor;
}
private static int insertLookupInDocumentWindowIfNeeded(Project project, Editor editor, int caretOffset, int prefix, String lookupString) {
DocumentWindow document = getInjectedDocument(project, editor, caretOffset);
if (document == null) return insertLookupInDocument(caretOffset, editor.getDocument(), prefix, lookupString);
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
int offset = document.hostToInjected(caretOffset);
int lookupStart = Math.min(offset, Math.max(offset - prefix, 0));
int diff = -1;
if (file != null) {
List<TextRange> ranges = InjectedLanguageManager.getInstance(project).intersectWithAllEditableFragments(file, TextRange.create(lookupStart, offset));
if (!ranges.isEmpty()) {
diff = ranges.get(0).getStartOffset() - lookupStart;
if (ranges.size() == 1 && diff == 0) diff = -1;
}
}
if (diff == -1) return insertLookupInDocument(caretOffset, editor.getDocument(), prefix, lookupString);
return document.injectedToHost(insertLookupInDocument(offset, document, prefix - diff, diff == 0 ? lookupString : lookupString.substring(diff)));
}
@Override
public void caretPositionChanged(CaretEvent e) {
if (!available() || myEditor.getSelectionModel().hasSelection()) return;
final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
final PsiElement rootPsiElement = treeStructure.getRootPsiElement();
if (rootPsiElement == null) return;
final PsiElement rootElement = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
int baseOffset = rootPsiElement.getTextRange().getStartOffset();
final int offset = myEditor.getCaretModel().getOffset() + baseOffset;
final PsiElement element = InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), offset);
if (element != null && myBlockTreeBuilder != null) {
TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
selectBlockNode(findBlockNode(rangeInHostFile, true));
}
myPsiTreeBuilder.select(element);
}
@Override
public Result preprocessEnter(
PsiFile file,
Editor editor,
Ref<Integer> caretOffset,
Ref<Integer> caretAdvance,
DataContext dataContext,
EditorActionHandler originalHandler) {
int offset = caretOffset.get();
if (editor instanceof EditorWindow) {
file = InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file);
editor = InjectedLanguageUtil.getTopLevelEditor(editor);
offset = editor.getCaretModel().getOffset();
}
if (!isApplicable(file, dataContext) || !insertIndent(file, offset)) {
return Result.Continue;
}
int indent = SectionParser.INDENT;
editor.getCaretModel().moveToOffset(offset);
Document doc = editor.getDocument();
PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc);
originalHandler.execute(editor, editor.getCaretModel().getCurrentCaret(), dataContext);
LogicalPosition position = editor.getCaretModel().getLogicalPosition();
if (position.column < indent) {
String spaces = StringUtil.repeatSymbol(' ', indent - position.column);
doc.insertString(editor.getCaretModel().getOffset(), spaces);
}
editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(position.line, indent));
return Result.Stop;
}
public GraphQLPsiSearchHelper(@NotNull final Project project) {
myProject = project;
mySettings = GraphQLSettings.getSettings(project);
psiManager = PsiManager.getInstance(myProject);
graphQLInjectionSearchHelper = ServiceManager.getService(GraphQLInjectionSearchHelper.class);
injectedLanguageManager = InjectedLanguageManager.getInstance(myProject);
graphQLConfigManager = GraphQLConfigManager.getService(myProject);
pluginDescriptor = PluginManager.getPlugin(PluginId.getId("com.intellij.lang.jsgraphql"));
final PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(myProject);
defaultProjectFile = (GraphQLFile) psiFileFactory.createFileFromText("Default schema file", GraphQLLanguage.INSTANCE, "");
GlobalSearchScope defaultProjectFileScope = GlobalSearchScope.fileScope(defaultProjectFile);
GlobalSearchScope builtInSchemaScope = GlobalSearchScope.fileScope(project, getBuiltInSchema().getVirtualFile());
GlobalSearchScope builtInRelaySchemaScope = GlobalSearchScope.fileScope(project, getRelayModernDirectivesSchema().getVirtualFile());
allBuiltInSchemaScopes = builtInSchemaScope
.union(new ConditionalGlobalSearchScope(builtInRelaySchemaScope, mySettings::isEnableRelayModernFrameworkSupport))
.union(defaultProjectFileScope)
;
final FileType[] searchScopeFileTypes = GraphQLFindUsagesUtil.getService().getIncludedFileTypes().toArray(FileType.EMPTY_ARRAY);
searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.projectScope(myProject), searchScopeFileTypes).union(allBuiltInSchemaScopes);
project.getMessageBus().connect().subscribe(PsiManagerImpl.ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener.Adapter() {
@Override
public void beforePsiChanged(boolean isPhysical) {
// clear the cache on each PSI change
fileNameToSchemaScope.clear();
}
});
}
/**
* Uses the {@link GraphQLInjectionIndex} to process injected GraphQL PsiFiles
*
* @param scopedElement the starting point of the enumeration settings the scopedElement of the processing
* @param schemaScope the search scope to use for limiting the schema definitions
* @param consumer a consumer that will be invoked for each injected GraphQL PsiFile
*/
public void processInjectedGraphQLPsiFiles(PsiElement scopedElement, GlobalSearchScope schemaScope, Consumer<PsiFile> consumer) {
try {
final PsiManager psiManager = PsiManager.getInstance(scopedElement.getProject());
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(scopedElement.getProject());
FileBasedIndex.getInstance().getFilesWithKey(GraphQLInjectionIndex.NAME, Collections.singleton(GraphQLInjectionIndex.DATA_KEY), virtualFile -> {
final PsiFile fileWithInjection = psiManager.findFile(virtualFile);
if (fileWithInjection != null) {
fileWithInjection.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (GraphQLLanguageInjectionUtil.isJSGraphQLLanguageInjectionTarget(element)) {
injectedLanguageManager.enumerate(element, (injectedPsi, places) -> {
consumer.accept(injectedPsi);
});
} else {
// visit deeper until injection found
super.visitElement(element);
}
}
});
}
return true;
}, schemaScope);
} catch (IndexNotReadyException e) {
// can't search yet (e.g. during project startup)
}
}
/**
* Returns the start text offset of the element in the toplevel file, i.e the PsiFile which containing the real document. If an element
* is injected then the outer file is returned.
*
* @param element The element to work on
* @return The start text offset in the physical PsiFile, injected virtual PsiFiles are not used for text offset calculation
*/
public static int getFileTextOffset(@NotNull PsiElement element) {
int offset = element.getTextOffset();
if (isInjectedElement(element)) {
//fixme languageManager is probably expensive
InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(element.getProject());
PsiLanguageInjectionHost injectionHost = languageManager.getInjectionHost(element);
if (injectionHost != null) {
offset += injectionHost.getTextOffset();
}
}
return offset;
}
public static boolean walkInjection(PsiElement host, @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place, boolean walkOn) {
//fixme does this work on the escaped or unescpaed text?
InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(host.getProject());
List<Pair<PsiElement, TextRange>> injectedPsiFiles = injectedLanguageManager.getInjectedPsiFiles(host);
if (injectedPsiFiles != null) {
for (Pair<PsiElement, TextRange> psi_range : injectedPsiFiles) {
//fixme check lastParent ?
walkOn &= psi_range.first.processDeclarations(processor, state, lastParent, place);
}
}
return walkOn;
}
@NotNull
@Override
public Collection<LookupElement> getLookupElements() {
final List<LookupElement> lookupElementList = new ArrayList<>();
PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(getProject()).getInjectionHost(getElement());
if (!(host instanceof BladePsiLanguageInjectionHost)) {
return Collections.emptyList();
}
final Set<String> uniqueSet = new HashSet<>();
BladeTemplateUtil.visitUpPath(host.getContainingFile(), 10, parameter -> {
if (!uniqueSet.contains(parameter.getContent())) {
uniqueSet.add(parameter.getContent());
LookupElementBuilder lookupElement = LookupElementBuilder.create(parameter.getContent()).withIcon(LaravelIcons.LARAVEL);
for(String templateName: BladeTemplateUtil.resolveTemplateName(parameter.getPsiElement().getContainingFile())) {
lookupElement = lookupElement.withTypeText(templateName, true);
if(parameter.getElementType() == BladeTokenTypes.SECTION_DIRECTIVE) {
lookupElement = lookupElement.withTailText("(section)", true);
} else if(parameter.getElementType() == BladeTokenTypes.YIELD_DIRECTIVE) {
lookupElement = lookupElement.withTailText("(yield)", true);
} else if(parameter.getElementType() == BladeTokenTypes.STACK_DIRECTIVE) {
lookupElement = lookupElement.withTailText("(stack)", true);
}
lookupElementList.add(lookupElement);
}
}
}, this.visitElements);
return lookupElementList;
}
@Override
public boolean showHint(@NotNull Editor editor) {
myEditor = editor;
TextRange range = InjectedLanguageManager.getInstance(myType.getProject()).injectedToHost(myType, myType.getTextRange());
HintManager.getInstance().showQuestionHint(editor, getText(), range.getStartOffset(), range.getEndOffset(), this);
return true;
}
private boolean checkRangeContainsOffset(int offset, final TextRange textRange, PsiElement element) {
int startOffset = element.getTextRange().getStartOffset();
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(myProject);
final PsiLanguageInjectionHost injectionHost = injectedLanguageManager.getInjectionHost(element);
if (injectionHost != null) {
final PsiElement nameIdentifier = getNameIdentifier();
final PsiLanguageInjectionHost initialInjectedHost = nameIdentifier != null ? injectedLanguageManager.getInjectionHost(nameIdentifier) : null;
if (initialInjectedHost != null && initialInjectedHost != injectionHost) {
return false;
}
}
return textRange.shiftRight(startOffset).containsOffset(offset);
}
private static void doProcessFile(@Nonnull PsiElementVisitor visitor, @Nonnull PsiManager psiManager, @Nonnull VirtualFile vFile,
boolean clearResolveCache) {
if (!vFile.isValid()) return;
PsiFile psiFile = psiManager.findFile(vFile);
if (psiFile == null || !shouldHighlightFile(psiFile)) return;
psiFile.accept(visitor);
if (clearResolveCache) {
psiManager.dropResolveCaches();
InjectedLanguageManager.getInstance(psiManager.getProject()).dropFileCaches(psiFile);
}
}
private void resetEditor(@Nonnull final List<? extends UsageInfo> infos) {
ApplicationManager.getApplication().assertIsDispatchThread();
PsiElement psiElement = infos.get(0).getElement();
if (psiElement == null) return;
PsiFile psiFile = psiElement.getContainingFile();
if (psiFile == null) return;
PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(myProject).getInjectionHost(psiFile);
if (host != null) {
psiFile = host.getContainingFile();
if (psiFile == null) return;
}
final Document document = PsiDocumentManager.getInstance(psiFile.getProject()).getDocument(psiFile);
if (document == null) return;
if (myEditor == null || document != myEditor.getDocument()) {
releaseEditor();
removeAll();
myEditor = createEditor(psiFile, document);
if (myEditor == null) return;
myLineHeight = myEditor.getLineHeight();
myEditor.setBorder(null);
add(myEditor.getComponent(), BorderLayout.CENTER);
invalidate();
validate();
}
if (!Comparing.equal(infos, myCachedSelectedUsageInfos)
// avoid moving viewport
|| !UsageViewPresentation.arePatternsEqual(myCachedSearchPattern, myPresentation.getSearchPattern()) || !UsageViewPresentation.arePatternsEqual(myCachedReplacePattern, myPresentation.getReplacePattern())) {
highlight(infos, myEditor, myProject, true, HighlighterLayer.ADDITIONAL_SYNTAX);
myCachedSelectedUsageInfos = infos;
myCachedSearchPattern = myPresentation.getSearchPattern();
myCachedReplacePattern = myPresentation.getReplacePattern();
}
}
static boolean ensureInjectionUpToDate(@Nonnull Caret hostCaret) {
Editor editor = hostCaret.getEditor();
Project project = editor.getProject();
if (project != null && InjectedLanguageManager.getInstance(project).mightHaveInjectedFragmentAtOffset(editor.getDocument(), hostCaret.getOffset())) {
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
return true;
}
return false;
}
public static RefElement retrieveRefElement(@Nonnull PsiElement element, @Nonnull GlobalInspectionContext globalContext) {
PsiFile elementFile = element.getContainingFile();
RefElement refElement = globalContext.getRefManager().getReference(elementFile);
if (refElement == null) {
PsiElement context = InjectedLanguageManager.getInstance(elementFile.getProject()).getInjectionHost(elementFile);
if (context != null) refElement = globalContext.getRefManager().getReference(context.getContainingFile());
}
return refElement;
}
@Nullable
protected PsiFile getContainingFile() {
PsiFile cf = myElement.getContainingFile();
PsiFile file = InjectedLanguageManager.getInstance(cf.getProject()).getTopLevelFile(cf);
if (file != null) return file.getOriginalFile();
LOG.error("Invalid element: " + myElement);
return null;
}
@Override
protected PsiElement getParent(@Nonnull final PsiElement element) {
if (element instanceof PsiFile && InjectedLanguageManager.getInstance(element.getProject()).isInjectedFragment((PsiFile)element)) {
return element.getParent();
}
return element.getContext();
}