下面列出了com.intellij.psi.PsiReferenceProvider#com.intellij.patterns.ElementPattern 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Check for {{ include('|') }}
*
* @param functionName twig function name
*/
public static ElementPattern<PsiElement> getPrintBlockFunctionPattern(String... functionName) {
//noinspection unchecked
return PlatformPatterns
.psiElement(TwigTokenTypes.STRING_TEXT)
.withParent(PlatformPatterns.or(
PlatformPatterns.psiElement(TwigElementTypes.PRINT_BLOCK),
PlatformPatterns.psiElement(TwigElementTypes.SET_TAG),
PlatformPatterns.psiElement(TwigElementTypes.IF_TAG),
PlatformPatterns.psiElement(TwigElementTypes.FUNCTION_CALL)
))
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(TwigTokenTypes.LBRACE),
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE),
PlatformPatterns.psiElement(TwigTokenTypes.SINGLE_QUOTE),
PlatformPatterns.psiElement(TwigTokenTypes.DOUBLE_QUOTE)
),
PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).withText(PlatformPatterns.string().oneOf(functionName))
)
.withLanguage(TwigLanguage.INSTANCE);
}
public static ElementPattern<PsiElement> getIfVariablePattern() {
// {% if "var" %}
//noinspection unchecked
return PlatformPatterns
.psiElement(TwigTokenTypes.IDENTIFIER)
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME).withText(
PlatformPatterns.string().oneOfIgnoreCase("if")
)
)
.withParent(
PlatformPatterns.psiElement(TwigElementTypes.IF_TAG)
)
.withLanguage(TwigLanguage.INSTANCE);
}
private void assertReferences(@NotNull ElementPattern<?> pattern, PsiElement psiElement) {
for (PsiReference reference : psiElement.getReferences()) {
// single resolve; should also match first multi by design
PsiElement element = reference.resolve();
if (pattern.accepts(element)) {
return;
}
// multiResolve support
if(element instanceof PsiPolyVariantReference) {
for (ResolveResult resolveResult : ((PsiPolyVariantReference) element).multiResolve(true)) {
if (pattern.accepts(resolveResult.getElement())) {
return;
}
}
}
}
fail(String.format("Fail that '%s' match given pattern", psiElement.toString()));
}
/**
* {% include foo ? '' : '' %}
* {% extends foo ? '' : '' %}
*/
public static ElementPattern<PsiElement> getTagTernaryPattern(@NotNull IElementType type) {
//noinspection unchecked
return PlatformPatterns.or(
PlatformPatterns.psiElement(TwigTokenTypes.STRING_TEXT)
.withParent(
PlatformPatterns.psiElement(type)
)
.afterLeafSkipping(
STRING_WRAP_PATTERN,
PlatformPatterns.psiElement(TwigTokenTypes.QUESTION)
)
.withLanguage(TwigLanguage.INSTANCE),
PlatformPatterns.psiElement(TwigTokenTypes.STRING_TEXT)
.withParent(
PlatformPatterns.psiElement(type)
)
.afterLeafSkipping(
STRING_WRAP_PATTERN,
PlatformPatterns.psiElement(TwigTokenTypes.COLON)
)
.withLanguage(TwigLanguage.INSTANCE)
);
}
/**
* Check for {% if foo is "foo foo" %}
*/
public static ElementPattern<PsiElement> getAfterIsTokenWithOneIdentifierLeafPattern() {
//noinspection unchecked
return PlatformPatterns
.psiElement()
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).afterLeafSkipping(PlatformPatterns.psiElement(PsiWhiteSpace.class), PlatformPatterns.or(
PlatformPatterns.psiElement(TwigTokenTypes.IS),
PlatformPatterns.psiElement(TwigTokenTypes.NOT)
))
)
.withLanguage(TwigLanguage.INSTANCE);
}
private void addMatchingProviders(final PsiElement position,
@Nullable final List<ProviderInfo<Provider, ElementPattern>> providerList,
@Nonnull List<ProviderInfo<Provider, ProcessingContext>> ret,
PsiReferenceService.Hints hints) {
if (providerList == null) return;
for (ProviderInfo<Provider, ElementPattern> trinity : providerList) {
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.provider).acceptsHints(position, hints)) {
continue;
}
final ProcessingContext context = new ProcessingContext();
if (hints != PsiReferenceService.Hints.NO_HINTS) {
context.put(PsiReferenceService.HINTS, hints);
}
boolean suitable = false;
try {
suitable = trinity.processingContext.accepts(position, context);
}
catch (IndexNotReadyException ignored) {
}
if (suitable) {
ret.add(new ProviderInfo<Provider, ProcessingContext>(trinity.provider, context, trinity.priority));
}
}
}
private void assertReferences(@NotNull ElementPattern<?> pattern, PsiElement psiElement) {
for (PsiReference reference : psiElement.getReferences()) {
// single resolve; should also match first multi by design
PsiElement element = reference.resolve();
if (pattern.accepts(element)) {
return;
}
// multiResolve support
if(reference instanceof PsiPolyVariantReference) {
for (ResolveResult resolveResult : ((PsiPolyVariantReference) reference).multiResolve(true)) {
if (pattern.accepts(resolveResult.getElement())) {
return;
}
}
}
}
fail(String.format("Fail that '%s' match given pattern", psiElement.toString()));
}
/**
* {% filter foo %}
*/
public static ElementPattern<PsiElement> getFilterTagPattern() {
//noinspection unchecked
return
PlatformPatterns
.psiElement(TwigTokenTypes.IDENTIFIER)
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME)
)
.withParent(
PlatformPatterns.psiElement(TwigElementTypes.FILTER_TAG)
)
.withLanguage(TwigLanguage.INSTANCE)
;
}
/**
* Check for {% if foo is "foo" %}
*/
public static ElementPattern<PsiElement> getAfterIsTokenPattern() {
//noinspection unchecked
return PlatformPatterns
.psiElement()
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.or(
PlatformPatterns.psiElement(TwigTokenTypes.IS),
PlatformPatterns.psiElement(TwigTokenTypes.NOT)
)
)
.withLanguage(TwigLanguage.INSTANCE);
}
public static ElementPattern<PsiElement> getSetVariablePattern() {
// {% set count1 = "var" %}
//noinspection unchecked
return PlatformPatterns
.psiElement(TwigTokenTypes.IDENTIFIER)
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.psiElement(TwigTokenTypes.EQ)
)
.withParent(
PlatformPatterns.psiElement(TwigElementTypes.SET_TAG)
)
.withLanguage(TwigLanguage.INSTANCE);
}
private MultiMap<SemKey, NullableFunction<PsiElement, ? extends SemElement>> collectProducers() {
final MultiMap<SemKey, NullableFunction<PsiElement, ? extends SemElement>> map = MultiMap.createSmart();
final SemRegistrar registrar = new SemRegistrar() {
@Override
public <T extends SemElement, V extends PsiElement> void registerSemElementProvider(SemKey<T> key,
final ElementPattern<? extends V> place,
final NullableFunction<V, T> provider) {
map.putValue(key, element -> {
if (place.accepts(element)) {
return provider.fun((V)element);
}
return null;
});
}
};
for (SemContributorEP contributor : myProject.getExtensions(SemContributor.EP_NAME)) {
contributor.registerSemProviders(myProject.getInjectingContainer(), registrar);
}
return map;
}
/**
* Check for {{ include('|') }}
*
* @param functionName twig function name
*/
public static ElementPattern<PsiElement> getPrintBlockFunctionPattern(String... functionName) {
//noinspection unchecked
return PlatformPatterns
.psiElement(TwigTokenTypes.STRING_TEXT)
.withParent(PlatformPatterns.or(
PlatformPatterns.psiElement(TwigElementTypes.PRINT_BLOCK),
PlatformPatterns.psiElement(TwigElementTypes.SET_TAG),
PlatformPatterns.psiElement(TwigElementTypes.IF_TAG),
PlatformPatterns.psiElement(TwigElementTypes.FUNCTION_CALL)
))
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(TwigTokenTypes.LBRACE),
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE),
PlatformPatterns.psiElement(TwigTokenTypes.SINGLE_QUOTE),
PlatformPatterns.psiElement(TwigTokenTypes.DOUBLE_QUOTE)
),
PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).withText(PlatformPatterns.string().oneOf(functionName))
)
.withLanguage(TwigLanguage.INSTANCE);
}
public void assertNavigationMatch(LanguageFileType languageFileType, String configureByText, ElementPattern<?> pattern) {
myFixture.configureByText(languageFileType, configureByText);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
Set<String> targetStrings = new HashSet<>();
for (GotoDeclarationHandler gotoDeclarationHandler : Extensions.getExtensions(GotoDeclarationHandler.EP_NAME)) {
PsiElement[] gotoDeclarationTargets = gotoDeclarationHandler.getGotoDeclarationTargets(psiElement, 0, myFixture.getEditor());
if(gotoDeclarationTargets == null || gotoDeclarationTargets.length == 0) {
continue;
}
for (PsiElement gotoDeclarationTarget : gotoDeclarationTargets) {
targetStrings.add(gotoDeclarationTarget.toString());
if(pattern.accepts(gotoDeclarationTarget)) {
return;
}
}
}
fail(String.format("failed that PsiElement (%s) navigate matches one of %s", psiElement.toString(), targetStrings.toString()));
}
@Override
public void addAcceptableReferenceProviders(@Nonnull PsiElement position,
@Nonnull List<ProviderInfo<Provider, ProcessingContext>> list,
@Nonnull PsiReferenceService.Hints hints) {
for (ProviderInfo<Provider, ElementPattern> trinity : myProviderPairs) {
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.provider).acceptsHints(position, hints)) {
continue;
}
final ProcessingContext context = new ProcessingContext();
if (hints != PsiReferenceService.Hints.NO_HINTS) {
context.put(PsiReferenceService.HINTS, hints);
}
boolean suitable = false;
try {
suitable = trinity.processingContext.accepts(position, context);
}
catch (IndexNotReadyException ignored) {
}
if (suitable) {
list.add(new ProviderInfo<Provider, ProcessingContext>(trinity.provider, context, trinity.priority));
}
}
}
private void assertNavigationMatch(ElementPattern<?> pattern) {
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
Set<String> targetStrings = new HashSet<String>();
for (GotoDeclarationHandler gotoDeclarationHandler : Extensions.getExtensions(GotoDeclarationHandler.EP_NAME)) {
PsiElement[] gotoDeclarationTargets = gotoDeclarationHandler.getGotoDeclarationTargets(psiElement, 0, myFixture.getEditor());
if(gotoDeclarationTargets == null || gotoDeclarationTargets.length == 0) {
continue;
}
for (PsiElement gotoDeclarationTarget : gotoDeclarationTargets) {
targetStrings.add(gotoDeclarationTarget.toString());
if(pattern.accepts(gotoDeclarationTarget)) {
return;
}
}
}
fail(String.format("failed that PsiElement (%s) navigate matches one of %s", psiElement.toString(), targetStrings.toString()));
}
private void assertNavigationMatch(ElementPattern<?> pattern) {
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
Set<String> targetStrings = new HashSet<String>();
for (GotoDeclarationHandler gotoDeclarationHandler : Extensions.getExtensions(GotoDeclarationHandler.EP_NAME)) {
PsiElement[] gotoDeclarationTargets = gotoDeclarationHandler.getGotoDeclarationTargets(psiElement, 0, myFixture.getEditor());
if(gotoDeclarationTargets == null || gotoDeclarationTargets.length == 0) {
continue;
}
for (PsiElement gotoDeclarationTarget : gotoDeclarationTargets) {
targetStrings.add(gotoDeclarationTarget.toString());
if(pattern.accepts(gotoDeclarationTarget)) {
return;
}
}
}
fail(String.format("failed that PsiElement (%s) navigate matches one of %s", psiElement.toString(), targetStrings.toString()));
}
public void assertPhpReferenceResolveTo(LanguageFileType languageFileType, String configureByText, ElementPattern<?> pattern) {
myFixture.configureByText(languageFileType, configureByText);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
psiElement = PsiTreeUtil.getParentOfType(psiElement, PhpReference.class);
if (psiElement == null) {
fail("Element is not PhpReference.");
}
PsiElement resolve = ((PhpReference) psiElement).resolve();
if(!pattern.accepts(resolve)) {
fail(String.format("failed pattern matches element of '%s'", resolve == null ? "null" : resolve.toString()));
}
assertTrue(pattern.accepts(resolve));
}
public static ElementPattern<PsiElement> getTwigMacroNameKnownPattern(String macroName) {
// {% macro <foo>(user) %}
//noinspection unchecked
return PlatformPatterns
.psiElement(TwigTokenTypes.IDENTIFIER).withText(macroName)
.withParent(PlatformPatterns.psiElement(
TwigElementTypes.MACRO_TAG
))
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME).withText("macro")
)
.withLanguage(TwigLanguage.INSTANCE);
}
/**
* {% block 'foo' %}
* {% block "foo" %}
* {% block foo %}
*/
public static ElementPattern<PsiElement> getBlockTagPattern() {
//noinspection unchecked
return PlatformPatterns.or(
// {% block "foo" %}
PlatformPatterns
.psiElement(TwigTokenTypes.STRING_TEXT)
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE),
PlatformPatterns.psiElement(TwigTokenTypes.SINGLE_QUOTE),
PlatformPatterns.psiElement(TwigTokenTypes.DOUBLE_QUOTE)
),
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME)
)
.withParent(
PlatformPatterns.psiElement(TwigBlockTag.class)
)
.withLanguage(TwigLanguage.INSTANCE),
// {% block foo %}
PlatformPatterns
.psiElement(TwigTokenTypes.IDENTIFIER)
.afterLeafSkipping(
PlatformPatterns.or(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
),
PlatformPatterns.psiElement(TwigTokenTypes.TAG_NAME)
)
.withParent(
PlatformPatterns.psiElement(TwigBlockTag.class)
)
.withLanguage(TwigLanguage.INSTANCE)
);
}
public void assertPhpReferenceResolveTo(LanguageFileType languageFileType, String configureByText, ElementPattern<?> pattern) {
myFixture.configureByText(languageFileType, configureByText);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
psiElement = PsiTreeUtil.getParentOfType(psiElement, PhpReference.class);
if (psiElement == null) {
fail("Element is not PhpReference.");
}
assertTrue(pattern.accepts(((PhpReference) psiElement).resolve()));
}
public void assertPhpReferenceNotResolveTo(LanguageFileType languageFileType, String configureByText, ElementPattern<?> pattern) {
myFixture.configureByText(languageFileType, configureByText);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
psiElement = PsiTreeUtil.getParentOfType(psiElement, PhpReference.class);
if (psiElement == null) {
fail("Element is not PhpReference.");
}
assertFalse(pattern.accepts(((PhpReference) psiElement).resolve()));
}
/**
* matches "@Callback(<property>=)"
*/
public static ElementPattern<PsiElement> getPropertyIdentifier(String propertyName) {
return PlatformPatterns.psiElement(PhpDocTokenTypes.DOC_IDENTIFIER).withText(propertyName)
.beforeLeafSkipping(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(PhpDocTokenTypes.DOC_TEXT).withText("=")
)
.withParent(PlatformPatterns.psiElement(PhpDocElementTypes.phpDocAttributeList));
}
private void assertReferenceMatchOnParent(@NotNull ElementPattern<?> pattern) {
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
if(psiElement == null) {
fail("Fail to find element in caret");
}
PsiElement parent = psiElement.getParent();
if(parent == null) {
fail("Fail to find parent element in caret");
}
assertReferences(pattern, parent);
}
public void assertReferenceMatchOnParent(@NotNull FileType fileType, @NotNull String contents, @NotNull ElementPattern<?> pattern) {
myFixture.configureByText(fileType, contents);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
if(psiElement == null) {
fail("Fail to find element in caret");
}
PsiElement parent = psiElement.getParent();
if(parent == null) {
fail("Fail to find parent element in caret");
}
assertReferences(pattern, parent);
}
/**
* return 'value' inside class method
*/
static public ElementPattern<PhpExpression> getMethodReturnPattern() {
return PlatformPatterns.or(
PlatformPatterns.psiElement(StringLiteralExpression.class)
.withParent(PlatformPatterns.psiElement(PhpReturn.class).inside(Method.class))
.withLanguage(PhpLanguage.INSTANCE),
PlatformPatterns.psiElement(ClassConstantReference.class)
.withParent(PlatformPatterns.psiElement(PhpReturn.class).inside(Method.class))
.withLanguage(PhpLanguage.INSTANCE)
);
}
public void assertPhpReferenceResolveTo(LanguageFileType languageFileType, String configureByText, ElementPattern<?> pattern) {
myFixture.configureByText(languageFileType, configureByText);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
psiElement = PsiTreeUtil.getParentOfType(psiElement, PhpReference.class);
if (psiElement == null) {
fail("Element is not PhpReference.");
}
assertTrue(pattern.accepts(((PhpReference) psiElement).resolve()));
}
private static ElementPattern<? extends PsiElement> annotationAboveMethod() {
// PsiIdentifier -> PsiJavaCodeReference -> PsiAnnotation -> PsiModifierList -> PsiMethod
return PlatformPatterns.psiElement(PsiIdentifier.class)
.withSuperParent(2, PsiAnnotation.class)
.withSuperParent(4, PsiMethod.class)
.afterLeaf("@");
}
@NotNull
private ElementPattern<PsiElement> getPositionPattern() {
return PlatformPatterns.or(
PlatformPatterns.psiElement(PhpTokenTypes.STRING_LITERAL_SINGLE_QUOTE).withParent(StringLiteralExpression.class),
PlatformPatterns.psiElement(PhpTokenTypes.STRING_LITERAL).withParent(StringLiteralExpression.class)
);
}
@NotNull
public static ElementPattern<PsiElement> elementWithStringLiteral(IElementType elementType, @NotNull String value) {
return PlatformPatterns.or(
PlatformPatterns.psiElement(elementType).withText("\"" + value + "\""),
PlatformPatterns.psiElement(elementType).withText("'" + value + "'")
);
}
private static ElementPattern<StringLiteralExpression> methodCallOnVariableWithStringArgument() {
return PlatformPatterns.psiElement(StringLiteralExpression.class).withSuperParent(
2,
PlatformPatterns.psiElement(MethodReference.class).withFirstChild(
PlatformPatterns.psiElement(Variable.class)
)
);
}