package com.jetbrains.lang.dart.ide.runner.server; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.actions.RunConfigurationProducer; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import com.jetbrains.lang.dart.ide.DartWritingAccessProvider; import com.jetbrains.lang.dart.ide.runner.test.DartTestRunConfigurationProducer; import com.jetbrains.lang.dart.psi.DartFile; import com.jetbrains.lang.dart.psi.DartImportStatement; import com.jetbrains.lang.dart.util.DartResolveUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class DartCommandLineRuntimeConfigurationProducer extends RunConfigurationProducer<DartCommandLineRunConfiguration> { public DartCommandLineRuntimeConfigurationProducer() { super(DartCommandLineRunConfigurationType.getInstance()); } @Override protected boolean setupConfigurationFromContext(final @NotNull DartCommandLineRunConfiguration configuration, final @NotNull ConfigurationContext context, final @NotNull Ref<PsiElement> sourceElement) { final VirtualFile dartFile = getRunnableDartFileFromContext(context, true); if (dartFile == null || DartTestRunConfigurationProducer.isFileInTestDirAndTestPackageExists(context.getProject(), dartFile)) { return false; } configuration.getRunnerParameters().setFilePath(dartFile.getPath()); configuration.getRunnerParameters() .setWorkingDirectory(DartCommandLineRunnerParameters.suggestDartWorkingDir(context.getProject(), dartFile)); configuration.setGeneratedName(); sourceElement.set(sourceElement.isNull() ? null : sourceElement.get().getContainingFile()); return true; } @Override public boolean isConfigurationFromContext(final @NotNull DartCommandLineRunConfiguration configuration, final @NotNull ConfigurationContext context) { final VirtualFile dartFile = getDartFileFromContext(context); return dartFile != null && dartFile.getPath().equals(configuration.getRunnerParameters().getFilePath()); } @Nullable public static VirtualFile getRunnableDartFileFromContext(@NotNull final ConfigurationContext context, final boolean checkBrowserSpecificImports) { final PsiElement psiLocation = context.getPsiLocation(); final PsiFile psiFile = psiLocation == null ? null : psiLocation.getContainingFile(); final VirtualFile virtualFile = DartResolveUtil.getRealVirtualFile(psiFile); if (psiFile instanceof DartFile && virtualFile != null && ProjectRootManager.getInstance(context.getProject()).getFileIndex().isInContent(virtualFile) && !DartWritingAccessProvider.isInDartSdkOrDartPackagesFolder(psiFile.getProject(), virtualFile) && DartResolveUtil.getMainFunction(psiFile) != null && (!checkBrowserSpecificImports || !hasImport((DartFile)psiFile, "dart:html", "dart:html_common", "dart:indexed_db", "dart:js", "dart:svg", "dart:web_audio", "dart:web_gl", "dart:web_sql"))) { return virtualFile; } return null; } @Nullable private static VirtualFile getDartFileFromContext(final @NotNull ConfigurationContext context) { final PsiElement psiLocation = context.getPsiLocation(); final PsiFile psiFile = psiLocation == null ? null : psiLocation.getContainingFile(); final VirtualFile virtualFile = DartResolveUtil.getRealVirtualFile(psiFile); return psiFile instanceof DartFile && virtualFile != null ? virtualFile : null; } private static boolean hasImport(final @NotNull DartFile psiFile, final @NotNull String... importTexts) { final DartImportStatement[] importStatements = PsiTreeUtil.getChildrenOfType(psiFile, DartImportStatement.class); if (importStatements == null) return false; for (DartImportStatement importStatement : importStatements) { if (ArrayUtil.contains(importStatement.getUriString(), importTexts)) return true; } return false; } }