package com.intellij.lang.javascript.uml.actions; import com.intellij.lang.javascript.DialectDetector; import com.intellij.lang.javascript.JSBundle; import com.intellij.lang.javascript.JavaScriptSupportLoader; import com.intellij.lang.javascript.parsing.JavaScriptParserBase; import com.intellij.lang.javascript.psi.JSElementFactory; import com.intellij.lang.javascript.psi.JSExpressionCodeFragment; import com.intellij.lang.javascript.psi.ecmal4.JSAttributeList; import com.intellij.lang.javascript.psi.ecmal4.JSClass; import com.intellij.lang.javascript.refactoring.ui.JSEditorTextField; import com.intellij.lang.javascript.refactoring.ui.JSReferenceEditor; import com.intellij.lang.javascript.refactoring.ui.JSVisibilityPanel; import com.intellij.lang.javascript.refactoring.util.JSRefactoringUtil; import com.intellij.openapi.editor.Document; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiCodeFragment; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.ui.EditorTextField; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; public class JSCreateFieldDialog extends DialogWrapper { private JSReferenceEditor myTypeField; private JLabel myTypeLabel; private EditorTextField myNameField; private JCheckBox myDeclareStaticCb; private JPanel myContentPane; private JSVisibilityPanel myVisibilityPanel; private JLabel myNameLabel; private EditorTextField myInitializerField; private JLabel myInitializerLabel; private JCheckBox myDeclareConstantCb; private final JSClass myTargetClass; private static boolean ourDeclareConstant; private static boolean ourDeclareStatic; public JSCreateFieldDialog(JSClass clazz) { super(clazz.getProject(), true); myTargetClass = clazz; setTitle(JSBundle.message("create.field.dialog.title")); myVisibilityPanel.configureOptions(false, false, DialectDetector.dialectOfElement(clazz)); myVisibilityPanel.setVisibility(JSAttributeList.AccessType.PRIVATE.name()); myTypeLabel.setLabelFor(myTypeField.getChildComponent()); myNameLabel.setLabelFor(myNameField); myInitializerLabel.setLabelFor(myInitializerField); myDeclareConstantCb.setSelected(ourDeclareConstant); myDeclareStaticCb.setSelected(ourDeclareStatic); init(); } private void createUIComponents() { Module module = ModuleUtilCore.findModuleForPsiElement(myTargetClass); GlobalSearchScope scope = getTypeFieldScope(module, myTargetClass.getProject()); myTypeField = createTypeField(myTargetClass.getProject(), scope); PsiCodeFragment initializerCodeFragment = createInitializerCodeFragment(myTargetClass); Document document = PsiDocumentManager.getInstance(myTargetClass.getProject()).getDocument(initializerCodeFragment); myInitializerField = new JSEditorTextField(myTargetClass.getProject(), document); } public static GlobalSearchScope getTypeFieldScope(@Nullable Module module, @NotNull Project project) { return module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : GlobalSearchScope.allScope(project); } public static JSReferenceEditor createTypeField(Project project, GlobalSearchScope scope) { return JSReferenceEditor.forClassName("", project, "JSCreateFieldDialog", scope, JavaScriptParserBase.ForceContext.Type, null, JSBundle.message("choose.field.type")); } public static JSExpressionCodeFragment createInitializerCodeFragment(JSClass c) { return JSElementFactory.createExpressionCodeFragment(c.getProject(), "", c, JavaScriptSupportLoader.ECMA_SCRIPT_L4, c.getResolveScope(), JSElementFactory.TopLevelCompletion.LITERAL_VALUES, null); } @Override protected JComponent createCenterPanel() { return myContentPane; } @Override public JComponent getPreferredFocusedComponent() { return myTypeField.getChildComponent(); } public String getFieldName() { return myNameField.getText(); } public String getFieldType() { return myTypeField.getText(); } public boolean isStatic() { return myDeclareStaticCb.isSelected(); } public String getVisibility() { return myVisibilityPanel.getVisibility(); } /** * @return pair(message, isFatal) */ @Nullable private Pair<String, Boolean> validateData() { if (!JSRefactoringUtil.isValidIdentifier(getFieldName(), myTargetClass.getProject())) { return Pair.create(JSBundle.message("invalid.identifier.value.0", getFieldName()), true); } String type = getFieldType().trim(); if ("void".equals(type) || type.contains(" ") || JSRefactoringUtil.createTypeElement(myTargetClass.getProject(), type, JavaScriptSupportLoader.ECMA_SCRIPT_L4) == null) { return Pair.create(JSBundle.message("invalid.field.type.expression", type), true); } if (isConstant() && StringUtil.isEmpty(getInitializer())) { return Pair.create(JSBundle.message("field.initializer.is.not.specified"), true); } if (!JSRefactoringUtil.isResolvableType(type, myTargetClass, false, false)) { return Pair.create(JSBundle.message("type.is.not.resolved", type), false); } if (myTargetClass.findFieldByName(getFieldName()) != null) { return Pair.create(JSBundle.message("class.already.contains.field.warning", myTargetClass.getQualifiedName(), getFieldName()), false); } return null; } public boolean isConstant() { return myDeclareConstantCb.isSelected(); } public String getInitializer() { return myInitializerField.getText(); } @Override protected String getDimensionServiceKey() { return "JSCreateFieldDialog"; } @Override protected void doOKAction() { Pair<String, Boolean> errorStatus = validateData(); if (errorStatus != null) { if (errorStatus.second) { Messages.showErrorDialog(myContentPane, errorStatus.first, getTitle()); return; } else { if (Messages.showYesNoDialog(myContentPane, errorStatus.first, getTitle(), Messages.getQuestionIcon()) != Messages.YES) { return; } } } myTypeField.updateRecents(); //noinspection AssignmentToStaticFieldFromInstanceMethod ourDeclareConstant = myDeclareConstantCb.isSelected(); //noinspection AssignmentToStaticFieldFromInstanceMethod ourDeclareStatic = myDeclareStaticCb.isSelected(); super.doOKAction(); } }