下面列出了怎么用com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil的API类实例代码及写法,或者点击链接到github查看源代码。
public ShaderLabCGCompletionContributor()
{
extend(CompletionType.BASIC, StandardPatterns.psiElement().withLanguage(CGLanguage.INSTANCE), new CompletionProvider()
{
@RequiredReadAction
@Override
public void addCompletions(@Nonnull CompletionParameters parameters, ProcessingContext context, @Nonnull final CompletionResultSet result)
{
Place shreds = InjectedLanguageUtil.getShreds(parameters.getOriginalFile());
for(PsiLanguageInjectionHost.Shred shred : shreds)
{
PsiLanguageInjectionHost host = shred.getHost();
if(host instanceof ShaderCGScript)
{
ShaderLabFile containingFile = (ShaderLabFile) host.getContainingFile();
ShaderReference.consumeProperties(containingFile, result::addElement);
}
}
}
});
}
@Override
public Object getData(@Nonnull Key<?> dataId) {
if (PlatformDataKeys.EDITOR == dataId) {
return myEditor;
}
if (dataId == AnActionEvent.injectedId(PlatformDataKeys.EDITOR)) {
return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
}
if (LangDataKeys.PSI_FILE == dataId) {
return myFile;
}
if (dataId == AnActionEvent.injectedId(LangDataKeys.PSI_FILE)) {
Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
return editor instanceof EditorWindow ? ((EditorWindow)editor).getInjectedFile() : getFile();
}
return super.getData(dataId);
}
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;
}
private void scheduleContributorsAfterAsyncCommit(CompletionInitializationContextImpl initContext, CompletionProgressIndicator indicator, OffsetsInFile hostCopyOffsets, boolean hasModifiers) {
CompletionPhase phase;
if (synchronous) {
phase = new CompletionPhase.BgCalculation(indicator);
indicator.makeSureLookupIsShown(0);
}
else {
phase = new CompletionPhase.CommittingDocuments(indicator, InjectedLanguageUtil.getTopLevelEditor(indicator.getEditor()));
}
CompletionServiceImpl.setCompletionPhase(phase);
AppUIExecutor.onUiThread().withDocumentsCommitted(initContext.getProject()).expireWith(phase).execute(() -> {
if (phase instanceof CompletionPhase.CommittingDocuments) {
((CompletionPhase.CommittingDocuments)phase).replaced = true;
}
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.BgCalculation(indicator));
startContributorThread(initContext, indicator, hostCopyOffsets, hasModifiers);
});
}
private static Runnable rememberDocumentState(final Editor _editor) {
final Editor editor = InjectedLanguageUtil.getTopLevelEditor(_editor);
final String documentText = editor.getDocument().getText();
final int caret = editor.getCaretModel().getOffset();
final int selStart = editor.getSelectionModel().getSelectionStart();
final int selEnd = editor.getSelectionModel().getSelectionEnd();
final int vOffset = editor.getScrollingModel().getVerticalScrollOffset();
final int hOffset = editor.getScrollingModel().getHorizontalScrollOffset();
return () -> {
DocumentEx document = (DocumentEx)editor.getDocument();
document.replaceString(0, document.getTextLength(), documentText);
editor.getCaretModel().moveToOffset(caret);
editor.getSelectionModel().setSelection(selStart, selEnd);
editor.getScrollingModel().scrollHorizontally(hOffset);
editor.getScrollingModel().scrollVertically(vOffset);
};
}
private List<LookupElement> getExactMatches(List<? extends LookupElement> items) {
String selectedText = InjectedLanguageUtil.getTopLevelEditor(myProcess.getParameters().getEditor()).getSelectionModel().getSelectedText();
List<LookupElement> exactMatches = new SmartList<>();
for (int i = 0; i < items.size(); i++) {
LookupElement item = items.get(i);
boolean isSuddenLiveTemplate = isSuddenLiveTemplate(item);
if (isPrefixItem(item, true) && !isSuddenLiveTemplate || item.getLookupString().equals(selectedText)) {
if (item instanceof LiveTemplateLookupElement) {
// prefer most recent live template lookup item
return Collections.singletonList(item);
}
exactMatches.add(item);
}
else if (i == 0 && isSuddenLiveTemplate && items.size() > 1 && !CompletionServiceImpl.isStartMatch(items.get(1), this)) {
return Collections.singletonList(item);
}
}
return exactMatches;
}
void inspectInjectedPsi(@Nonnull final List<PsiElement> elements,
final boolean onTheFly,
@Nonnull final ProgressIndicator indicator,
@Nonnull final InspectionManager iManager,
final boolean inVisibleRange,
@Nonnull final List<LocalInspectionToolWrapper> wrappers) {
final Set<PsiFile> injected = new THashSet<>();
for (PsiElement element : elements) {
InjectedLanguageUtil.enumerate(element, getFile(), false, (injectedPsi, places) -> injected.add(injectedPsi));
}
if (injected.isEmpty()) return;
Processor<PsiFile> processor = injectedPsi -> {
doInspectInjectedPsi(injectedPsi, onTheFly, indicator, iManager, inVisibleRange, wrappers);
return true;
};
if (!JobLauncher.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<>(injected), indicator, myFailFastOnAcquireReadAction, processor)) {
throw new ProcessCanceledException();
}
}
private static void iterateOverCarets(@Nonnull final Project project,
@Nonnull final Editor hostEditor,
@Nonnull final MultiCaretCodeInsightActionHandler handler) {
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
final PsiFile psiFile = documentManager.getCachedPsiFile(hostEditor.getDocument());
documentManager.commitAllDocuments();
hostEditor.getCaretModel().runForEachCaret(new CaretAction() {
@Override
public void perform(Caret caret) {
Editor editor = hostEditor;
if (psiFile != null) {
Caret injectedCaret = InjectedLanguageUtil.getCaretForInjectedLanguageNoCommit(caret, psiFile);
if (injectedCaret != null) {
caret = injectedCaret;
editor = caret.getEditor();
}
}
final PsiFile file = PsiUtilBase.getPsiFileInEditor(caret, project);
if (file != null) {
handler.invoke(project, editor, caret, file);
}
}
});
}
@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;
}
@Override
public boolean maySaveDocument(@Nonnull Document document, boolean isSaveExplicit) {
if (ApplicationManager.getApplication().isDisposed() || isSaveExplicit) {
return true;
}
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
if (!project.isInitialized() || project.isDisposed()) {
continue;
}
LookupEx lookup = LookupManager.getInstance(project).getActiveLookup();
if (lookup != null) {
Editor editor = InjectedLanguageUtil.getTopLevelEditor(lookup.getEditor());
if (editor.getDocument() == document) {
return false;
}
}
}
return true;
}
@Nullable
public static Pair<PsiFile, Editor> chooseBetweenHostAndInjected(@Nonnull PsiFile hostFile,
@Nonnull Editor hostEditor,
@Nullable PsiFile injectedFile,
@Nonnull PairProcessor<? super PsiFile, ? super Editor> predicate) {
Editor editorToApply = null;
PsiFile fileToApply = null;
Editor injectedEditor = null;
if (injectedFile != null) {
injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, injectedFile);
if (predicate.process(injectedFile, injectedEditor)) {
editorToApply = injectedEditor;
fileToApply = injectedFile;
}
}
if (editorToApply == null && hostEditor != injectedEditor && predicate.process(hostFile, hostEditor)) {
editorToApply = hostEditor;
fileToApply = hostFile;
}
if (editorToApply == null) return null;
return Pair.create(fileToApply, editorToApply);
}
@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 void selectionChanged(SelectionEvent e) {
if (!available() || !myEditor.getSelectionModel().hasSelection()) return;
ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
if (treeStructure == null) return;
final PsiElement rootElement = treeStructure.getRootPsiElement();
if (rootElement == null) return;
final SelectionModel selection = myEditor.getSelectionModel();
final TextRange textRange = rootElement.getTextRange();
int baseOffset = textRange != null ? textRange.getStartOffset() : 0;
final int start = selection.getSelectionStart()+baseOffset;
final int end = selection.getSelectionEnd()+baseOffset - 1;
final PsiElement element =
findCommonParent(InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), start),
InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), end));
if (element != null && myBlockTreeBuilder != null) {
if (myEditor.getContentComponent().hasFocus()) {
TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
selectBlockNode(findBlockNode(rangeInHostFile, true));
updateIntersectHighlighter(myHighlighter.getStartOffset(), myHighlighter.getEndOffset());
}
}
myPsiTreeBuilder.select(element);
}
@Override
public boolean containsWhiteSpaceSymbolsOnly(int startOffset, int endOffset) {
WhiteSpaceFormattingStrategy strategy = myWhiteSpaceStrategy;
if (strategy.check(myDocument.getCharsSequence(), startOffset, endOffset) >= endOffset) {
return true;
}
PsiElement injectedElement = myFile != null ? InjectedLanguageUtil.findElementAtNoCommit(myFile, startOffset) : null;
if (injectedElement != null) {
Language injectedLanguage = injectedElement.getLanguage();
if (!injectedLanguage.equals(myFile.getLanguage())) {
WhiteSpaceFormattingStrategy localStrategy = WhiteSpaceFormattingStrategyFactory.getStrategy(injectedLanguage);
if (localStrategy != null) {
return localStrategy.check(myDocument.getCharsSequence(), startOffset, endOffset) >= endOffset;
}
}
}
return false;
}
@Override
public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) {
PsiElement element = getElement(dataContext);
if (element == null) {
element = BaseRefactoringAction.getElementAtCaret(editor, file);
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
final String newName = dataContext.getData(DEFAULT_NAME);
if (newName != null) {
rename(element, project, element, editor, newName);
return;
}
}
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
final PsiElement nameSuggestionContext = InjectedLanguageUtil.findElementAtNoCommit(file, editor.getCaretModel().getOffset());
invoke(element, project, nameSuggestionContext, editor);
}
@Override
public void templateFinished(Template template, final boolean brokenOff) {
boolean bind = false;
try {
super.templateFinished(template, brokenOff);
if (!brokenOff) {
bind = performRefactoring();
}
moveOffsetAfter(!brokenOff);
}
finally {
if (!bind) {
try {
((DesktopEditorImpl)InjectedLanguageUtil.getTopLevelEditor(myEditor)).stopDumbLater();
}
finally {
FinishMarkAction.finish(myProject, myEditor, myMarkAction);
if (myBeforeRevert != null) {
myBeforeRevert.dispose();
}
}
}
}
}
private InplaceRefactoring doRename(PsiElement elementToRename, Editor editor) {
if (elementToRename instanceof PsiNameIdentifierOwner) {
RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(elementToRename);
if (processor.isInplaceRenameSupported()) {
StartMarkAction startMarkAction = StartMarkAction.canStart(elementToRename.getProject());
if (startMarkAction == null || (processor.substituteElementToRename(elementToRename, editor)
== elementToRename)) {
processor.substituteElementToRename(elementToRename, editor, new Pass<PsiElement>() {
@Override
public void pass(PsiElement element) {
MemberInplaceRenamer renamer = createMemberRenamer(element,
(PsiNameIdentifierOwner) elementToRename, editor);
boolean startedRename = renamer.performInplaceRename();
if (!startedRename) {
performDialogRename(editor);
}
}
});
return null;
}
} else {
InplaceRefactoring inplaceRefactoring = editor.getUserData(InplaceRefactoring.INPLACE_RENAMER);
if ((inplaceRefactoring instanceof MemberInplaceRenamer)) {
TemplateState templateState = TemplateManagerImpl
.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(editor));
if (templateState != null) {
templateState.gotoEnd(true);
}
}
}
}
performDialogRename(editor);
return null;
}
@Override
public void run() {
CommandProcessor.getInstance().executeCommand(getProject(), () -> {
final CodeCompletionHandlerBase handler = new CodeCompletionHandlerBase(CompletionType.BASIC) {
@Override
protected void completionFinished(final CompletionProgressIndicator indicator, boolean hasModifiers) {
// find our lookup element
final LookupElement lookupElement = ContainerUtil.find(indicator.getLookup().getItems(), insert::match);
if(lookupElement == null) {
fail("No matching lookup element found");
}
// overwrite behavior and force completion + insertHandler
CommandProcessor.getInstance().executeCommand(indicator.getProject(), new Runnable() {
@Override
public void run() {
//indicator.setMergeCommand(); Currently method has package level access
indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, lookupElement);
}
}, "Autocompletion", null);
}
};
Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
handler.invokeCompletion(getProject(), editor);
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
}, null, null);
}
@Override
public boolean canPutAt(@NotNull VirtualFile file, int line, @NotNull Project project)
{
final Document document = FileDocumentManager.getInstance().getDocument(file);
if (document != null)
{
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (psiFile != null)
{
final boolean isMuleAndXml = MuleConfigUtils.isMuleFile(psiFile);
if (isMuleAndXml)
{
final XmlTag xmlTagAt = MuleConfigUtils.getXmlTagAt(project, XDebuggerUtil.getInstance().createPosition(file, line));
if (xmlTagAt != null)
{
return MuleConfigUtils.getMuleElementTypeFromXmlElement(xmlTagAt) == MuleElementType.MESSAGE_PROCESSOR;
}
else
{
final PsiElement firstWeaveElement = WeavePsiUtils.getFirstWeaveElement(project, document, line);
if (firstWeaveElement != null)
{
PsiLanguageInjectionHost parent = PsiTreeUtil.getParentOfType(firstWeaveElement, PsiLanguageInjectionHost.class);
if (parent != null)
{
final PsiElement elementInInjected = InjectedLanguageUtil.findElementInInjected(parent, line);
final Language language = elementInInjected.getLanguage();
return language == WeaveLanguage.getInstance();
}
}
}
}
}
}
return false;
}
@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;
}
@NotNull
private List<Block> buildInjectedBlocks() {
PsiElement psi = myNode.getPsi();
if (psi == null) {
return EMPTY;
}
PsiFile file = psi.getContainingFile();
if (file == null) {
return EMPTY;
}
if (InjectedLanguageUtil.getCachedInjectedDocuments(file).isEmpty()) {
return EMPTY;
}
TextRange blockRange = myNode.getTextRange();
List<DocumentWindow> documentWindows = InjectedLanguageUtil.getCachedInjectedDocuments(file);
for (DocumentWindow documentWindow : documentWindows) {
int startOffset = documentWindow.injectedToHost(0);
int endOffset = startOffset + documentWindow.getTextLength();
if (blockRange.containsRange(startOffset, endOffset)) {
PsiFile injected = PsiDocumentManager.getInstance(psi.getProject()).getCachedPsiFile(documentWindow);
if (injected != null) {
List<Block> result = ContainerUtilRt.newArrayList();
GraphQLInjectedLanguageBlockBuilder builder = new GraphQLInjectedLanguageBlockBuilder(settings);
builder.addInjectedBlocks(result, myNode, getWrap(), getAlignment(), getIndent());
return result;
}
}
}
return EMPTY;
}
@Override
public void run() {
CommandProcessor.getInstance().executeCommand(getProject(), () -> {
final CodeCompletionHandlerBase handler = new CodeCompletionHandlerBase(CompletionType.BASIC) {
@Override
protected void completionFinished(final CompletionProgressIndicator indicator, boolean hasModifiers) {
// find our lookup element
final LookupElement lookupElement = ContainerUtil.find(indicator.getLookup().getItems(), insert::match);
if(lookupElement == null) {
fail("No matching lookup element found");
}
// overwrite behavior and force completion + insertHandler
CommandProcessor.getInstance().executeCommand(indicator.getProject(), new Runnable() {
@Override
public void run() {
//indicator.setMergeCommand(); Currently method has package level access
indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, lookupElement);
}
}, "Autocompletion", null);
}
};
Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
handler.invokeCompletion(getProject(), editor);
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
}, null, null);
}
@Override
@Nonnull
public List<IntentionAction> getAvailableIntentions() {
doHighlighting();
PsiFile file = getFile();
Editor editor = getEditor();
if (editor instanceof EditorWindow) {
editor = ((EditorWindow)editor).getDelegate();
file = InjectedLanguageUtil.getTopLevelFile(file);
}
return getAvailableIntentions(editor, file);
}
private void setupEditorForInjectedLanguage() {
Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
if (editor instanceof EditorWindow) {
myFile = ((EditorWindow)editor).getInjectedFile();
myEditor = editor;
}
}
@Override
@Nonnull
public List<HighlightInfo> doHighlighting() {
final Project project = getProject();
PsiDocumentManager.getInstance(project).commitAllDocuments();
PsiFile file = getFile();
Editor editor = getEditor();
if (editor instanceof EditorWindow) {
editor = ((EditorWindow)editor).getDelegate();
file = InjectedLanguageUtil.getTopLevelFile(file);
}
return instantiateAndRun(file, editor, ArrayUtil.EMPTY_INT_ARRAY, myAllowDirt);
}
private static void setupEditorForInjectedLanguage() {
Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
if (editor instanceof EditorWindow) {
myFile = ((EditorWindow)editor).getInjectedFile();
myEditor = editor;
}
}
private void updateComponentInner(@Nonnull DataContext dataContext, boolean requestFocus) {
if (dataContext.getData(CommonDataKeys.PROJECT) != myProject) {
return;
}
final Editor editor = dataContext.getData(CommonDataKeys.EDITOR);
if (editor == null) {
PsiElement element = dataContext.getData(CommonDataKeys.PSI_ELEMENT);
if (element != null) {
doUpdateComponent(element);
}
return;
}
PsiDocumentManager.getInstance(myProject).performLaterWhenAllCommitted(() -> {
if (editor.isDisposed()) return;
PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
Editor injectedEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file);
PsiFile injectedFile = injectedEditor != null ? PsiUtilBase.getPsiFileInEditor(injectedEditor, myProject) : null;
if (injectedFile != null) {
doUpdateComponent(injectedEditor, injectedFile, requestFocus);
}
else if (file != null) {
doUpdateComponent(editor, file, requestFocus);
}
});
}
static OffsetsInFile insertDummyIdentifier(CompletionInitializationContext initContext, CompletionProgressIndicator indicator) {
OffsetsInFile topLevelOffsets = indicator.getHostOffsets();
CompletionAssertions.checkEditorValid(initContext.getEditor());
if (initContext.getDummyIdentifier().isEmpty()) {
return topLevelOffsets;
}
Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(initContext.getEditor());
OffsetMap hostMap = topLevelOffsets.getOffsets();
PsiFile hostCopy = obtainFileCopy(topLevelOffsets.getFile());
Document copyDocument = Objects.requireNonNull(hostCopy.getViewProvider().getDocument());
String dummyIdentifier = initContext.getDummyIdentifier();
int startOffset = hostMap.getOffset(CompletionInitializationContext.START_OFFSET);
int endOffset = hostMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET);
indicator.registerChildDisposable(() -> new OffsetTranslator(hostEditor.getDocument(), initContext.getFile(), copyDocument, startOffset, endOffset, dummyIdentifier));
copyDocument.setText(hostEditor.getDocument().getText());
OffsetMap copyOffsets = topLevelOffsets.getOffsets().copyOffsets(copyDocument);
indicator.registerChildDisposable(() -> copyOffsets);
copyDocument.replaceString(startOffset, endOffset, dummyIdentifier);
return new OffsetsInFile(hostCopy, copyOffsets);
}
private static WatchingInsertionContext insertItemHonorBlockSelection(CompletionProcessEx indicator, LookupElement item, char completionChar, StatisticsUpdate update) {
final Editor editor = indicator.getEditor();
final int caretOffset = indicator.getCaret().getOffset();
final int idEndOffset = calcIdEndOffset(indicator);
final int idEndOffsetDelta = idEndOffset - caretOffset;
WatchingInsertionContext context;
if (editor.getCaretModel().supportsMultipleCarets()) {
Ref<WatchingInsertionContext> lastContext = Ref.create();
Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
boolean wasInjected = hostEditor != editor;
OffsetsInFile topLevelOffsets = indicator.getHostOffsets();
hostEditor.getCaretModel().runForEachCaret(caret -> {
OffsetsInFile targetOffsets = findInjectedOffsetsIfAny(caret, wasInjected, topLevelOffsets, hostEditor);
PsiFile targetFile = targetOffsets.getFile();
Editor targetEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, targetFile);
int targetCaretOffset = targetEditor.getCaretModel().getOffset();
int idEnd = targetCaretOffset + idEndOffsetDelta;
if (idEnd > targetEditor.getDocument().getTextLength()) {
idEnd = targetCaretOffset; // no replacement by Tab when offsets gone wrong for some reason
}
WatchingInsertionContext currentContext = insertItem(indicator.getLookup(), item, completionChar, update, targetEditor, targetFile, targetCaretOffset, idEnd, targetOffsets.getOffsets());
lastContext.set(currentContext);
});
context = lastContext.get();
}
else {
PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, indicator.getProject());
context = insertItem(indicator.getLookup(), item, completionChar, update, editor, psiFile, caretOffset, idEndOffset, indicator.getOffsetMap());
}
if (context.shouldAddCompletionChar()) {
WriteAction.run(() -> addCompletionChar(context, item));
}
checkPsiTextConsistency(indicator);
return context;
}
private static void checkPsiTextConsistency(CompletionProcessEx indicator) {
PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(InjectedLanguageUtil.getTopLevelEditor(indicator.getEditor()), indicator.getProject());
if (psiFile != null) {
if (Registry.is("ide.check.stub.text.consistency") || ApplicationManager.getApplication().isUnitTestMode() && !ApplicationInfoImpl.isInPerformanceTest()) {
StubTextInconsistencyException.checkStubTextConsistency(psiFile);
if (PsiDocumentManager.getInstance(psiFile.getProject()).hasUncommitedDocuments()) {
PsiDocumentManager.getInstance(psiFile.getProject()).commitAllDocuments();
StubTextInconsistencyException.checkStubTextConsistency(psiFile);
}
}
}
}