Search in sources :

Example 1 with VariablesProcessor

use of com.intellij.psi.scope.processor.VariablesProcessor in project intellij-community by JetBrains.

the class GrChangeSignatureUsageProcessor method createDefaultValue.

@Nullable
private static GrExpression createDefaultValue(GroovyPsiElementFactory factory, JavaChangeInfo changeInfo, JavaParameterInfo info, final GrArgumentList list, PsiSubstitutor substitutor) {
    if (info.isUseAnySingleVariable()) {
        final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
        final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
        final VariablesProcessor processor = new VariablesProcessor(false) {

            @Override
            protected boolean check(PsiVariable var, ResolveState state) {
                if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField) var, list, null))
                    return false;
                if (var instanceof GrVariable && PsiUtil.isLocalVariable(var) && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) {
                    return false;
                }
                if (PsiTreeUtil.isAncestor(var, list, false))
                    return false;
                final PsiType _type = var instanceof GrVariable ? ((GrVariable) var).getTypeGroovy() : var.getType();
                final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(_type);
                return type.isAssignableFrom(varType);
            }

            @Override
            public boolean execute(@NotNull PsiElement pe, @NotNull ResolveState state) {
                super.execute(pe, state);
                return size() < 2;
            }
        };
        treeWalkUp(list, processor);
        if (processor.size() == 1) {
            final PsiVariable result = processor.getResult(0);
            return factory.createExpressionFromText(result.getName(), list);
        }
        if (processor.size() == 0) {
            final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class);
            if (parentClass != null) {
                PsiClass containingClass = parentClass;
                final Set<PsiClass> containingClasses = new HashSet<>();
                final PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(list.getProject());
                while (containingClass != null) {
                    if (type.isAssignableFrom(jfactory.createType(containingClass, PsiSubstitutor.EMPTY))) {
                        containingClasses.add(containingClass);
                    }
                    containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
                }
                if (containingClasses.size() == 1) {
                    return factory.createThisExpression(containingClasses.contains(parentClass) ? null : containingClasses.iterator().next());
                }
            }
        }
    }
    final PsiElement element = info.getActualValue(list.getParent(), substitutor);
    if (element instanceof GrExpression) {
        return (GrExpression) element;
    }
    final String value = info.getDefaultValue();
    return !StringUtil.isEmpty(value) ? factory.createExpressionFromText(value, list) : null;
}
Also used : VariablesProcessor(com.intellij.psi.scope.processor.VariablesProcessor) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) NotNull(org.jetbrains.annotations.NotNull) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) HashSet(com.intellij.util.containers.HashSet) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with VariablesProcessor

use of com.intellij.psi.scope.processor.VariablesProcessor in project intellij-community by JetBrains.

the class ReassignVariableUtil method reassign.

@VisibleForTesting
public static boolean reassign(final Editor editor) {
    final SmartPsiElementPointer<PsiDeclarationStatement> pointer = editor.getUserData(DECLARATION_KEY);
    final PsiDeclarationStatement declaration = pointer != null ? pointer.getElement() : null;
    final PsiType type = getVariableType(declaration);
    if (type != null) {
        VariablesProcessor proc = findVariablesOfType(declaration, type);
        if (proc.size() > 0) {
            List<PsiVariable> vars = new ArrayList<>();
            for (int i = 0; i < proc.size(); i++) {
                final PsiVariable variable = proc.getResult(i);
                PsiElement outerCodeBlock = PsiUtil.getVariableCodeBlock(variable, null);
                if (outerCodeBlock == null)
                    continue;
                if (ReferencesSearch.search(variable, new LocalSearchScope(outerCodeBlock)).forEach(reference -> {
                    final PsiElement element = reference.getElement();
                    if (element != null) {
                        return HighlightControlFlowUtil.getInnerClassVariableReferencedFrom(variable, element) == null;
                    }
                    return true;
                })) {
                    vars.add(variable);
                }
            }
            if (vars.isEmpty()) {
                return true;
            }
            if (vars.size() == 1) {
                replaceWithAssignment(declaration, proc.getResult(0), editor);
                return true;
            }
            final DefaultListModel<PsiVariable> model = new DefaultListModel<>();
            for (PsiVariable var : vars) {
                model.addElement(var);
            }
            final JBList list = new JBList(model);
            list.setCellRenderer(new ListCellRendererWrapper<PsiVariable>() {

                @Override
                public void customize(JList list, PsiVariable value, int index, boolean selected, boolean hasFocus) {
                    if (value != null) {
                        setText(value.getName());
                        setIcon(value.getIcon(0));
                    }
                }
            });
            final VisualPosition visualPosition = editor.getCaretModel().getVisualPosition();
            final Point point = editor.visualPositionToXY(new VisualPosition(visualPosition.line + 1, visualPosition.column));
            JBPopupFactory.getInstance().createListPopupBuilder(list).setTitle("Choose variable to reassign").setRequestFocus(true).setItemChoosenCallback(() -> replaceWithAssignment(declaration, (PsiVariable) list.getSelectedValue(), editor)).createPopup().show(new RelativePoint(editor.getContentComponent(), point));
        }
        return true;
    }
    return false;
}
Also used : LocalSearchScope(com.intellij.psi.search.LocalSearchScope) VariablesProcessor(com.intellij.psi.scope.processor.VariablesProcessor) ArrayList(java.util.ArrayList) RelativePoint(com.intellij.ui.awt.RelativePoint) RelativePoint(com.intellij.ui.awt.RelativePoint) RelativePoint(com.intellij.ui.awt.RelativePoint) JBList(com.intellij.ui.components.JBList) VisualPosition(com.intellij.openapi.editor.VisualPosition) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 3 with VariablesProcessor

