use of com.intellij.psi.PsiLanguageInjectionHost in project intellij-community by JetBrains.
the class XmlLanguageInjector method getInjectedLanguage.
void getInjectedLanguage(final PsiElement place, final Ref<Boolean> unparsableRef, final PairProcessor<Language, List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>>> processor) {
if (place instanceof XmlTag) {
final XmlTag xmlTag = (XmlTag) place;
List<BaseInjection> injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
//noinspection ForLoopReplaceableByForEach
for (int i = 0, injectionsSize = injections.size(); i < injectionsSize; i++) {
final BaseInjection injection = injections.get(i);
if (injection.acceptsPsiElement(xmlTag)) {
final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
if (language == null)
continue;
final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());
final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result = ContainerUtil.newArrayList();
xmlTag.acceptChildren(new PsiElementVisitor() {
@Override
public void visitElement(final PsiElement element) {
if (element instanceof XmlText) {
if (!(element instanceof PsiLanguageInjectionHost) || element.getTextLength() == 0)
return;
final List<TextRange> list = injection.getInjectedArea(element);
final InjectedLanguage l = InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false);
for (TextRange textRange : list) {
result.add(Trinity.create((PsiLanguageInjectionHost) element, l, textRange));
}
} else if (element instanceof XmlTag) {
if (!separateFiles)
unparsableRef.set(Boolean.TRUE);
if (injection instanceof AbstractTagInjection && ((AbstractTagInjection) injection).isApplyToSubTags()) {
element.acceptChildren(this);
}
}
}
});
if (!result.isEmpty()) {
if (separateFiles) {
for (Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange> trinity : result) {
processor.process(language, Collections.singletonList(trinity));
}
} else {
processor.process(language, result);
}
}
if (injection.isTerminal()) {
break;
}
}
}
} else if (place instanceof XmlAttributeValue && place.getParent() instanceof XmlAttribute) {
final XmlAttribute attribute = (XmlAttribute) place.getParent();
final XmlAttributeValue value = (XmlAttributeValue) place;
//if (value == null) return;
// Check that we don't inject anything into embedded (e.g. JavaScript) content:
// XmlToken: "
// JSEmbeddedContent
// XmlToken "
// Actually IDEA shouldn't ask for injected languages at all in this case.
final PsiElement[] children = value.getChildren();
if (children.length < 3 || !(children[1] instanceof XmlToken) || ((XmlToken) children[1]).getTokenType() != XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) {
return;
}
List<BaseInjection> injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = injections.size(); i < size; i++) {
BaseInjection injection = injections.get(i);
if (injection.acceptsPsiElement(attribute)) {
final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
if (language == null)
continue;
final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());
final List<TextRange> ranges = injection.getInjectedArea(value);
if (ranges.isEmpty())
continue;
final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result = new ArrayList<>();
final InjectedLanguage l = InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false);
for (TextRange textRange : ranges) {
result.add(Trinity.create((PsiLanguageInjectionHost) value, l, textRange));
}
if (separateFiles) {
for (Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange> trinity : result) {
processor.process(language, Collections.singletonList(trinity));
}
} else {
processor.process(language, result);
}
if (injection.isTerminal()) {
break;
}
}
}
}
}
use of com.intellij.psi.PsiLanguageInjectionHost in project intellij-community by JetBrains.
the class InjectedLanguageBlockBuilder method addInjectedBlocks.
public boolean addInjectedBlocks(List<Block> result, final ASTNode injectionHost, Wrap wrap, Alignment alignment, Indent indent) {
final PsiFile[] injectedFile = new PsiFile[1];
final Ref<TextRange> injectedRangeInsideHost = new Ref<>();
final Ref<Integer> prefixLength = new Ref<>();
final Ref<Integer> suffixLength = new Ref<>();
final Ref<ASTNode> injectionHostToUse = new Ref<>(injectionHost);
final PsiLanguageInjectionHost.InjectedPsiVisitor injectedPsiVisitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List<PsiLanguageInjectionHost.Shred> places) {
if (places.size() != 1) {
return;
}
final PsiLanguageInjectionHost.Shred shred = places.get(0);
TextRange textRange = shred.getRangeInsideHost();
PsiLanguageInjectionHost shredHost = shred.getHost();
if (shredHost == null) {
return;
}
ASTNode node = shredHost.getNode();
if (node == null) {
return;
}
if (node != injectionHost) {
int shift = 0;
boolean canProcess = false;
for (ASTNode n = injectionHost.getTreeParent(), prev = injectionHost; n != null; prev = n, n = n.getTreeParent()) {
shift += n.getStartOffset() - prev.getStartOffset();
if (n == node) {
textRange = textRange.shiftRight(shift);
canProcess = true;
break;
}
}
if (!canProcess) {
return;
}
}
String childText;
if ((injectionHost.getTextLength() == textRange.getEndOffset() && textRange.getStartOffset() == 0) || (canProcessFragment((childText = injectionHost.getText()).substring(0, textRange.getStartOffset()), injectionHost) && canProcessFragment(childText.substring(textRange.getEndOffset()), injectionHost))) {
injectedFile[0] = injectedPsi;
injectedRangeInsideHost.set(textRange);
prefixLength.set(shred.getPrefix().length());
suffixLength.set(shred.getSuffix().length());
}
}
};
final PsiElement injectionHostPsi = injectionHost.getPsi();
InjectedLanguageUtil.enumerate(injectionHostPsi, injectionHostPsi.getContainingFile(), false, injectedPsiVisitor);
if (injectedFile[0] != null) {
final Language childLanguage = injectedFile[0].getLanguage();
final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(childLanguage, injectionHostPsi);
if (builder != null) {
final int startOffset = injectedRangeInsideHost.get().getStartOffset();
final int endOffset = injectedRangeInsideHost.get().getEndOffset();
TextRange range = injectionHostToUse.get().getTextRange();
int childOffset = range.getStartOffset();
if (startOffset != 0) {
final ASTNode leaf = injectionHostToUse.get().findLeafElementAt(startOffset - 1);
result.add(createBlockBeforeInjection(leaf, wrap, alignment, indent, new TextRange(childOffset, childOffset + startOffset)));
}
addInjectedLanguageBlockWrapper(result, injectedFile[0].getNode(), indent, childOffset + startOffset, new TextRange(prefixLength.get(), injectedFile[0].getTextLength() - suffixLength.get()));
if (endOffset != injectionHostToUse.get().getTextLength()) {
final ASTNode leaf = injectionHostToUse.get().findLeafElementAt(endOffset);
result.add(createBlockAfterInjection(leaf, wrap, alignment, indent, new TextRange(childOffset + endOffset, range.getEndOffset())));
}
return true;
}
}
return false;
}
use of com.intellij.psi.PsiLanguageInjectionHost in project intellij-community by JetBrains.
the class IElementTypeTest method testManipulatorRegistered.
public void testManipulatorRegistered() {
LanguageExtensionPoint[] extensions = Extensions.getExtensions(new ExtensionPointName<LanguageExtensionPoint>("com.intellij.lang.parserDefinition"));
Set<String> classes = new HashSet<>();
List<String> failures = new ArrayList<>();
int total = 0;
for (LanguageExtensionPoint e : extensions) {
ParserDefinition definition = (ParserDefinition) e.getInstance();
for (IElementType type : IElementType.enumerate(IElementType.TRUE)) {
if (type instanceof ILeafElementType)
continue;
try {
CompositeElement treeElement = ASTFactory.composite(type);
total++;
PsiElement element = treeElement instanceof PsiElement ? (PsiElement) treeElement : definition.createElement(treeElement);
if (element instanceof PsiLanguageInjectionHost && classes.add(element.getClass().getName())) {
boolean ok = ElementManipulators.getManipulator(element) != null;
System.out.println((ok ? "OK " : "FAIL") + " " + element.getClass().getSimpleName() + " [" + definition.getClass().getSimpleName() + "]");
if (!ok)
failures.add(element.getClass().getName());
}
} catch (Throwable ignored) {
}
}
}
System.out.println("count: " + classes.size() + ", total: " + total);
assertEmpty("PsiLanguageInjectionHost requires " + ElementManipulators.EP_NAME, failures);
}
use of com.intellij.psi.PsiLanguageInjectionHost in project intellij-community by JetBrains.
the class XsltCodeInsightUtil method getRangeInsideHostingFile.
@NotNull
public static TextRange getRangeInsideHostingFile(XPathElement expr) {
final PsiLanguageInjectionHost host = PsiTreeUtil.getContextOfType(expr, PsiLanguageInjectionHost.class, true);
assert host != null;
final List<Pair<PsiElement, TextRange>> psi = InjectedLanguageManager.getInstance(host.getProject()).getInjectedPsiFiles(host);
assert psi != null;
for (Pair<PsiElement, TextRange> pair : psi) {
if (PsiTreeUtil.isAncestor(pair.first, expr, false)) {
return expr.getTextRange().shiftRight(pair.second.getStartOffset() + host.getTextRange().getStartOffset());
}
}
assert false;
return null;
}
use of com.intellij.psi.PsiLanguageInjectionHost in project intellij-community by JetBrains.
the class PyDocstringFile method getLanguageLevel.
@Override
public LanguageLevel getLanguageLevel() {
final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(getProject());
final PsiLanguageInjectionHost host = languageManager.getInjectionHost(this);
if (host != null)
return LanguageLevel.forElement(host.getContainingFile());
return super.getLanguageLevel();
}
Aggregations