package com.wix.rt.build; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.*; import com.wix.rt.RTProjectComponent; import com.wix.rtk.cli.RTSettings; import com.wix.rt.settings.Settings; import com.wix.rtk.cli.RTRunner; import com.wix.rtk.cli.Result; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; public class RTFileListener { private final Project project; private final AtomicBoolean LISTENING = new AtomicBoolean(false); private RTFileVfsListener listener; private static final Logger LOG = Logger.getInstance(RTFileListener.class); public RTFileListener(@NotNull Project project) { this.project = project; } private void startListener() { if (LISTENING.compareAndSet(false, true)) ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { listener = new RTFileVfsListener(); VirtualFileManager.getInstance().addVirtualFileListener(listener, RTFileListener.this.project); // EditorEventMulticaster multicaster = EditorFactory.getInstance().getEventMulticaster(); // multicaster.addDocumentListener(new RTFileDocumentListener(), RTFileListener.this.project); } }); } }); } private void stopListener() { if (LISTENING.compareAndSet(true, false)) ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { VirtualFileManager.getInstance().removeVirtualFileListener(listener); // EditorEventMulticaster multicaster = EditorFactory.getInstance().getEventMulticaster(); // multicaster.addDocumentListener(new RTFileDocumentListener(), RTFileListener.this.project); } }); } }); } public static void start(@NotNull Project project) { RTFileListener listener = ServiceManager.getService(project, RTFileListener.class); listener.startListener(); } public static void stop(@NotNull Project project) { RTFileListener listener = ServiceManager.getService(project, RTFileListener.class); if (listener == null) { LOG.warn("failed to stop RTFileListener"); } else { listener.stopListener(); } } private void fileChanged(@NotNull VirtualFile file) { if ((RTFileUtil.isRTFile(file) || RTFileUtil.isJSRTFile(file)) && !project.isDisposed()) { // restartAnalyzer(); compile(file); } } private void compile(@NotNull final VirtualFile file) { compile(file, project); } public static void compile(@NotNull final VirtualFile file, @NotNull final Project project) { RTProjectComponent component = project.getComponent(RTProjectComponent.class); if (!component.shouldCompileRT()) { return; } Runnable runnable = new Runnable() { @Override public void run() { try { Settings settings = Settings.getInstance(project); RTSettings rtSettings = RTSettings.buildSettings(settings, project.getBasePath(), file.getPath()); Result out = RTRunner.build(rtSettings); } catch (Exception e1) { e1.printStackTrace(); // warn(project, e1.toString()); } } }; // ApplicationManager.getApplication().runWriteAction() ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { // final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); Task.Backgroundable task = new Task.Backgroundable(project, "Compile RT", true, PerformInBackgroundOption.ALWAYS_BACKGROUND) { @Override public void run(@NotNull ProgressIndicator indicator) { try { Settings settings = Settings.getInstance(project); RTSettings rtSettings = RTSettings.buildSettings(settings, project.getBasePath(), file.getPath()); Result out = RTRunner.build(rtSettings); file.getParent().refresh(false, false); } catch (Exception e1) { e1.printStackTrace(); // warn(project, e1.toString()); } } }; final ProgressIndicator indicator = new BackgroundableProcessIndicator(task); ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, indicator); } }); // ApplicationManager.getApplication().runWriteAction(); // if (ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, "compile rt", true, project)) { // file.getParent().refresh(false, false); // //// final DartListPackageDirsDialog dialog = new DartListPackageDirsDialog(project, packageNameToDirMap); //// dialog.show(); //// //// if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { //// configurePubListPackageDirsLibrary(project, affectedModules, packageNameToDirMap); //// } //// //// if (dialog.getExitCode() == DartListPackageDirsDialog.CONFIGURE_NONE_EXIT_CODE) { //// removePubListPackageDirsLibrary(project); //// } // } } private void restartAnalyzer() { RTProjectComponent component = project.getComponent(RTProjectComponent.class); if (component.isEnabled()) { DaemonCodeAnalyzer.getInstance(project).restart(); } } /** * VFS Listener */ private final class RTFileVfsListener extends VirtualFileAdapter { private RTFileVfsListener() { } public static final String NAME = "name"; public void fileCreated(@NotNull VirtualFileEvent event) { // System.out.println("fileCreated " + event.getFileName()); RTFileListener.this.fileChanged(event.getFile()); } public void fileDeleted(@NotNull VirtualFileEvent event) { // System.out.println("fileDeleted " + event.getFileName()); RTFileListener.this.fileChanged(event.getFile()); // VirtualFile file = event.getFile(); // if (RTFileUtil.isRTFile(file)) { //and file is rt with rt.js // VirtualFile jsFile = file.getParent().findChild(RTFileUtil.getJsRTFileName(file)); // if (jsFile != null) { // VfsLocationChangeDialog d = new VfsLocationChangeDialog(new LessProjectState()); // d.shouldDeleteCssFile(event); //// jsFile.rename(this, RTFileUtil.getJsRTFileName((String) event.getNewValue())); // } // } } public void fileMoved(@NotNull VirtualFileMoveEvent event) { // RTProjectComponent component = project.getComponent(RTProjectComponent.class); // component.vfsLocationChangeDialog.s // event. // System.out.println("fileMoved " + event.getFileName()); RTFileListener.this.fileChanged(event.getFile()); } public void fileCopied(@NotNull VirtualFileCopyEvent event) { // System.out.println("fileCopied " + event.getFileName()); RTFileListener.this.fileChanged(event.getFile()); // RTFileListener.this.fileChanged(event.getOriginalFile()); } @Override public void contentsChanged(@NotNull VirtualFileEvent event) { // System.out.println("contentsChanged " + event.getFileName()); RTFileListener.this.fileChanged(event.getFile()); } @Override public void propertyChanged(@NotNull VirtualFilePropertyEvent event) { // System.out.println("propertyChanged " + event.getFileName()); VirtualFile file = event.getFile(); if (event.getPropertyName().equals(NAME) && RTFileUtil.isRTFile(file)) { //and file is rt with rt.js VirtualFile jsFile = file.getParent().findChild(RTFileUtil.getJsRTFileName((String) event.getOldValue())); if (jsFile != null) { try { jsFile.rename(this, RTFileUtil.getJsRTFileName((String) event.getNewValue())); } catch (IOException e) { e.printStackTrace(); } } else { //try a .ts file jsFile = file.getParent().findChild(RTFileUtil.getTsRTFileName((String) event.getOldValue())); if (jsFile != null) { try { jsFile.rename(this, RTFileUtil.getTsRTFileName((String) event.getNewValue())); } catch (IOException e) { e.printStackTrace(); } } } } } } /** * Document Listener */ private final class RTFileDocumentListener extends DocumentAdapter { private RTFileDocumentListener() { } public void documentChanged(DocumentEvent event) { VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument()); if (file != null) { RTFileListener.this.fileChanged(file); } } } }