in tapestry/src/main/java/com/intellij/tapestry/intellij/lang/completion/TemplateCompletionContributor.java [36:180]
public TemplateCompletionContributor() {
extend(null, psiElement(), new CompletionProvider<>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
@NotNull ProcessingContext context,
@NotNull CompletionResultSet result) {
PsiElement psiElement = parameters.getPosition();
if (!(psiElement instanceof LeafPsiElement)) return;
PsiElement prev = psiElement.getPrevSibling();
if (prev != null && ".".equals(prev.getText())) return;
Module module = ModuleUtilCore.findModuleForPsiElement(psiElement);
// if this isn't a Tapestry module don't do anything
if (!TapestryUtils.isTapestryModule(module)) return;
if (psiElement instanceof XmlToken && ((XmlToken)psiElement).getTokenType().toString().equals("XML_ATTRIBUTE_VALUE_TOKEN")) {
// The selected attribute
XmlAttribute attribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class);
// The selected tag
XmlTag tag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class);
if (attribute == null) {
return;
}
// Completion of type and id attributes is handled by ComponentNameContextGetter
if (TapestryXmlExtension.isTapestryTemplateNamespace(attribute.getNamespace()) &&
(attribute.getLocalName().equals("type") ||
attribute.getLocalName().equals("id") ||
attribute.getLocalName().equals("mixins"))) {
return;
}
// Try to match the tag to a component
TapestryComponent component = TapestryUtils.getTypeOfTag(tag);
if (component == null) return;
TapestryProject tapestryProject = TapestryModuleSupportLoader.getTapestryProject(module);
if (tapestryProject == null) return;
final PresentationLibraryElement element = tapestryProject.findElementByTemplate(parameters.getOriginalFile());
if (element == null) return;
IntellijJavaClassType elementClass = (IntellijJavaClassType)element.getElementClass();
if (elementClass == null) return;
for (TapestryParameter parameter : component.getParameters().values()) {
String attributeValue = "";
if (tag != null) {
attributeValue = tag.getAttributeValue(attribute.getLocalName());
}
if (!parameter.getName().equalsIgnoreCase(attribute.getLocalName())) {
continue;
}
if (attributeValue != null) {
// Completion of all attribute values that starts with "prop:"
if (attributeValue.equals("prop:IntellijIdeaRulezzz ")) {
Set<String> properties = ClassUtils.getClassProperties(elementClass).keySet();
ArrayList<String> returnedProperties = new ArrayList<>();
for (String property : properties) {
returnedProperties.add("prop:" + property);
}
addVariants(result, returnedProperties);
return;
}
// Completion of composed properties
if (attributeValue.contains(".") &&
!attributeValue.contains("..") &&
(parameter.getDefaultPrefix().equals("prop") || attributeValue.startsWith("prop:"))) {
Set<String> properties;
if (attributeValue.contains("." + CompletionInitializationContext.DUMMY_IDENTIFIER)) {
String words = "";
try (Scanner scan = new Scanner(attributeValue)) {
String word = "";
while (scan.hasNext() && !word.contains(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED)) {
word = scan.next();
words += word;
}
}
attributeValue = words.replaceFirst(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED, "");
}
ResolvedValue resolvedValue;
try {
resolvedValue =
ValueResolverChain.getInstance().resolve(tapestryProject, elementClass, attributeValue, parameter.getDefaultPrefix());
}
catch (Exception ex) {
_logger.error(ex);
return;
}
if (resolvedValue != null && resolvedValue.getType() != null && resolvedValue.getType() instanceof IJavaClassType) {
elementClass =
new IntellijJavaClassType(module, ((IntellijJavaClassType)resolvedValue.getType()).getPsiClass().getContainingFile());
properties = ClassUtils.getClassProperties(elementClass).keySet();
ArrayList<String> returnedProperties = new ArrayList<>();
for (String property : properties) {
returnedProperties.add(attributeValue + property);
}
addVariants(result, returnedProperties);
return;
}
}
}
// Completion of boolean parameter
if (parameter.getParameterField().getType() != null) {
if (parameter.getParameterField().getType().getName().toLowerCase(Locale.getDefault()).equals("boolean")) {
Set<String> attributes = new HashSet<>(ClassUtils.getClassProperties(elementClass).keySet());
attributes.add("literal:true");
attributes.add("literal:false");
addVariants(result, attributes);
return;
}
}
// Completion of all attributes whose default prefix is "prop"
if (parameter.getDefaultPrefix().equals("prop")) {
addVariants(result, ClassUtils.getClassProperties(elementClass).keySet());
}
}
}
}
private void addVariants(@NotNull CompletionResultSet result, Collection<String> returnedProperties) {
for (String property : returnedProperties) {
result.addElement(LookupElementBuilder.create(property).withCaseSensitivity(false));
}
}
});
}