/* * Copyright 2011-present Greg Shrago * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.intellij.jflex.psi.impl; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import org.intellij.jflex.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; /** * @author gregsh */ public class JFlexPsiImplUtil extends JavaRefHelper { @NotNull public static String getName(PsiNameIdentifierOwner o) { return ObjectUtils.assertNotNull(o.getNameIdentifier()).getText(); } @NotNull public static PsiNameIdentifierOwner setName(PsiNameIdentifierOwner o, String newName) { ObjectUtils.assertNotNull(o.getNameIdentifier()).replace(JFlexPsiElementFactory.createIdFromText(o.getProject(), newName)); return o; } @NotNull public static PsiElement getNameIdentifier(JFlexMacroDefinition o) { return o.getId(); } @NotNull public static PsiReference getReference(JFlexMacroReference o) { return new PsiReferenceBase<JFlexMacroReference>(o, TextRange.from(0, o.getTextRange().getLength())) { @Nullable @Override public PsiElement resolve() { final String name = getElement().getId().getText(); CommonProcessors.FindFirstProcessor<JFlexMacroDefinition> processor = new CommonProcessors.FindFirstProcessor<JFlexMacroDefinition>() { @Override protected boolean accept(JFlexMacroDefinition o) { return Comparing.equal(o.getName(), name); } }; processMacroVariants(getElement(), processor); return processor.getFoundValue(); } @NotNull @Override public Object[] getVariants() { CommonProcessors.CollectProcessor<JFlexMacroDefinition> processor = new CommonProcessors.CollectProcessor<>(); processMacroVariants(getElement(), processor); return ArrayUtil.toObjectArray(processor.getResults()); } @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { return getElement().getId().replace(JFlexPsiElementFactory.createIdFromText(getElement().getProject(), newElementName)); } }; } private static boolean processMacroVariants(PsiElement context, Processor<JFlexMacroDefinition> processor) { final PsiFile containingFile = context.getContainingFile(); List<JFlexMacroDefinition> macros = CachedValuesManager.getCachedValue( containingFile, () -> CachedValueProvider.Result.create(computeDefinitions(containingFile, JFlexMacroDefinition.class), containingFile)); return ContainerUtil.process(macros, processor); } public static <T> List<T> computeDefinitions(PsiFile psiFile, final Class<T> clazz) { final List<T> result = ContainerUtil.newArrayList(); psiFile.acceptChildren(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if (clazz.isInstance(element)) { result.add((T)element); } else if (!(element instanceof JFlexLexicalRulesSection) && !(element instanceof JFlexUserCodeSection)) { super.visitElement(element); } } }); return result; } @NotNull public static PsiElement getNameIdentifier(JFlexStateDefinition o) { return o.getId(); } @NotNull public static PsiReference getReference(JFlexStateReference o) { return new StateRef(o); } public static boolean isYYINITIAL(String s) { return "YYINITIAL".equals(s); } }