package com.jetbrains.lang.dart.psi.impl; import com.intellij.extapi.psi.ASTWrapperPsiElement; import com.intellij.lang.ASTNode; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.SearchScope; import com.intellij.psi.tree.IElementType; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.lang.dart.psi.*; import com.jetbrains.lang.dart.resolve.DartUseScope; import com.jetbrains.lang.dart.util.DartControlFlowUtil; import com.jetbrains.lang.dart.util.DartResolveUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Set; public class DartPsiCompositeElementImpl extends ASTWrapperPsiElement implements DartPsiCompositeElement { public DartPsiCompositeElementImpl(@NotNull ASTNode node) { super(node); } public IElementType getTokenType() { return getNode().getElementType(); } public String toString() { return getTokenType().toString(); } @NotNull @Override public SearchScope getUseScope() { final VirtualFile file = DartResolveUtil.getRealVirtualFile(getContainingFile()); if (file == null || !ProjectRootManager.getInstance(getProject()).getFileIndex().isInContent(file)) { return super.getUseScope(); } return new DartUseScope(getProject(), file); } @Override public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) { return processDeclarationsImpl(this, processor, state, lastParent) && super.processDeclarations(processor, state, lastParent, place); } public static boolean processDeclarationsImpl(@Nullable PsiElement context, PsiScopeProcessor processor, ResolveState state, @Nullable PsiElement lastParent) { if (context == null) { return true; } for (DartComponentName element : getDeclarationElementToProcess(context, lastParent)) { if (!processor.execute(element, state)) { return false; } } return true; } private static Set<DartComponentName> getDeclarationElementToProcess(@NotNull PsiElement context, @Nullable PsiElement lastParent) { final PsiElement[] children = context.getChildren(); final Set<DartComponentName> result = DartControlFlowUtil.getSimpleDeclarations(children, lastParent, context instanceof DartStatements); for (PsiElement child : children) { if (child instanceof DartFormalParameterList) { final DartFormalParameterList formalParameterList = (DartFormalParameterList)child; final List<DartNormalFormalParameter> normalFormalParameterList = formalParameterList.getNormalFormalParameterList(); final DartOptionalFormalParameters optionalFormalParameters = formalParameterList.getOptionalFormalParameters(); if (optionalFormalParameters != null) { normalFormalParameterList.addAll( ContainerUtil.map(optionalFormalParameters.getDefaultFormalNamedParameterList(), DartDefaultFormalNamedParameter::getNormalFormalParameter) ); } for (DartNormalFormalParameter parameter : normalFormalParameterList) { final DartComponentName componentName = parameter.findComponentName(); if (componentName != null) { result.add(componentName); } } } if (child instanceof DartTypeParameters) { for (DartTypeParameter typeParameter : ((DartTypeParameters)child).getTypeParameterList()) { result.add(typeParameter.getComponentName()); } } if (child instanceof DartImportStatement) { ContainerUtil.addIfNotNull(result, ((DartImportStatement)child).getImportPrefix()); } if (child instanceof DartCatchPart) { result.addAll(((DartCatchPart)child).getComponentNameList()); } } if (context instanceof DartForStatement) { final DartForLoopPartsInBraces loopPartsInBraces = ((DartForStatement)context).getForLoopPartsInBraces(); final DartForLoopParts loopParts = loopPartsInBraces == null ? null : loopPartsInBraces.getForLoopParts(); final DartForInPart forInPart = loopParts == null ? null : loopParts.getForInPart(); final DartComponentName componentName = forInPart == null ? null : forInPart.getComponentName(); if (componentName != null) { result.add(componentName); } final DartVarAccessDeclaration varDeclaration = forInPart == null ? null : forInPart.getVarAccessDeclaration(); if (varDeclaration != null) { result.add(varDeclaration.getComponentName()); } final DartVarDeclarationList varDeclarationList = loopParts == null ? null : loopParts.getVarDeclarationList(); if (varDeclarationList != null) { DartControlFlowUtil.addFromVarDeclarationList(result, varDeclarationList); } } return result; } }