2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.jetbrains.python.refactoring.convertTopLevelFunction;
18 import com.intellij.openapi.actionSystem.CommonDataKeys;
19 import com.intellij.openapi.actionSystem.DataContext;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.editor.Editor;
22 import com.intellij.openapi.project.Project;
23 import com.intellij.psi.PsiElement;
24 import com.intellij.psi.PsiFile;
25 import com.intellij.psi.util.PsiTreeUtil;
26 import com.intellij.refactoring.RefactoringActionHandler;
27 import com.intellij.refactoring.RefactoringBundle;
28 import com.intellij.refactoring.util.CommonRefactoringUtil;
29 import com.intellij.util.IncorrectOperationException;
30 import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
31 import com.jetbrains.python.psi.PyFunction;
32 import com.jetbrains.python.psi.PyReferenceExpression;
33 import com.jetbrains.python.refactoring.PyBaseRefactoringAction;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
38 * @author Mikhail Golubev
40 public class PyConvertLocalFunctionToTopLevelFunctionAction extends PyBaseRefactoringAction {
41 public static final String ID = "py.make.function.top.level";
44 protected boolean isAvailableInEditorOnly() {
49 protected boolean isEnabledOnElementInsideEditor(@NotNull PsiElement element,
50 @NotNull Editor editor,
51 @NotNull PsiFile file,
52 @NotNull DataContext context) {
53 return findTargetFunction(element) != null;
57 protected boolean isEnabledOnElementsOutsideEditor(@NotNull PsiElement[] elements) {
62 private static PyFunction findTargetFunction(@NotNull PsiElement element) {
63 PyFunction result = null;
64 if (isLocalFunction(element)) {
65 result = (PyFunction)element;
68 final PyReferenceExpression refExpr = PsiTreeUtil.getParentOfType(element, PyReferenceExpression.class);
69 if (refExpr == null) {
72 final PsiElement resolved = refExpr.getReference().resolve();
73 if (isLocalFunction(resolved)) {
74 result = (PyFunction)resolved;
80 private static boolean isLocalFunction(@Nullable PsiElement resolved) {
81 if (resolved instanceof PyFunction && PsiTreeUtil.getParentOfType(resolved, ScopeOwner.class, true) instanceof PyFunction) {
89 protected RefactoringActionHandler getHandler(@NotNull DataContext dataContext) {
90 return new RefactoringActionHandler() {
92 public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
93 final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
94 if (element != null) {
95 final PyFunction function = findTargetFunction(element);
96 if (function != null) {
98 new PyMakeFunctionTopLevelProcessor(function, editor).run();
100 catch (IncorrectOperationException e) {
101 if (ApplicationManager.getApplication().isUnitTestMode()) {
104 CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.title"), e.getMessage(), ID, project);
111 public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
112 // should be called only from the editor