package org.angularjs.lang.psi; import com.intellij.lang.javascript.psi.impl.JSExpressionImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil; import org.angularjs.lang.parser.AngularJSElementTypes; import org.angularjs.lang.parser.AngularJSMessageFormatParser; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.List; /** * @author Irina.Chernushina on 12/2/2015. */ public class AngularJSMessageFormatExpression extends JSExpressionImpl { private static final Logger LOG = Logger.getInstance("#org.angularjs.lang.psi.AngularJSMessageFormatExpression"); public AngularJSMessageFormatExpression(IElementType elementType) { super(elementType); } @Override public void accept(@NotNull PsiElementVisitor visitor) { if (visitor instanceof AngularJSElementVisitor) { ((AngularJSElementVisitor)visitor).visitMessageFormatExpression(this); } else { super.accept(visitor); } } public AngularJSMessageFormatParser.ExtensionType getExtensionType() { final Ref<PsiElement> ref = new Ref<>(); PsiTreeUtil.processElements(this, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiElement element) { final boolean isExpressionName = element.getNode().getElementType() == AngularJSElementTypes.MESSAGE_FORMAT_EXPRESSION_NAME; ref.set(element); return !isExpressionName; } }); final PsiElement typeElement = getExtensionTypeElement(); if (typeElement == null) return null; try { return AngularJSMessageFormatParser.ExtensionType.valueOf(typeElement.getText()); } catch (IllegalArgumentException e) { return null; } } public PsiElement getExtensionTypeElement() { final Ref<PsiElement> ref = new Ref<>(); PsiTreeUtil.processElements(this, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiElement element) { final boolean isExpressionName = element.getNode().getElementType() == AngularJSElementTypes.MESSAGE_FORMAT_EXPRESSION_NAME; ref.set(element); return !isExpressionName; } }); if (ref.isNull()) { LOG.error("AngularJS message format expression does not have name"); return null; } else { return ref.get(); } } public PsiElement[] getOptions() { return ((CompositeElement)getNode()).getChildrenAsPsiElements(AngularJSElementTypes.MESSAGE_FORMAT_OPTION, PsiElement.ARRAY_FACTORY); } public List<PsiElement> getSelectionKeywordElements() { if (!(getNode() instanceof CompositeElement)) return Collections.emptyList(); final PsiElement[] selectionsKeywords = ((CompositeElement)getNode()).getChildrenAsPsiElements( AngularJSElementTypes.MESSAGE_FORMAT_SELECTION_KEYWORD, PsiElement.ARRAY_FACTORY); return ContainerUtil.filter(selectionsKeywords, element -> element.getNode().getElementType() == AngularJSElementTypes.MESSAGE_FORMAT_SELECTION_KEYWORD); } }