package com.intellij.lang.javascript.validation.fixes; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.ide.util.PlatformPackageUtil; import com.intellij.lang.LanguageNamesValidation; import com.intellij.lang.javascript.JavaScriptSupportLoader; import com.intellij.lang.javascript.refactoring.util.JSRefactoringUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class CreateMxmlFileIntentionBase implements CreateClassIntentionWithCallback { protected PsiElement myElement; protected String myPackageName; protected String myClassName; private boolean myIdentifierIsValid; private Consumer<String> myCreatedClassFqnConsumer; public CreateMxmlFileIntentionBase(final String classFqn, final @NotNull PsiElement element) { myElement = element; myClassName = StringUtil.getShortName(classFqn); myIdentifierIsValid = LanguageNamesValidation.INSTANCE.forLanguage(JavaScriptSupportLoader.JAVASCRIPT.getLanguage()).isIdentifier(myClassName, null); myPackageName = StringUtil.getPackageName(classFqn); } @NotNull public String getFamilyName() { return CodeInsightBundle.message("create.file.family"); } public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) { return myIdentifierIsValid && myElement.isValid(); } public void setCreatedClassFqnConsumer(final Consumer<String> consumer) { myCreatedClassFqnConsumer = consumer; } @NotNull public String getName() { return getText(); } public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { invoke(project, null, myElement.getContainingFile()); } public void invoke(@NotNull final Project project, final @Nullable Editor editor, final PsiFile file) throws IncorrectOperationException { final Module module = ModuleUtil.findModuleForPsiElement(file); if (module == null) { return; } final Pair<String, PsiDirectory> fileTextAndDir = getFileTextAndDir(module); if (fileTextAndDir.first == null || fileTextAndDir.second == null) { return; } ApplicationManager.getApplication().runWriteAction(() -> { try { final String fileName = myClassName + JavaScriptSupportLoader.MXML_FILE_EXTENSION_DOT; final PsiFile newFile = fileTextAndDir.second.createFile(fileName); final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); final Document document = psiDocumentManager.getDocument(newFile); document.setText(fileTextAndDir.first); psiDocumentManager.commitDocument(document); CodeStyleManager.getInstance(project).reformat(newFile); FileEditorManager.getInstance(project).openFile(newFile.getVirtualFile(), true); if (myCreatedClassFqnConsumer != null) { final String packageName = ProjectRootManager.getInstance(project).getFileIndex().getPackageNameByDirectory( fileTextAndDir.second.getVirtualFile()); myCreatedClassFqnConsumer.consume(packageName + (packageName.isEmpty() ? "" : ".") + myClassName); } } catch (IncorrectOperationException e) { Messages.showErrorDialog(project, e.getMessage(), getText()); } }); } protected Pair<String, PsiDirectory> getFileTextAndDir(final @NotNull Module module) { final PsiDirectory baseDir = myElement.getContainingFile().getParent(); final GlobalSearchScope scope = PlatformPackageUtil.adjustScope(baseDir, GlobalSearchScope.moduleWithDependenciesScope(module), false, true); final PsiDirectory psiDirectory = JSRefactoringUtil .chooseOrCreateDirectoryForClass(module.getProject(), module, scope, myPackageName, null, baseDir, ThreeState.UNSURE); return Pair.create(getFileText(), psiDirectory); } protected String getFileText() { return ""; } }