下面列出了怎么用com.intellij.psi.xml.XmlAttributeValue的API类实例代码及写法,或者点击链接到github查看源代码。
public void testReferenceCanResolveDefinition() {
PsiFile file = myFixture.configureByText(PhpFileType.INSTANCE, "<?php \n" +
"\"LLL:EXT:foo/sample.xlf:sys_<caret>language.language_isocode.ab\";");
PsiElement elementAtCaret = file.findElementAt(myFixture.getCaretOffset()).getParent();
PsiReference[] references = elementAtCaret.getReferences();
for (PsiReference reference : references) {
if (reference instanceof TranslationReference) {
ResolveResult[] resolveResults = ((TranslationReference) reference).multiResolve(false);
for (ResolveResult resolveResult : resolveResults) {
assertInstanceOf(resolveResult.getElement(), XmlAttributeValue.class);
return;
}
}
}
fail("TranslationReference could not be resolved");
}
public static PsiElement retrieveFluidElementAtPosition(PsiElement psiElement) {
FileViewProvider viewProvider = psiElement.getContainingFile().getViewProvider();
if (!viewProvider.getLanguages().contains(FluidLanguage.INSTANCE)) {
return null;
}
int textOffset = psiElement.getTextOffset();
FluidFile psi = (FluidFile) viewProvider.getPsi(FluidLanguage.INSTANCE);
if (psiElement instanceof XmlAttributeValue) {
textOffset += 2;
}
PsiElement elementAt = psi.findElementAt(textOffset);
if (elementAt == null) {
return null;
}
if (elementAt.getNode().getElementType().equals(FluidTypes.IDENTIFIER)) {
return elementAt.getParent();
}
return null;
}
private static Template buildTemplate(@NotNull XmlAttribute attr, List<XmlTag> refs) {
//XmlFile containingFile = (XmlFile)attr.getContainingFile();
PsiElement commonParent = PsiTreeUtil.findCommonParent(refs);
TemplateBuilderImpl builder = new TemplateBuilderImpl(attr);
XmlAttributeValue attrValue = attr.getValueElement();
PsiElement valuePsi = attrValue.getFirstChild().getNextSibling();
String flowNameValue = new String(attrValue.getValue());
builder.replaceElement(valuePsi,"PrimaryVariable", new TextExpression(flowNameValue), true);
/*
for (XmlTag ref : refs) {
if (ref.getContainingFile().equals(attr.getContainingFile())) {
XmlAttribute nextAttr = ref.getAttribute(MuleConfigConstants.NAME_ATTRIBUTE);
XmlAttributeValue nextValue = nextAttr.getValueElement();
PsiElement nextValuePsi = nextValue.getFirstChild().getNextSibling();
builder.replaceElement(nextValuePsi, "OtherVariable", "PrimaryVariable",false);
}
}
*/
return builder.buildInlineTemplate();
}
public boolean isReferenceTo(PsiElement element) {
if (element == null)
return false;
PsiElement parent = PsiTreeUtil.getParentOfType(element, XmlTag.class);
if (parent != null && parent instanceof XmlTag &&
(MuleConfigConstants.FLOW_TAG_NAME.equals(((XmlTag)parent).getName()) ||
MuleConfigConstants.SUB_FLOW_TAG_NAME.equals(((XmlTag)parent).getName()))) { //It's a <flow> tag or <sub-flow> tag
if (element instanceof XmlAttributeValue && ((XmlAttributeValue)element).getValue().equals(getFlowName())) {
return true;
}
}
return false;
}
private PsiElement findDeclaration(PsiElement element, String type) {
if (!(element instanceof XmlAttributeValue)) {
return null;
}
JSObjectLiteralExpression exports = WeexFileUtil.getExportsStatement(element);
if (exports == null) {
return null;
} else {
String valueName = CodeUtil.getVarNameFromMustache(((XmlAttributeValue) element).getValue());
if ("function".equals(type)) {
return WeexFileUtil.getFunctionDeclaration(value, valueName);
} else {
return WeexFileUtil.getVarDeclaration(value, valueName);
}
}
}
private List<PsiElement> findEndpoints(Module module, Predicate<String> uriCondition, Predicate<XmlTag> tagCondition) {
Predicate<XmlAttributeValue> endpointMatcher =
((Predicate<XmlAttributeValue>)this::isEndpointUriValue)
.and(e -> parentTagMatches(e, tagCondition))
.and(e -> uriCondition.test(e.getValue()));
List<PsiElement> endpointDeclarations = new ArrayList<>();
IdeaUtils.getService().iterateXmlDocumentRoots(module, root -> {
if (isAcceptedNamespace(root.getNamespace())) {
IdeaUtils.getService().iterateXmlNodes(root, XmlAttributeValue.class, value -> {
if (endpointMatcher.test(value)) {
endpointDeclarations.add(value);
}
return true;
});
}
});
return endpointDeclarations;
}
@Override
public boolean isPlaceForEndpointUri(PsiElement location) {
XmlFile file = PsiTreeUtil.getParentOfType(location, XmlFile.class);
if (file == null || file.getRootTag() == null || !isAcceptedNamespace(file.getRootTag().getNamespace())) {
return false;
}
XmlAttributeValue value = PsiTreeUtil.getParentOfType(location, XmlAttributeValue.class, false);
if (value == null) {
return false;
}
XmlAttribute attr = PsiTreeUtil.getParentOfType(location, XmlAttribute.class);
if (attr == null) {
return false;
}
return attr.getLocalName().equals("uri") && isInsideCamelRoute(location, false);
}
@Override
public Optional<String> extractTextFromElement(PsiElement element, boolean concatString, boolean stripWhitespace) {
// maybe its xml then try that
if (element instanceof XmlAttributeValue) {
return Optional.ofNullable(((XmlAttributeValue) element).getValue());
} else if (element instanceof XmlText) {
return Optional.ofNullable(((XmlText) element).getValue());
} else if (element instanceof XmlToken) {
// it may be a token which is a part of an combined attribute
if (concatString) {
XmlAttributeValue xml = PsiTreeUtil.getParentOfType(element, XmlAttributeValue.class);
if (xml != null) {
return Optional.ofNullable(getInnerText(xml.getValue()));
}
} else {
String returnText = element.getText();
final PsiElement prevSibling = element.getPrevSibling();
if (prevSibling != null && prevSibling.getText().equalsIgnoreCase("&")) {
returnText = prevSibling.getText() + returnText;
}
return Optional.ofNullable(getInnerText(returnText));
}
}
return Optional.empty();
}
/**
* Adjust the text range according to the type of ${@link PsiElement}
* @return a new text range
*/
private TextRange getAdjustedTextRange(@NotNull PsiElement element, TextRange range, String text, SimpleValidationResult result) {
if (element instanceof XmlAttributeValue) {
// we can use the xml range as-is
range = ((XmlAttributeValue) element).getValueTextRange();
} else if (getIdeaUtils().isJavaLanguage(element)) {
// all the programming languages need to have the offset adjusted by 1
range = TextRange.create(range.getStartOffset() + 1, range.getEndOffset());
}
//we need to calculate the correct start and end position to be sure we highlight the correct word
int startIdx = result.getIndex();
//test if the simple expression is closed correctly
int endIdx = text.indexOf("}", startIdx);
if (endIdx == -1) {
//the expression is not closed, test for first " " to see if can stop text range here
endIdx = text.indexOf(" ", startIdx) - 1;
}
//calc the end index for highlighted word
endIdx = endIdx < 0 ? range.getEndOffset() : (range.getStartOffset() + endIdx) + 1;
if (endIdx < startIdx) {
endIdx = range.getEndOffset();
}
range = TextRange.create(range.getStartOffset() + result.getIndex(), endIdx);
return range;
}
/**
* Adjust the text range according to the type of ${@link PsiElement}
* @return a new text range
*/
private TextRange getAdjustedTextRange(@NotNull PsiElement element, TextRange range, String text, LanguageValidationResult result) {
if (element instanceof XmlAttributeValue) {
// we can use the xml range as-is
range = ((XmlAttributeValue) element).getValueTextRange();
} else if (getIdeaUtils().isJavaLanguage(element)) {
// all the programming languages need to have the offset adjusted by 1
range = TextRange.create(range.getStartOffset() + 1, range.getEndOffset());
}
//we need to calculate the correct start and end position to be sure we highlight the correct word
int startIdx = result.getIndex();
//test if the simple expression is closed correctly
int endIdx = text.indexOf("}", startIdx);
if (endIdx == -1) {
//the expression is not closed, test for first " " to see if can stop text range here
endIdx = text.indexOf(" ", startIdx) - 1;
}
//calc the end index for highlighted word
endIdx = endIdx < 0 ? (range.getEndOffset() - 1) : (range.getStartOffset() + endIdx) + 1;
if (endIdx <= startIdx) {
endIdx = range.getEndOffset();
}
range = TextRange.create(range.getStartOffset() + result.getIndex(), endIdx);
return range;
}
/**
* If element at this location specifies a reference to a bean (e.g. a BeanInject annotation, bean property reference,
* etc.), returns the expected type of that bean
*/
public PsiType findExpectedBeanTypeAt(PsiElement location) {
PsiAnnotation annotation = PsiTreeUtil.getParentOfType(location, PsiAnnotation.class);
if (annotation != null) {
return IdeaUtils.getService().findAnnotatedElementType(annotation);
}
return Optional.ofNullable(PsiTreeUtil.getParentOfType(location, XmlAttributeValue.class, false))
.filter(e -> Arrays.stream(e.getReferences()).anyMatch(ref -> ref instanceof BeanReference))
.map(e -> PsiTreeUtil.getParentOfType(e, XmlTag.class))
.map(this::findPropertyNameReference)
.map(PropertyNameReference::resolve)
.map(target -> {
if (target instanceof PsiField) {
return ((PsiField) target).getType();
} else if (target instanceof PsiMethod) {
return ((PsiMethod) target).getParameterList().getParameters()[0].getType();
} else {
return null;
}
})
.orElse(null);
}
@Override
public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNull Collection<LineMarkerInfo> results) {
// we need project element; so get it from first item
if(psiElements.size() == 0) {
return;
}
Project project = psiElements.get(0).getProject();
if(!Symfony2ProjectComponent.isEnabled(project)) {
return;
}
for(PsiElement psiElement: psiElements) {
if(psiElement.getNode().getElementType() != XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) {
continue;
}
PsiElement xmlAttributeValue = psiElement.getParent();
if(xmlAttributeValue instanceof XmlAttributeValue && (DoctrineMetadataPattern.getXmlTargetDocumentClass().accepts(xmlAttributeValue) || DoctrineMetadataPattern.getXmlTargetEntityClass().accepts(xmlAttributeValue) || DoctrineMetadataPattern.getEmbeddableNameClassPattern().accepts(xmlAttributeValue))) {
attachXmlRelationMarker(psiElement, (XmlAttributeValue) xmlAttributeValue, results);
}
}
}
private void attachXmlRelationMarker(@NotNull PsiElement target, @NotNull XmlAttributeValue psiElement, @NotNull Collection<LineMarkerInfo> results) {
String value = psiElement.getValue();
if(StringUtils.isBlank(value)) {
return;
}
Collection<PhpClass> classesInterface = DoctrineMetadataUtil.getClassInsideScope(psiElement, value);
if(classesInterface.size() == 0) {
return;
}
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.DOCTRINE_LINE_MARKER).
setTargets(classesInterface).
setTooltipText("Navigate to class");
results.add(builder.createLineMarkerInfo(target));
}
@NotNull
public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) {
if(!Symfony2ProjectComponent.isEnabled(holder.getProject())) {
return super.buildVisitor(holder, isOnTheFly);
}
return new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(element instanceof XmlAttributeValue) {
registerAttributeRequirementProblem(holder, (XmlAttributeValue) element, "_method");
registerAttributeRequirementProblem(holder, (XmlAttributeValue) element, "_scheme");
} else if(element instanceof XmlAttribute) {
registerRoutePatternProblem(holder, (XmlAttribute) element);
} else if(element instanceof YAMLKeyValue) {
registerYmlRoutePatternProblem(holder, (YAMLKeyValue) element);
}
super.visitElement(element);
}
};
}
private void registerAttributeRequirementProblem(@NotNull ProblemsHolder holder, @NotNull XmlAttributeValue xmlAttributeValue, @NotNull final String requirementAttribute) {
if(!xmlAttributeValue.getValue().equals(requirementAttribute)) {
return;
}
XmlAttribute xmlAttributeKey = PsiElementAssertUtil.getParentOfTypeWithNameOrNull(xmlAttributeValue, XmlAttribute.class, "key");
if(xmlAttributeKey != null) {
XmlTag xmlTagDefault = PsiElementAssertUtil.getParentOfTypeWithNameOrNull(xmlAttributeKey, XmlTag.class, "requirement");
if(xmlTagDefault != null) {
XmlTag xmlTagRoute = PsiElementAssertUtil.getParentOfTypeWithNameOrNull(xmlTagDefault, XmlTag.class, "route");
if(xmlTagRoute != null) {
// attach to attribute token only we dont want " or ' char included
PsiElement target = findAttributeValueToken(xmlAttributeValue, requirementAttribute);
holder.registerProblem(target != null ? target : xmlAttributeValue, String.format("The '%s' requirement is deprecated", requirementAttribute), ProblemHighlightType.LIKE_DEPRECATED);
}
}
}
}
@NotNull
@Override
public Collection<LookupElement> getLookupElements() {
PsiElement parent = getElement().getParent();
if(!(parent instanceof XmlAttributeValue)) {
return Collections.emptyList();
}
Collection<PhpClass> phpClasses = new ArrayList<>();
ContainerUtil.addIfNotNull(phpClasses, XmlHelper.getPhpClassForClassFactory((XmlAttributeValue) parent));
ContainerUtil.addIfNotNull(phpClasses, XmlHelper.getPhpClassForServiceFactory((XmlAttributeValue) parent));
Collection<LookupElement> lookupElements = new ArrayList<>();
for (PhpClass phpClass : phpClasses) {
lookupElements.addAll(PhpElementsUtil.getClassPublicMethod(phpClass).stream()
.map(PhpLookupElement::new)
.collect(Collectors.toList())
);
}
return lookupElements;
}
/**
* @see XmlHelper#visitServiceCallArgumentMethodIndex
*/
public void testVisitServiceCallArgument() {
myFixture.configureByText(XmlFileType.INSTANCE, "" +
"<service class=\"Foo\\Bar\">\n" +
" <call method=\"setBar\">\n" +
" <argument/>\n" +
" <argument type=\"service\" id=\"ma<caret>iler\" />\n" +
" </call>\n" +
"</service>"
);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
PsiElement parent = psiElement.getParent();
Collection<String> results = new ArrayList<>();
XmlHelper.visitServiceCallArgument((XmlAttributeValue) parent, visitor ->
results.add(visitor.getClassName() + ":" + visitor.getMethod() + ":" + visitor.getParameterIndex())
);
assertContainsElements(results, "Foo\\Bar:setBar:1");
}
/**
* @see XmlHelper#visitServiceCallArgumentMethodIndex
*/
public void testVisitServiceCallArgumentParameter() {
myFixture.configureByText(XmlFileType.INSTANCE, "" +
"<service class=\"Foo\\Bar\">\n" +
" <call method=\"setBar\">\n" +
" <argument/>\n" +
" <argument type=\"service\" id=\"ma<caret>iler\" />\n" +
" </call>\n" +
"</service>"
);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
PsiElement parent = psiElement.getParent();
Collection<Parameter> results = new ArrayList<>();
XmlHelper.visitServiceCallArgumentMethodIndex((XmlAttributeValue) parent, results::add);
assertNotNull(
ContainerUtil.find(results, parameter -> "arg2".equals(parameter.getName()))
);
}
public void testCanFindDefinitionElements() {
assertSize(2, TranslationUtil.findDefinitionElements(myFixture.getProject(), "LLL:EXT:foo/sample.xlf:sys_language.language_isocode.ab"));
assertSize(1, TranslationUtil.findDefinitionElements(myFixture.getProject(), "LLL:EXT:foo/de.sample.xlf:sys_language.language_isocode.ab"));
PsiElement[] definitionElements = TranslationUtil.findDefinitionElements(myFixture.getProject(), "LLL:EXT:foo/sample.xlf:sys_language.language_isocode.ab");
for (PsiElement definitionElement : definitionElements) {
assertInstanceOf(definitionElement, XmlAttributeValue.class);
}
}
@Override
public void visitXmlTag(XmlTag tag) {
if (tag.getName().equals("f:alias")) {
XmlAttribute map = tag.getAttribute("map");
if (map != null) {
XmlAttributeValue valueElement = map.getValueElement();
if (valueElement != null) {
TextRange valueTextRange = valueElement.getValueTextRange();
PsiElement fluidElement = extractLanguagePsiElementForElementAtPosition(FluidLanguage.INSTANCE, tag, valueTextRange.getStartOffset() + 1);
FluidArrayCreationExpr fluidArray = (FluidArrayCreationExpr) PsiTreeUtil.findFirstParent(fluidElement, x -> x instanceof FluidArrayCreationExpr);
if (fluidArray != null) {
fluidArray.getArrayKeyList().forEach(fluidArrayKey -> {
if (fluidArrayKey.getFirstChild() instanceof FluidStringLiteral) {
String key = ((FluidStringLiteral) fluidArrayKey.getFirstChild()).getContents();
variables.put(key, new FluidVariable(key));
return;
}
variables.put(fluidArrayKey.getText(), new FluidVariable(fluidArrayKey.getText()));
});
}
}
}
}
super.visitXmlTag(tag);
}
@Override
public void getLanguagesToInject(@NotNull PsiLanguageInjectionHost host,
@NotNull InjectedLanguagePlaces injectedLanguagePlaces) {
if (MuleConfigUtils.isMuleFile(host.getContainingFile())) {
if (host instanceof XmlAttributeValue) {
// Try to inject a language, somewhat abusing the lazy evaluation of predicates :(
for (Pair<String, String> language : languages) {
if (tryInjectLanguage(language.getFirst(), language.getSecond(), host, injectedLanguagePlaces)) {
break;
}
}
} else if (host instanceof XmlText) {
final XmlTag tag = ((XmlText) host).getParentTag();
if (tag != null) {
final QName tagName = MuleConfigUtils.getQName(tag);
if (tagName.equals(globalFunctions) || tagName.equals(expressionComponent) || tagName.equals(expressionTransformer)) {
final String scriptingName = MelLanguage.MEL_LANGUAGE_ID;
injectLanguage(host, injectedLanguagePlaces, scriptingName);
} else if (tagName.equals(scriptingScript)) {
final String engine = tag.getAttributeValue("engine");
if (engine != null) {
injectLanguage(host, injectedLanguagePlaces, StringUtil.capitalize(engine));
}
} else if (tagName.equals(dwSetPayload) || tagName.equals(dwSetProperty) || tagName.equals(dwSetVariable) || tagName.equals(dwSetSessionVar)) {
injectLanguage(host, injectedLanguagePlaces, WEAVE_LANGUAGE_ID);
}
}
}
}
}
private boolean isExpectedLocalName(@NotNull String langPrefix,
@NotNull PsiLanguageInjectionHost psiLanguageInjectionHost) {
final XmlAttributeValue attributeValue = (XmlAttributeValue) psiLanguageInjectionHost;
final String expressionText = attributeValue.getValue();
return expressionText.startsWith(getLanguagePrefix(langPrefix)) && expressionText.endsWith("]");
}
private void injectLanguage(String langPrefix, @NotNull String languageId,
@NotNull PsiLanguageInjectionHost host,
@NotNull InjectedLanguagePlaces injectedLanguagePlaces) {
// Find the required Language
final Language requiredLanguage = Language.findLanguageByID(languageId);
if (requiredLanguage == null) {
return;
}
final TextRange textRange = ((XmlAttributeValue) host).getValueTextRange();
final int length = getLanguagePrefix(langPrefix).length() + 1;
final TextRange expressionTextRange = TextRange.from(length, textRange.getLength() - length);
injectedLanguagePlaces.addPlace(requiredLanguage, expressionTextRange, null, null);
}
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
if (element instanceof XmlAttributeValue && !isMelExpression((XmlAttributeValue) element)) {
final XmlAttributeValue attribute = (XmlAttributeValue) element;
return new PsiReference[]{new FlowRefPsiReference(attribute)};
}
return PsiReference.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
if (element instanceof XmlAttributeValue) {
final XmlAttributeValue attribute = (XmlAttributeValue) element;
return new PsiReference[]{new ConfigRefPsiReference(attribute)};
}
return PsiReference.EMPTY_ARRAY;
}
private void performInsert(XmlAttributeValue value, InsertionContext insertionContext, LookupElement lookupElement) {
if (value.getText().startsWith("\"")) {
insertionContext.getDocument().replaceString(
value.getTextOffset(),
value.getTextOffset() + getTailLength(value) + lookupElement.getLookupString().length(),
lookupElement.getLookupString());
} else {
insertionContext.getDocument().replaceString(
value.getTextOffset() - 1,
value.getTextOffset() + getTailLength(value) + lookupElement.getLookupString().length() - 1,
"\"" + lookupElement.getLookupString() + "\"");
}
}
private int getTailLength(XmlAttributeValue value) {
String[] temp = value.getValue().split(CompletionInitializationContext.DUMMY_IDENTIFIER);
if (temp.length == 2) {
return temp[1].length();
}
return 0;
}
private boolean available(PsiElement element) {
PsiElement context = element.getContext();
return context instanceof JSBlockStatement
|| context instanceof CssDeclaration
|| context instanceof XmlAttributeValue
|| context instanceof XmlText;
}
private boolean guessFunction(PsiElement element) {
if (element.getContext() instanceof XmlAttributeValue) {
try {
XmlAttributeValue value = (XmlAttributeValue) element.getContext();
return ((XmlAttribute) value.getContext()).getName().startsWith("on");
} catch (Exception e) {
return false;
}
}
return element.getContext() instanceof JSBlockStatement;
}
private ReferencedClass findReferencedClass(XmlAttributeValue element) {
JavaClassReference ref = JavaClassUtils.getService().findClassReference(element);
if (ref != null) {
return new ReferencedClass(element.getValue(), ref);
}
return null;
}