PyExpression (@NotNull final Project project, @NotNull PsiFile file, @NotNull final PsiElement element1, @NotNull final PsiElement element2) { PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2); if (parent != null && !(parent instanceof PyElement)) { parent = PsiTreeUtil.getParentOfType(parent, PyElement.class); } if (parent == null) { return null; } // If it is PyIfPart for example, parent if statement, we should deny if (!(parent instanceof PyExpression)){ return null; } // We cannot extract anything within import statements if (PsiTreeUtil.getParentOfType(parent, PyImportStatement.class, PyFromImportStatement.class) != null){ return null; } if ((element1 == PsiTreeUtil.getDeepestFirst(parent)) && (element2 == PsiTreeUtil.getDeepestLast(parent))) { return (PyExpression) parent; } // Check if selection breaks AST node in binary expression if (parent instanceof PyBinaryExpression) { final String selection = file.getText().substring(element1.getTextOffset(), element2.getTextOffset() + element2.getTextLength()); final PyElementGenerator generator = PyElementGenerator.getInstance(project); final LanguageLevel langLevel = LanguageLevel.forElement(element1); final PyExpression expression = generator.createFromText(langLevel, PyAssignmentStatement.class, "z=" + selection).getAssignedValue(); if (!(expression instanceof PyBinaryExpression) || PsiUtilCore.hasErrorElementChild(expression)) { return null; } final String parentText = parent.getText(); final int startOffset = element1.getTextOffset() - parent.getTextOffset() - 1; if (startOffset < 0) { return null; } final int endOffset = element2.getTextOffset() + element2.getTextLength() - parent.getTextOffset(); final String prefix = parentText.substring(0, startOffset); final String suffix = parentText.substring(endOffset); final TextRange textRange = TextRange.from(startOffset, endOffset - startOffset); final PsiElement fakeExpression = generator.createExpressionFromText(langLevel, prefix + "python" + suffix); if (PsiUtilCore.hasErrorElementChild(fakeExpression)) { return null; } expression.putUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE, Pair.create(parent, textRange)); return expression; } return null; }