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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations