Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack Manager #457

Draft
wants to merge 77 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
d43b191
Stack framework support
carymrobbins Apr 19, 2019
b65b2c6
[stack-manager] Compiling and a simple PackageConfigTest
carymrobbins Jun 13, 2020
ae5cafe
[stack-manager] Don't parse a PackageConfig from a package.yaml
carymrobbins Jun 13, 2020
6fe4ec5
[stack-manager] Parse more fields into the PackageConfig
carymrobbins Jun 13, 2020
04d79a1
[stack-manager] Update StackProjectSettingsListener interface
carymrobbins Jun 15, 2020
fed8aae
[stack-manager] Initial StackProjectResolver.resolveProjectInfo
carymrobbins Jun 15, 2020
c0bb89d
[stack-manager] Fix minor compile issues
carymrobbins Jun 15, 2020
863eea5
[stack-manager] add 'depends' on externalSystem in plugin.xml
carymrobbins Jun 15, 2020
0fb1727
[stack-manager] Add StackIconProvider
carymrobbins Jun 15, 2020
5825065
[stack-manager] Move PackageConfig parsing out of StackProjectResolve…
carymrobbins Jun 16, 2020
a3b1c42
[stack-manager] Fix illegal read actions
carymrobbins Jun 16, 2020
28aa811
[stack-manager] Mostly working reimport
carymrobbins Jun 16, 2020
26f4e1f
[stack-manager] Cleaning up the module hierarchy (incomplete)
carymrobbins Jun 16, 2020
c8d9d90
[stack-manager] Remove 'ImplicitLibrary' from 'CabalQuery'
carymrobbins Jun 16, 2020
95a5df9
[stack-manager] Improve indexing performance with HaskellDirectoryInd…
carymrobbins Jun 17, 2020
64b831c
[stack-manager] Add exclude roots
carymrobbins Jun 17, 2020
a8d51cf
Add a TODO for StackOverflowPreventedException in HaskellVaridBaseImpl
carymrobbins Jun 17, 2020
aebaba6
[stack-manager] Don't use one module per source root; use one module …
carymrobbins Jun 17, 2020
9a3ad39
[stack-manager] Optimize how we obtain the runtime jars for external …
carymrobbins Jun 17, 2020
d210e47
[stack-manager] Minor updates; fix icon provider registration (includ…
carymrobbins Jun 17, 2020
acef229
[stack-manager] Auto-import on new project open
carymrobbins Jun 23, 2020
45200b0
[stack-manager] Major victory: reload icon appearing and working when…
carymrobbins Jun 24, 2020
0702b2e
[stack-manager] Slight refactor to easily get StackManager for a give…
carymrobbins Jun 24, 2020
f57a245
[stack-manager] Update HaskellIcons to use svg
carymrobbins Jun 24, 2020
aa82e14
[stack-manager] Show auto-import icon when package.yaml or .cabal fil…
carymrobbins Jun 24, 2020
7681f78
[stack-manager] Remove unnecessary newline from plugin.xml
carymrobbins Jun 24, 2020
b76076c
[stack-manager] Simplify re-import detection
carymrobbins Jun 24, 2020
f92c905
[stack-manager] Remove unused StackConfigLocator and StackProjectSett…
carymrobbins Jun 24, 2020
475b00c
[stack-manager] Default in-process stack external system to false
carymrobbins Jun 24, 2020
a20c87b
[stack-manager] Pass at implementing an ImportProvider for the new au…
carymrobbins Jun 24, 2020
8a5b6e8
[stack-manager] Remove unnecessary ImportProvider (project-open proce…
carymrobbins Jun 24, 2020
de70ce5
[stack-manager] Use StackSettings.scala over the .java version
carymrobbins Jun 25, 2020
01534c5
[stack-manager] Remove outdated doc comment on CabalQuery.getLibrary
carymrobbins Jun 25, 2020
7cf9280
[stack-manager] Remove unnecessary AbstractStackLocalSettings.java
carymrobbins Jun 25, 2020
d33f6e3
[stack-manager] Minor cleanups; remove println, improve comments
carymrobbins Jun 25, 2020
0f16382
[stack-manager] Simplify StackExecutionSettings and add an explicit doc
carymrobbins Jun 25, 2020
6341a96
[stack-manager] Refactor StackExecutionSettingsBuilder
carymrobbins Jun 25, 2020
529627c
[stack-manager] Fix todo in StackExecutionSettingsBuilder
carymrobbins Jun 25, 2020
1ef4711
[stack-manager] Improve doc comments
carymrobbins Jun 25, 2020
6b80253
[stack-manager] Add TODO to remove StackYaml
carymrobbins Jun 25, 2020
ff2294f
[stack-manager] Remove stack import wizard code
carymrobbins Jun 25, 2020
147e9c7
[stack-manager] Empty impls for StackTaskManager
carymrobbins Jun 25, 2020
3f0a70c
[stack-manager] Add ImportStackProjectAction
carymrobbins Jun 25, 2020
f95ce8b
[stack-manager] StackTaskManager doc comment
carymrobbins Jun 26, 2020
9382c25
[stack-manager] Remove unused StackExecutionConsoleManager
carymrobbins Jun 26, 2020
37ccf24
[stack-manager] Resolve dependencies
carymrobbins Jun 26, 2020
37d57d4
[stack-manager] Update HaskellBuildSettings to synchronize useStack/C…
carymrobbins Jun 28, 2020
17aa4c1
[stack-manager] Configure stack on initial project open
carymrobbins Jun 28, 2020
1fcfcf3
[stack-manager] Update CabalQueryTest with Library changes
carymrobbins Jul 6, 2020
41a10d7
[stack-manager] Move configureStack logic into StackProjectImporter
carymrobbins Jul 13, 2020
7ff4ec5
[stack-manager] Update stack external system to run in-process
carymrobbins Jul 14, 2020
ad4ea7a
[stack-manager] Build stack deps (useful for ghc-pkg dump)
carymrobbins Jul 14, 2020
721309a
[stack-manager] Fix stack project re-import from action
carymrobbins Jul 15, 2020
6adc4ae
[stack-manager] Check that process is alive before destroying
carymrobbins Jul 15, 2020
38081ed
[stack-manager] Small refactor for StackProjectInfoResolver
carymrobbins Jul 15, 2020
e9fd804
[stack-manager] Log lines when building deps
carymrobbins Jul 15, 2020
411f3d7
[stack-manager] Load ghc-pkg cache on stack import
carymrobbins Jul 15, 2020
18c24f9
[stack-manager] Initial pass at getting the dep data in at stack impo…
carymrobbins Jul 16, 2020
dc4b4c4
[stack-manager] Rework cache to support visible modules by file
carymrobbins Jul 16, 2020
0b5e13d
[stack-manager] Working visible modules completion
carymrobbins Jul 16, 2020
0ae312a
[stack-manager] Guard ghc-pkg features behind experimental setting
carymrobbins Jul 17, 2020
b81f787
[stack-manager] Cache ghc-pkg dump
carymrobbins Jul 18, 2020
d552295
[stack-manager] Store ghc-pkg-dump cache into explicit file for testing
carymrobbins Jul 18, 2020
10c068c
[stack-manager] Add PackageConfigCacheService
carymrobbins Jul 24, 2020
bf48b24
[stack-manager] Add DEV_MODE to build.gradle
carymrobbins Jul 26, 2020
0ac442a
[stack-manager] Add stack tool window
carymrobbins Jul 27, 2020
e44b58e
[stack-manager] Fix bug in JDOMExternalizable derivation
carymrobbins Jul 30, 2020
f9643eb
[stack-manager] Fix bug when loading ghc-pkg cache
carymrobbins Aug 5, 2020
0ddead6
[stack-manager] Resolve dependency versions
carymrobbins Aug 11, 2020
347ce84
[stack-manager] Update for IDEA 2020.2
carymrobbins Aug 28, 2020
de9a7a4
[stack-manager] Pre-compute cabal file list; more LOG messages
carymrobbins Sep 22, 2020
8faa7ab
[endless-recursion] Remove unnecessary check for inImportedModule
carymrobbins Oct 30, 2020
cfcc7da
[stack-manager] Fix test compile errors
carymrobbins Feb 11, 2021
43324e2
Revert "[endless-recursion] Remove unnecessary check for inImportedMo…
carymrobbins Feb 11, 2021
c385700
[stack-manager] Avoid NoSuchFileException in HaskellDirectoryIndexExc…
carymrobbins Feb 11, 2021
9987c69
[stack-manager] Fix NewProjectWizardTest
carymrobbins Feb 11, 2021
cf6ef2e
[stack-manager] Fix HaskellCompletionTest
carymrobbins Feb 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ build.properties
.gradletasknamecache
build/
lib/
/gradle.properties
12 changes: 11 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ allprojects {
version = properties('platformVersion')
type = properties('platformType')
plugins = ['java', 'yaml']
// Useful plugins to default-install when developing.
if (System.properties['DEV_MODE'] == "true") {
plugins += ['gradle', 'IdeaVIM:0.58']
}
}

repositories {
Expand All @@ -47,7 +51,9 @@ allprojects {
configurations {
provided
compile.extendsFrom provided
paradise
}
configurations.paradise.transitive = false

dependencies {

Expand All @@ -56,7 +62,8 @@ allprojects {
compile "org.scala-lang:scala-reflect:${scalaVersion}"
compile "org.scala-lang:scala-library:${scalaVersion}"

compile "io.estatico:newtype_${scalaBinaryVersion}:0.1.0"
paradise "org.scalamacros:paradise_${scalaVersion}:2.1.1"
compile "io.estatico:newtype_${scalaBinaryVersion}:0.4.4"
compile "org.scalaz:scalaz-core_${scalaBinaryVersion}:7.2.17"
compile "org.yaml:snakeyaml:1.16"

Expand All @@ -79,6 +86,7 @@ allprojects {
}

it.tasks.withType(ScalaCompile) {
String paradiseJar = configurations.paradise.singleFile.path
scalaCompileOptions.setAdditionalParameters([
'-deprecation',
'-feature',
Expand All @@ -98,6 +106,8 @@ allprojects {
'-Ywarn-unused:patvars',
'-Ywarn-unused:privates',
'-Ywarn-value-discard',
// Use '-Ymacro-annotations' once moved to scala 2.13
"-Xplugin:${paradiseJar}".toString()
])
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import scala.util.control.NonFatal

/**
* The parse result of a stack.yaml file.
*
* TODO: Remove in favor of a PSI interface.
*/
sealed case class StackYaml(packages: util.List[StackYaml.Package])

Expand Down
45 changes: 41 additions & 4 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<depends>com.intellij.modules.lang</depends>
-->

<depends>com.intellij.modules.java</depends>
<depends>com.intellij.modules.externalSystem</depends>

<application-components>
<!-- Add your application components here -->
</application-components>
Expand Down Expand Up @@ -58,6 +61,11 @@
description="Finds Cabal packages in your project and imports them as Haskell modules.">
<add-to-group group-id="ToolsMenu" anchor="first"/>
</action>
<action id="HaskForce.ImportStackProject"
class="com.haskforce.haskell.project.externalSystem.stack.ImportStackProjectAction"
text="Import Current Project Using Haskell Stack">
<add-to-group group-id="ExternalSystem.Actions" anchor="last"/>
</action>
</actions>

<extensions defaultExtensionNs="com.intellij">
Expand Down Expand Up @@ -91,6 +99,7 @@
<!-- Cache-->
<projectService serviceImplementation="com.haskforce.codeInsight.HaskellCompletionCacheService"/>
<projectService serviceImplementation="com.haskforce.tooling.ghcPkg.GhcPkgDumpProjectCacheService"/>
<projectService serviceImplementation="com.haskforce.tooling.stack.PackageConfigCacheService"/>

<!-- Language injections -->
<lang.elementManipulator forClass="com.haskforce.psi.HaskellQqblob"
Expand Down Expand Up @@ -193,10 +202,38 @@
<spellchecker.bundledDictionaryProvider
implementation="com.haskforce.spellchecker.HaskellBundledDictionaryProvider"/>

<projectImportProvider
implementation="com.haskforce.importWizard.stack.StackProjectImportProvider"/>
<projectImportBuilder
implementation="com.haskforce.importWizard.stack.StackProjectImportBuilder"/>

<directoryIndexExcludePolicy
implementation="com.haskforce.haskell.roots.HaskellDirectoryIndexExcludePolicy"/>

<!-- Stack support -->

<!--
We take advantage of being able to use the PSI model and other IDE
features while performing a stack project import, so we need to
do this in-process with the IDE and not via the external system.
The out-of-process external system is mostly useful for JVM build tools
which may be leaky. We are not leveraging any such JVM tool so doing
this in-process is better for us.
-->
<registryKey
key="HASKELL_STACK.system.in.process"
defaultValue="true"
restartRequired="true"
description="Whether IDE should use 'in-process' mode for the Haskell Stack external system"
/>

<projectOpenProcessor implementation="com.haskforce.haskell.project.externalSystem.stack.StackProjectOpenProcessor"/>
<externalSystemManager implementation="com.haskforce.haskell.project.externalSystem.stack.StackManager"/>
<externalIconProvider key="HASKELL_STACK" implementationClass="com.haskforce.haskell.project.externalSystem.stack.StackIconProvider"/>
<externalSystemTaskNotificationListener implementation="com.haskforce.haskell.project.externalSystem.stack.StackProjectImportNotificationListener"/>
<projectService serviceImplementation="com.haskforce.haskell.project.externalSystem.stack.StackSettings"/>
<projectService serviceImplementation="com.haskforce.haskell.project.externalSystem.stack.StackLocalSettings"/>

<toolWindow
id="Stack" anchor="right" icon="/icons/haskell-13px.png"
factoryClass="com.haskforce.haskell.project.externalSystem.stack.ui.StackToolWindowFactory"
/>

<!-- External builder support -->
<!-- Note that the classpath is needed for plugin deployment to export a zip archive. -->
Expand Down
80 changes: 80 additions & 0 deletions resources/icons/haskell-load-changes.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed resources/icons/haskell.png
Binary file not shown.
74 changes: 74 additions & 0 deletions resources/icons/haskell.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed resources/icons/[email protected]
Binary file not shown.
48 changes: 2 additions & 46 deletions src/com/haskforce/HaskForceBuildProcessParametersProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,11 @@ package com.haskforce
import java.util

import com.intellij.compiler.server.BuildProcessParametersProvider
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.containers.ContainerUtil

import scala.reflect.{ClassTag, classTag}

/**
* The external builder in jps-plugin needs to have some jars added to its
* classpath for some classes it uses. We figure out the right jar name
* by picking a class from that jar and use `PathManager` to resolve the
* jar for that class. Otherwise, keeping the version numbers updated for
* the jars becomes cumbersome and error-prone.
* classpath for some classes it uses.
*/
class HaskForceBuildProcessParametersProvider extends BuildProcessParametersProvider {

override def getClassPath: util.List[String] = {
mkList(
jarPath[com.intellij.execution.ExecutionException]("platform-ide-util-io"),
jarPath[scala.Symbol]("scala-library"),
jarPath[scala.reflect.runtime.JavaUniverse]("scala-reflect"),
jarPath[scalaz.Scalaz.type]("scalaz-core"),
jarPath[org.yaml.snakeyaml.Yaml]("snakeyaml"),
jarPath[io.estatico.newtype.NewType]("newtype")
)
}

/**
* Takes an array of jar names, logs each one, and builds a list to be
* added to the external builder classpath.
*/
private def mkList(xs: String*): util.List[String] = {
val res = ContainerUtil.immutableList(xs: _*)
res.forEach(x => HaskForceBuildProcessParametersProvider.LOG.info(s"Adding jar to builder classpath: $x"))
res
}

/**
* Resolve a jar from the class supplied `A` type parameter. The `name`
* argument is only supplied for debugging purposes.
*/
private def jarPath[A : ClassTag](name: String): String = {
val cls = classTag[A].runtimeClass
PathManager.getJarPathForClass(cls) match {
case null => throw new RuntimeException(s"Failed to find jar path '$name' for class '$cls'")
case s => s
}
}
}

object HaskForceBuildProcessParametersProvider {
private val LOG = Logger.getInstance(getClass)
override def getClassPath: util.List[String] = HaskForceRuntime.classPath
}
42 changes: 42 additions & 0 deletions src/com/haskforce/HaskForceRuntime.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.haskforce

import java.util

import com.intellij.openapi.application.PathManager
import com.intellij.util.containers.ContainerUtil

import scala.reflect.{ClassTag, classTag}

object HaskForceRuntime {

/**
* Get the jars that HaskForce uses so we can run HaskForce code
* in external JVM processes (external builder, external system, etc.).
*
* We figure out the right jar names required by HaskForce
* by picking a class from that jar and use `PathManager` to resolve the
* jar for that class. Otherwise, keeping the version numbers updated for
* the jars becomes cumbersome and error-prone.
*/
lazy val classPath: util.List[String] = ContainerUtil.immutableList(
jarPath[com.intellij.execution.ExecutionException]("platform-ide-util-io"),
jarPath[scala.Symbol]("scala-library"),
jarPath[scala.reflect.runtime.JavaUniverse]("scala-reflect"),
jarPath[scalaz.Scalaz.type]("scalaz-core"),
jarPath[org.yaml.snakeyaml.Yaml]("snakeyaml"),
jarPath[io.estatico.newtype.NewType]("newtype"),
jarPath[org.jetbrains.yaml.YAMLLanguage]("yaml")
)

/**
* Resolve a jar from the class supplied `A` type parameter. The `name`
* argument is only supplied for debugging purposes.
*/
private def jarPath[A : ClassTag](name: String): String = {
val cls = classTag[A].runtimeClass
PathManager.getJarPathForClass(cls) match {
case null => throw new RuntimeException(s"Failed to find jar path '$name' for class '$cls'")
case s => s
}
}
}
Loading