package com.intellij.lang.javascript.uml.actions; import com.intellij.lang.javascript.JSBundle; import com.intellij.lang.javascript.JavaScriptSupportLoader; import com.intellij.lang.javascript.psi.JSElementFactory; import com.intellij.lang.javascript.psi.JSFile; import com.intellij.lang.javascript.psi.JSFunction; import com.intellij.lang.javascript.psi.ecmal4.JSAttributeList; import com.intellij.lang.javascript.psi.ecmal4.JSClass; import com.intellij.lang.javascript.psi.resolve.JSInheritanceUtil; import com.intellij.lang.javascript.refactoring.changeSignature.JSChangeSignatureDialog; import com.intellij.lang.javascript.refactoring.changeSignature.JSChangeSignatureProcessor; import com.intellij.openapi.ui.Messages; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; public class JSCreateMethodDialog extends JSChangeSignatureDialog { private CreateAction myCreateAction; private final JSClass myTargetClass; private JCheckBox myStaticCb; public JSCreateMethodDialog(final JSClass targetClass, final JSFunction method, boolean forceConstructor) { super(method, forceConstructor, method); myTargetClass = targetClass; setTitle(JSBundle.message(forceConstructor ? "create.constructor.dialog.title" : "create.method.dialog.title")); } static JSFunction createFakeMethod(JSClass clazz, String text, boolean inClass) { if (inClass) { JSFile file = JSElementFactory.createExpressionCodeFragment(clazz.getProject(), (clazz.isInterface() ? "interface" : "class") + " Dummy {" + text + "}", clazz, JavaScriptSupportLoader.ECMA_SCRIPT_L4, null, JSElementFactory.TopLevelCompletion.NO, null); JSClass aClass = PsiTreeUtil.findChildOfType(file, JSClass.class); return aClass.getFunctions()[0]; } else { JSFile file = JSElementFactory.createExpressionCodeFragment(clazz.getProject(), text, clazz, JavaScriptSupportLoader.ECMA_SCRIPT_L4, null, JSElementFactory.TopLevelCompletion.NO, null); return PsiTreeUtil.findChildOfType(file, JSFunction.class); } } @Override protected String getDefaultValueColumnTitle() { return null; } @Override protected void createDefaultActions() { super.createDefaultActions(); myCreateAction = new CreateAction(); } @NotNull @Override protected Action[] createActions() { return new Action[]{myCreateAction, getCancelAction()}; } @Override protected boolean hasPreviewButton() { return false; } @Override protected void invokeRefactoring(BaseRefactoringProcessor processor) { close(OK_EXIT_CODE); } @Override protected JSChangeSignatureProcessor createRefactoringProcessor() { return null; // ignore } @Override public String getMethodName() { return super.getMethodName(); } public String getReturnTypeText() { return myReturnTypeCodeFragment != null ? myReturnTypeCodeFragment.getText() : ""; } @Override protected String getHelpId() { return null; } @Override protected String validateAndCommitData() { String error = super.validateAndCommitData(); if (error != null) { return error; } JSFunction existingMethod = JSInheritanceUtil.findMethodInClass(createMethod(), myTargetClass, true); if (existingMethod != null && existingMethod.getAttributeList().hasModifier(JSAttributeList.ModifierType.STATIC) == (myStaticCb != null && myStaticCb.isSelected())) { boolean contains = existingMethod.getParent() == myTargetClass; String message = JSBundle.message("class.already.contains.method.warning", myTargetClass.getQualifiedName(), Integer.valueOf(contains ? 1 : 2), getMethodName()); if (Messages.showYesNoDialog(myProject, message, getTitle(), Messages.getQuestionIcon()) != Messages.YES) { return EXIT_SILENTLY; } } return null; } @Override protected String calculateModifiers() { String result = super.calculateModifiers(); if (myStaticCb != null && myStaticCb.isSelected()) { result += " static "; } return result; } public JSFunction createMethod() { String methodText = calculateSignature() + (myTargetClass.isInterface() ? ";" : "{}"); return createFakeMethod(myTargetClass, methodText, true); } @Override protected JPanel createVisibilityPanel() { JPanel visibilityPanel = super.createVisibilityPanel(); if (myMethod.isConstructor()) { return visibilityPanel; } JPanel panel = new JPanel(new BorderLayout()); panel.add(visibilityPanel, BorderLayout.NORTH); myStaticCb = new JCheckBox(JSBundle.message("declare.static")); myStaticCb.addChangeListener(new ChangeListener() { @Override public void stateChanged(final ChangeEvent e) { updateSignature(); } }); panel.add(myStaticCb, BorderLayout.SOUTH); return panel; } private class CreateAction extends AbstractAction { public CreateAction() { putValue(NAME, JSBundle.message("create.button.text")); putValue(DEFAULT_ACTION, Boolean.TRUE); } @Override public void actionPerformed(ActionEvent e) { doOKAction(); } } }