use of com.intellij.psi.scope.processor.VariablesProcessor in project intellij-community by JetBrains.

the class ExtractMethodProcessor method getArtificialOutputVariable.

@Nullable
private PsiVariable getArtificialOutputVariable() {
    if (myOutputVariables.length == 0 && myExitStatements.isEmpty()) {
        if (myCanBeChainedConstructor) {
            final Set<PsiField> fields = new HashSet<>();
            for (PsiElement element : myElements) {
                element.accept(new JavaRecursiveElementWalkingVisitor() {

                    @Override
                    public void visitReferenceExpression(PsiReferenceExpression expression) {
                        super.visitReferenceExpression(expression);
                        final PsiElement resolve = expression.resolve();
                        if (resolve instanceof PsiField && ((PsiField) resolve).hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isAccessedForWriting(expression)) {
                            fields.add((PsiField) resolve);
                        }
                    }
                });
            }
            if (!fields.isEmpty()) {
                return fields.size() == 1 ? fields.iterator().next() : null;
            }
        }
        final VariablesProcessor processor = new VariablesProcessor(true) {

            @Override
            protected boolean check(PsiVariable var, ResolveState state) {
                return isDeclaredInside(var);
            }
        };
        PsiScopesUtil.treeWalkUp(processor, myElements[myElements.length - 1], myCodeFragmentMember);
        if (processor.size() == 1) {
            return processor.getResult(0);
        }
    }
    return null;
}
Also used : VariablesProcessor(com.intellij.psi.scope.processor.VariablesProcessor) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with VariablesProcessor

use of com.intellij.psi.scope.processor.VariablesProcessor in project intellij-community by JetBrains.

the class JavaVariableInplaceIntroducer method getAdvertisementText.

@Nullable
private static String getAdvertisementText(final PsiDeclarationStatement declaration, final PsiType type, final boolean hasTypeSuggestion) {
    final VariablesProcessor processor = ReassignVariableUtil.findVariablesOfType(declaration, type);
    final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
    if (processor.size() > 0) {
        final Shortcut[] shortcuts = keymap.getShortcuts("IntroduceVariable");
        if (shortcuts.length > 0) {
            return "Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to reassign existing variable";
        }
    }
    if (hasTypeSuggestion) {
        final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable");
        if (shortcuts.length > 0) {
            return "Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to change type";
        }
    }
    return null;
}
Also used : VariablesProcessor(com.intellij.psi.scope.processor.VariablesProcessor) Shortcut(com.intellij.openapi.actionSystem.Shortcut) Keymap(com.intellij.openapi.keymap.Keymap) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with VariablesProcessor

use of com.intellij.psi.scope.processor.VariablesProcessor in project intellij-community by JetBrains.

the class ReassignVariableUtil method findVariablesOfType.

static VariablesProcessor findVariablesOfType(final PsiDeclarationStatement declaration, final PsiType type) {
    VariablesProcessor proc = new VariablesProcessor(false) {

        @Override
        protected boolean check(PsiVariable var, ResolveState state) {
            for (PsiElement element : declaration.getDeclaredElements()) {
                if (element == var)
                    return false;
            }
            return TypeConversionUtil.isAssignable(var.getType(), type);
        }
    };
    PsiElement scope = declaration;
    while (scope != null) {
        if (scope instanceof PsiFile || scope instanceof PsiMethod || scope instanceof PsiLambdaExpression || scope instanceof PsiClassInitializer)
            break;
        scope = scope.getParent();
    }
    if (scope == null)
        return proc;
    PsiScopesUtil.treeWalkUp(proc, declaration, scope);
    return proc;
}
Also used : VariablesProcessor(com.intellij.psi.scope.processor.VariablesProcessor)

Aggregations

VariablesProcessor (com.intellij.psi.scope.processor.VariablesProcessor)7 Nullable (org.jetbrains.annotations.Nullable)4 HashSet (com.intellij.util.containers.HashSet)2 NotNull (org.jetbrains.annotations.NotNull)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Shortcut (com.intellij.openapi.actionSystem.Shortcut)1 VisualPosition (com.intellij.openapi.editor.VisualPosition)1 Keymap (com.intellij.openapi.keymap.Keymap)1 LocalSearchScope (com.intellij.psi.search.LocalSearchScope)1 RelativePoint (com.intellij.ui.awt.RelativePoint)1 JBList (com.intellij.ui.components.JBList)1 ArrayList (java.util.ArrayList)1 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)1 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)1 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)1