com-lihaoyi / acyclic Goto Github PK
View Code? Open in Web Editor NEWAcyclic is a Scala compiler plugin to let you prohibit circular dependencies between files
License: MIT License
Acyclic is a Scala compiler plugin to let you prohibit circular dependencies between files
License: MIT License
I have imported acyclic in project but it is not working as it is not showing any error but while running I am getting exception
Here's the log.
Initially I have a project that compiles fine. I now add acyclic-0.1.2
to build.sbt
, then do sbt reload
and then do sbt update
, I get the following:
reload
[info] Loading global plugins from /home/vasya/.sbt/0.13/plugins
[info] Loading project definition from /home/HIDDEN
[info] Set current project to HIDDEN (in build file:/home/HIDDEN)
update
[info] Updating {file:/home/HIDDEN...
[info] Resolving com.lihaoyi.acyclic#acyclic_2.10;0.1.2 ...
[warn] module not found: com.lihaoyi.acyclic#acyclic_2.10;0.1.2
[warn] ==== local: tried
[warn] /home/vasya/.ivy2/local/com.lihaoyi.acyclic/acyclic_2.10/0.1.2/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/com/lihaoyi/acyclic/acyclic_2.10/0.1.2/acyclic_2.10-0.1.2.pom
[warn] HIDDEN (2 repos logs)
[warn] ==== Global snapshots repo: tried
[warn] http://oss.sonatype.org/content/repositories/snapshots/com/lihaoyi/acyclic/acyclic_2.10/0.1.2/acyclic_2.10-0.1.2.pom
[warn] ==== repo.spray.io: tried
[warn] http://repo.spray.io/com/lihaoyi/acyclic/acyclic_2.10/0.1.2/acyclic_2.10-0.1.2.pom
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.lihaoyi.acyclic#acyclic_2.10;0.1.2: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last *:update for the full output.
error sbt.ResolveException: unresolved dependency: com.lihaoyi.acyclic#acyclic_2.10;0.1.2: not found
[error] Total time: 5 s, completed Apr 30, 2014 3:54:41 PM
Everything is nice if I use the version acyclic-0.1.1
(both in addCompilerPlugin
and libraryDependencies +=
).
2.13.11 JARs are on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-13-11-release-planning/6088/11
A.scala:
package skip
package a
import acyclic.skipped
trait A {
val b: B
}
B.scala:
package skip
package a
import acyclic.skipped
trait B {
val a: A
}
build.sbt:
organization in ThisBuild := "skip"
version in ThisBuild := "1.0-SNAPSHOT"
scalaVersion in ThisBuild := "2.12.5"
val acyclicVersion = "0.1.7"
val acyclicDep = "com.lihaoyi" %% "acyclic" % acyclicVersion % Provided
lazy val acyclicCompilerPlugin = addCompilerPlugin("com.lihaoyi" %% "acyclic" % acyclicVersion)
autoCompilerPlugins in ThisBuild := true
lazy val `acyclic` = (project in file("."))
.settings(settings)
lazy val settings = Seq(
libraryDependencies ++= Seq(
acyclicDep
),
acyclicCompilerPlugin
)
scalacOptions in ThisBuild ++= Seq(
"-P:acyclic:force", // Run cyclic dependencies check on all files
)
If you change
package skip
package a
to
package skip.a
in both files, then it compiles fine.
which is now on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-13-13-release-planning/6315/17
Hi,
When I try to use acyclic with a play project I get fololowing error on compilation time. I think the reason is reverse routing is generated dynamically.
Is there any workaround for this ?
PS: I get this error although I didn't annotate my source files yet with acyclic annotations
[error]
[error] last tree to typer: Block
[error] symbol: null
[error] symbol definition: null
[error] tpe: scala.runtime.AbstractPartialFunction[play.api.mvc.RequestHeader,play.api.mvc.Handler] with Serializable
[error] symbol owners:
[error] context owners: method routes -> object Routes -> package <empty>
[error]
[error] == Enclosing template or block ==
[error]
[error] Apply( // def <init>(): scala.runtime.AbstractPartialFunction[play.api.mvc.RequestHeader,play.api.mvc.Handler] with Serializable, tree.tpe=scala.runtime.AbstractPartialFunction[play.api.mvc.RequestHeader,play.api.mvc.Handler] with Serializable
[error] new $anonfun."<init>" // def <init>(): scala.runtime.AbstractPartialFunction[play.api.mvc.RequestHeader,play.api.mvc.Handler] with Serializable, tree.tpe=()scala.runtime.AbstractPartialFunction[play.api.mvc.RequestHeader,play.api.mvc.Handler] with Serializable
[error] Nil
[error] )
[error]
[error] == Expanded type of tree ==
[error]
[error] TypeRef(
[error] TypeSymbol(
[error] final class $anonfun extends AbstractPartialFunction[play.api.mvc.RequestHeader,play.api.mvc.Handler] with Serializable
[error]
[error] )
[error] )
[error]
[error] uncaught exception during compilation: java.lang.NullPointerException
Stacktrace
java.lang.NullPointerException
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1$$anonfun$1.isDefinedAt(DependencyExtraction.scala:56)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1$$anonfun$1.isDefinedAt(DependencyExtraction.scala:55)
at acyclic.plugin.DependencyExtraction$CollectTypeTraverser$1.traverse(DependencyExtraction.scala:12)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:58)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.internal.Trees$$anonfun$itraverse$5.apply$mcV$sp(Trees.scala:1119)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2849)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1118)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:13)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2825)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2829)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:62)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.internal.Trees$$anonfun$itraverse$3.apply$mcV$sp(Trees.scala:1111)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2849)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1110)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:13)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2825)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2829)
at scala.reflect.internal.Trees$$anonfun$itraverse$1.apply$mcV$sp(Trees.scala:1103)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2849)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1102)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:13)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2825)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$.byMembers$1(DependencyExtraction.scala:71)
at acyclic.plugin.DependencyExtraction$.apply(DependencyExtraction.scala:95)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:70)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:68)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.HashSet$HashSet1.foreach(HashSet.scala:153)
at scala.collection.immutable.HashSet$HashTrieSet.foreach(HashSet.scala:306)
at scala.collection.immutable.HashSet$HashTrieSet.foreach(HashSet.scala:306)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractSet.scala$collection$SetLike$$super$map(Set.scala:47)
at scala.collection.SetLike$class.map(SetLike.scala:93)
at scala.collection.AbstractSet.map(Set.scala:47)
at acyclic.plugin.PluginPhase$$anon$1.run(PluginPhase.scala:68)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1583)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1557)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1553)
at scala.tools.nsc.Global$Run.compile(Global.scala:1662)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:123)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:99)
at xsbt.CompilerInterface.run(CompilerInterface.scala:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:48)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:98)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:98)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:98)
at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:159)
at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:142)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:86)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:38)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:36)
at sbt.inc.Incremental$.cycle(Incremental.scala:73)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:33)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:32)
at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:41)
at sbt.inc.Incremental$.compile(Incremental.scala:32)
at sbt.inc.IncrementalCompile$.apply(Compile.scala:26)
at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:150)
at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:70)
at sbt.compiler.AggressiveCompile.apply(AggressiveCompile.scala:45)
at sbt.Compiler$.apply(Compiler.scala:70)
at sbt.Defaults$.sbt$Defaults$$compileTaskImpl(Defaults.scala:722)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:716)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:716)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
at sbt.std.Transform$$anon$4.work(System.scala:64)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
at sbt.Execute.work(Execute.scala:244)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
We’re trying to modularize a largish code base, and it would be great if acyclic could help us see where there are branches we could move into their own subprojects.
We use -Ywarn-unused-import
(and -Xfatal-warnings
), and get
Unused import
import acyclic.file
on any file I add it to.
I don’t know of any way to silence an unused import warning (e.g., using @SuppressWarnings
), but I’d happily do that if possible.
...which is now on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-13-14-release-planning/6581/13
I'd appreciate a place to ask simple non Stack Overflow questions publicly.
Hey @lihaoyi,
can you please check:
https://github.com/lihaoyi/acyclic/blob/master/src/main/scala/acyclic/plugin/PluginPhase.scala#L34-L37
Here it's ok, but when I check the ones on maven, it's different:
def units = global.currentRun
.units
.filter(!_.isJava)
.toSeq
.sortBy(_.source.content.mkString.hashCode())
which makes java files not to compile into project... it was how I did it (screwed up) initially but then changed it to actual fix, somehow this discrepancy happened... my actual fixes got merged though
can you check it out please ? I believe 0.1.3 - maven one - is now broken.
...which is now on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-12-19-release-planning/6216/13
2.12.18 JARs are on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-12-18-release-planning/6089/9
I got (on acyclic 0.2.0)
[error] Unwanted cyclic dependency [67/1927]
[error] ## Exception when compiling 24 sources to /home/oscar/predictionmachine/hiona/core/target/scala-2.13/classes
[error] java.lang.NoSuchMethodError: scala.tools.nsc.CompilationUnits$CompilationUnit.echo(Lscala/reflect/internal/util/Position$
Ljava/lang/String;)V
[error] acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$33(PluginPhase.scala:161)
[error] acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$33$adapted(PluginPhase.scala:152)
[error] scala.collection.IterableOnceOps.foreach(IterableOnce.scala:553)
[error] scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:551)
[error] scala.collection.AbstractIterator.foreach(Iterator.scala:1279)
[error] acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$28(PluginPhase.scala:152)
[error] scala.collection.IterableOnceOps.foreach(IterableOnce.scala:553)
[error] scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:551)
[error] scala.collection.AbstractIterable.foreach(Iterable.scala:920)
[error] scala.collection.IterableOps$WithFilter.foreach(Iterable.scala:890)
[error] acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$25(PluginPhase.scala:138)
[error] acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$25$adapted(PluginPhase.scala:137)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] acyclic.plugin.PluginPhase$$anon$1.run(PluginPhase.scala:137)
[error] scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1505)
...
when I downgraded to 2.13.0 it worked.
Hooking acyclic into my project crashes. Maybe I'm not using compatible versions of scala or something. Looking forward to using it after this is hopefully figured out!
[info] This is sbt 0.13.6
[info] The current project is built against Scala 2.11.6
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin, play.twirl.sbt.SbtTwirl, play.Play, play.PlayJava, play.PlayScala, com.typesafe.sbt.jse.SbtJsEngine, com.typesafe.sbt.jse.SbtJsTask, com.typesafe.sbt.web.SbtWeb, com.typesafe.sbt.webdriver.SbtWebDriver, com.typesafe.sbt.coffeescript.SbtCoffeeScript, com.typesafe.sbt.less.SbtLess, com.typesafe.sbt.jshint.SbtJSHint, com.typesafe.sbt.rjs.SbtRjs, com.typesafe.sbt.digest.SbtDigest, com.typesafe.sbt.mocha.SbtMocha, com.typesafe.sbt.gzip.SbtGzip, com.jamesward.play.BrowserNotifierPlugin, com.typesafe.sbteclipse.plugin.EclipsePlugin, com.typesafe.sbt.SbtStartScript, org.netbeans.nbsbt.plugin.NetBeansPlugin, com.typesafe.sbt.SbtScalariform, org.sbtidea.SbtIdeaPlugin, com.typesafe.sbt.SbtNativePackager
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4
$ last compile:compile
[debug]
[debug] Initial source changes:
[debug] removed:Set()
[debug] added: .....
[debug] Recompiling all 78 sources: invalidated sources (78) exceeded 50.0% of all sources
[info] Compiling 77 Scala sources and 1 Java source to .....
[debug] Getting compiler-interface from component compiler for Scala 2.11.6
[debug] Getting compiler-interface from component compiler for Scala 2.11.6
[debug] Running cached compiler 5d06c36f, interfacing (CompilerInterface) with Scala compiler version 2.11.6
[debug] Calling Scala compiler with arguments (CompilerInterface):
[debug] -unchecked
[debug] -deprecation
[debug] -encoding
[debug] utf8
[debug] -unchecked
[debug] -feature
[debug] -feature
[debug] -language:reflectiveCalls
[debug] -Xplugin:/home/matan/.ivy2/cache/com.lihaoyi/acyclic_2.11/jars/acyclic_2.11-0.1.2.jar
[debug] -bootclasspath
[debug] /usr/lib/jvm/java-7-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-7-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-7-oracle/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-7-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-7-oracle/jre/classes:/home/matan/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.6.jar
[debug] -classpath
3.0.0-RC2.jar:/home/matan/.ivy2/cache/com.lihaoyi/acyclic_2.11/jars/acyclic_2.11-0.1.2.jar
java.lang.NullPointerException
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1$$anonfun$1.isDefinedAt(DependencyExtraction.scala:56)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1$$anonfun$1.isDefinedAt(DependencyExtraction.scala:55)
at acyclic.plugin.DependencyExtraction$CollectTypeTraverser$1.traverse(DependencyExtraction.scala:12)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:58)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser.traverseTypeAscription(Trees.scala:2478)
at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1214)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1203)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1328)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2484)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:62)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1208)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1203)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1327)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser$$anonfun$traverseStats$1$$anonfun$apply$1.apply$mcV$sp(Trees.scala:2498)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
at scala.reflect.api.Trees$Traverser.traverseStats(Trees.scala:2497)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1326)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$.byMembers$1(DependencyExtraction.scala:71)
at acyclic.plugin.DependencyExtraction$.apply(DependencyExtraction.scala:95)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:73)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:71)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1222)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1212)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1222)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1212)
at scala.collection.immutable.Stream.foreach(Stream.scala:595)
at scala.collection.TraversableOnce$class.toMap(TraversableOnce.scala:301)
at scala.collection.AbstractTraversable.toMap(Traversable.scala:104)
at acyclic.plugin.PluginPhase$$anon$1.run(PluginPhase.scala:89)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1500)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1487)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1482)
at scala.tools.nsc.Global$Run.compile(Global.scala:1580)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:116)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:95)
at xsbt.CompilerInterface.run(CompilerInterface.scala:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:162)
at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:96)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:139)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:86)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:38)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:36)
at sbt.inc.IncrementalCommon.cycle(IncrementalCommon.scala:31)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:39)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:38)
at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:66)
at sbt.inc.Incremental$.compile(Incremental.scala:38)
at sbt.inc.IncrementalCompile$.apply(Compile.scala:26)
at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:153)
at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:70)
at sbt.compiler.AggressiveCompile.apply(AggressiveCompile.scala:45)
at sbt.Compiler$.apply(Compiler.scala:74)
at sbt.Compiler$.apply(Compiler.scala:65)
at sbt.Defaults$.sbt$Defaults$$compileTaskImpl(Defaults.scala:777)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:769)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:769)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:235)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
[error] (compile:compile) java.lang.NullPointerException
What might it be?
It is written scalaOptions += "-P:acyclic:force" instead of scalacOptions += "-P:acyclic:force" ;)
I am using acyclic plugin with in sample application as describe in documentation. When i compile my application there is no error or warning generate. [https://github.com/harmeetsingh0013/asyclic-test](Please click on link for looking my sample application)
2.13.9 JARs are on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-13-9-release-planning/5693/16
Scala 2.13.10 is now on Maven Central; we plan to announce it on Thu Oct 13.
...which is now on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-13-12-release-planning/6217/26
I'm trying to use the plugin per the readme.
plugins.sbt
addCompilerPlugin("com.lihaoyi" %% "acyclic" % "0.1.7")
scala project file
scalacOptions ++= Seq(
"-Yresolve-term-conflict:package", "-Ywarn-dead-code", "-Ywarn-inaccessible",
"-feature", "-language:_", "-P:acyclic:force"),
library dependencies:
"org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided",
"com.lihaoyi" %% "acyclic" % "0.1.7" % "provided"
error on test:compile
[error] bad option: -P:acyclic:force
[error] bad option: -P:acyclic:force
[error] bad option: -P:acyclic:force
[error] one error found
[error] one error found
What do I try next?
This would help to identify and break the big (most impactful) cycles first.
One could also add options to filter the results by a minimum cycle length.
would it be possible to have a version where the plugin enforces no file cycles by default, with an import to opt-out of the check? (which could raise a warning / info level message)
I'd like to use this in the ensime server code, but I don't really want to have to annotate every single file https://github.com/ensime/ensime-server/issues/1148
2.12.17 JARs are on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-12-17-release-planning/5805
Thanks for creating the plugin. Starting a fresh project and want to have clean code. :)
I'm testing out the plugin to make sure I've configured it correctly. It doesn't seem to detect package cycles in test code, See https://github.com/gshakhn/acyclic-test for a sample project.
Running sbt test:compile
doesn't cause a compilation error. If classes A
and B
are moved to the source directory, running sbt compile
makes the compile fail as expected.
Am I missing a configuration option, or does the plugin not support test code?
Periodically after saving a single file and attempting to run tests in IDEA, I get the following exception from Acyclic. Exception goes away if I do a complete rebuild. Exception is not thrown when compiling with SBT.
Error:scalac: Error: key not found: /foo/bar.scala
java.util.NoSuchElementException: key not found: /foo/bar.scala
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.MapLike$class.apply(MapLike.scala:141)
at scala.collection.AbstractMap.apply(Map.scala:59)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6$$anonfun$apply$8.apply(PluginPhase.scala:84)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6$$anonfun$apply$8.apply(PluginPhase.scala:84)
at scala.collection.TraversableLike$$anonfun$groupBy$1.apply(TraversableLike.scala:321)
at scala.collection.TraversableLike$$anonfun$groupBy$1.apply(TraversableLike.scala:320)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
at scala.collection.TraversableLike$class.groupBy(TraversableLike.scala:320)
at scala.collection.AbstractTraversable.groupBy(Traversable.scala:104)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:84)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:71)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1233)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1223)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1233)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1223)
at scala.collection.immutable.Stream.foreach(Stream.scala:595)
at scala.collection.TraversableOnce$class.toMap(TraversableOnce.scala:316)
at scala.collection.AbstractTraversable.toMap(Traversable.scala:104)
at acyclic.plugin.PluginPhase$$anon$1.run(PluginPhase.scala:89)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1501)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1486)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1481)
at scala.tools.nsc.Global$Run.compile(Global.scala:1582)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:115)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:94)
at xsbt.CompilerInterface.run(CompilerInterface.scala:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at org.jetbrains.jps.incremental.scala.local.IdeaIncrementalCompiler.compile(IdeaIncrementalCompiler.scala:29)
at org.jetbrains.jps.incremental.scala.local.LocalServer.compile(LocalServer.scala:26)
at org.jetbrains.jps.incremental.scala.remote.Main$.make(Main.scala:67)
at org.jetbrains.jps.incremental.scala.remote.Main$.nailMain(Main.scala:24)
at org.jetbrains.jps.incremental.scala.remote.Main.nailMain(Main.scala)
at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.martiansoftware.nailgun.NGSession.run(NGSession.java:319)
It'd be great if you could run acyclic without putting import acyclic.file into every source file.
Hi, this is my first try with this plugin and here is what I get :
java.lang.NullPointerException
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1$$anonfun$1.isDefinedAt(DependencyExtraction.scala:56)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1$$anonfun$1.isDefinedAt(DependencyExtraction.scala:55)
at acyclic.plugin.DependencyExtraction$CollectTypeTraverser$1.traverse(DependencyExtraction.scala:12)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:58)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser.traverseTypeAscription(Trees.scala:2478)
at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1214)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1203)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1328)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2484)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:62)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1208)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1203)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1327)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:27)
at scala.reflect.api.Trees$Traverser$$anonfun$traverseStats$1$$anonfun$apply$1.apply$mcV$sp(Trees.scala:2498)
at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
at scala.reflect.api.Trees$Traverser.traverseStats(Trees.scala:2497)
at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1326)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
at acyclic.plugin.DependencyExtraction$ExtractDependenciesByMemberRefTraverser$1.traverse(DependencyExtraction.scala:65)
at acyclic.plugin.DependencyExtraction$.byMembers$1(DependencyExtraction.scala:71)
at acyclic.plugin.DependencyExtraction$.apply(DependencyExtraction.scala:95)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:73)
at acyclic.plugin.PluginPhase$$anon$1$$anonfun$6.apply(PluginPhase.scala:71)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1222)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1212)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1222)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1212)
at scala.collection.immutable.Stream.foreach(Stream.scala:595)
at scala.collection.TraversableOnce$class.toMap(TraversableOnce.scala:301)
at scala.collection.AbstractTraversable.toMap(Traversable.scala:104)
at acyclic.plugin.PluginPhase$$anon$1.run(PluginPhase.scala:89)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1500)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1487)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1482)
at scala.tools.nsc.Global$Run.compile(Global.scala:1580)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:116)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:95)
at xsbt.CompilerInterface.run(CompilerInterface.scala:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:162)
at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:96)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:139)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:86)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:38)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:36)
at sbt.inc.IncrementalCommon.cycle(IncrementalCommon.scala:31)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:39)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:38)
at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:66)
at sbt.inc.Incremental$.compile(Incremental.scala:38)
at sbt.inc.IncrementalCompile$.apply(Compile.scala:26)
at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:153)
at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:70)
at sbt.compiler.AggressiveCompile.apply(AggressiveCompile.scala:45)
at sbt.Compiler$.apply(Compiler.scala:74)
at sbt.Compiler$.apply(Compiler.scala:65)
at sbt.Defaults$.sbt$Defaults$$compileTaskImpl(Defaults.scala:789)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:781)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:781)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:235)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
My project is a Play 2.3.7 project with a few sub-projects; its environment is :
In a project the compile phase failed when configured with -P:acyclic:force
, but the same messages is not shown (as warning) when the warn
options is added (-P:acyclic:force:warn
).
We should probably add a test case to ensure warn
works as expected.
When using acyclic with settings
lazy val acyclicSettings = Seq(
libraryDependencies += "com.lihaoyi" %% "acyclic" % acyclicVersion.value % "provided",
autoCompilerPlugins := true,
scalacOptions += "-P:acyclic:force",
libraryDependencies += compilerPlugin("com.lihaoyi" %% "acyclic" % acyclicVersion.value)
)
Sbt console crashes with
[IJ]sbt:proj1> console
[info] Starting scala interpreter...
Welcome to Scala 2.13.1 (OpenJDK 64-Bit Server VM, Java 1.8.0_232).
Type in expressions for evaluation. Or try :help.
scala> val a = 1
java.util.NoSuchElementException: key not found: <console>
at scala.collection.immutable.Map$Map1.apply(Map.scala:240)
at acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$8(PluginPhase.scala:96)
at scala.collection.IterableOps.groupBy(Iterable.scala:557)
at scala.collection.IterableOps.groupBy$(Iterable.scala:552)
at scala.collection.AbstractIterable.groupBy(Iterable.scala:921)
at acyclic.plugin.PluginPhase$$anon$1.$anonfun$run$2(PluginPhase.scala:96)
at scala.collection.immutable.List.map(List.scala:219)
at scala.collection.immutable.List.map(List.scala:79)
at acyclic.plugin.PluginPhase$$anon$1.run(PluginPhase.scala:83)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1506)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1490)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compile(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request.$anonfun$compile$7(IMain.scala:913)
at scala.runtime.java8.JFunction0$mcZ$sp.apply(JFunction0$mcZ$sp.scala:17)
at scala.tools.nsc.interpreter.IMain.$anonfun$withoutWarnings$1(IMain.scala:1334)
at scala.tools.nsc.interpreter.shell.ReplReporterImpl.withoutPrintingResults(Reporter.scala:64)
at scala.tools.nsc.interpreter.IMain.withoutWarnings(IMain.scala:99)
at scala.tools.nsc.interpreter.IMain$Request.compile(IMain.scala:913)
at scala.tools.nsc.interpreter.IMain.compile(IMain.scala:493)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:487)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:470)
at scala.tools.nsc.interpreter.shell.ILoop.interpretStartingWith(ILoop.scala:931)
at scala.tools.nsc.interpreter.shell.ILoop.command(ILoop.scala:788)
at scala.tools.nsc.interpreter.shell.ILoop.processLine(ILoop.scala:462)
at scala.tools.nsc.interpreter.shell.ILoop.loop(ILoop.scala:485)
at scala.tools.nsc.interpreter.shell.ILoop.run(ILoop.scala:1020)
at xsbt.ConsoleInterface.run(ConsoleInterface.scala:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sbt.internal.inc.AnalyzingCompiler.call(AnalyzingCompiler.scala:248)
at sbt.internal.inc.AnalyzingCompiler.console(AnalyzingCompiler.scala:210)
at sbt.Console.console0$1(Console.scala:48)
at sbt.Console.$anonfun$apply$2(Console.scala:51)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
at sbt.util.InterfaceUtil$$anon$1.get(InterfaceUtil.scala:10)
at sbt.TrapExit$App.run(TrapExit.scala:257)
at java.lang.Thread.run(Thread.java:748)
That entry seems to have slain the compiler. Shall I replay
your session? I can re-run each line except the last one.
[y/n]
sbt version 1.3.4
A number of issues have noted the verbosity of failures and this is a problem for us as well for cycles at package level introduced by one small change.
Let me explain my use-case. The way that I want to use acyclic is to enforce a hexagonal architecture at the package level.
We have three package hierarchies in services, domain
, application
and infrastructure
. domain
is not allowed to have external dependencies, application
is allowed to use domain
and `infrastructure is allowed to use both the other two. It's an onion architecture basically.
I was really neatly able to achieve this functionality with
package uk.co.boostpower.some-service
package object application {
import acyclic.pkg
}
package object domain {
import acyclic.pkg
}
package object infrastructure {
import acyclic.pkg
}
This prevents cycles. The problem is that the moment a cycle is introduced (eg one class in domain package depends on infrastructure) the errors reported are,
it could be hard to spot the cause of the problem as it is only one (although it does always seem to be at the top).
What would be nice is if the report described the package cycle violations at a top level with one example but didn't print all the other hundreds of violations (the same way that it doesn't currently print more than one violation per file).
It could be something like,
[error] Unwanted cyclic dependency between uk/co/boostpower/debt/domain and uk/co/boostpower/debt/infrastructure
[error] uk/co/boostpower/debt/domain depends on uk/co/boostpower/debt/infrastructure
[info] /home/circleci/project/debt/src/main/scala/uk/co/boostpower/debt/domain/entities.scala:16:19:
[info] case class Phooey(fooBar: FooBar)
[info] ^
[info] symbol: class FooBar
[info] More dependencies in file /home/circleci/project/debt/src/main/scala/uk/co/boostpower/debt/domain/entities.scala at lines 7 7
[info] uk.co.boostpower.debt.infrastructure depends on uk/co/boostpower/debt/domain
[info] /home/circleci/project/debt/src/main/scala/uk/co/boostpower/debt/infrastructure/BalanceServiceRestClient.scala:11:8:
[info] import uk.co.boostpower.debt.domain.balance.BalanceService
[info] ^
[info] symbol: value <import>
[info] More dependencies in file /home/circleci/project/debt/src/main/scala/uk/co/boostpower/debt/infrastructure/BalanceServiceRestClient.scala at lines 7 7
[info] More dependencies in file /home/circleci/project/debt/src/main/scala/uk/co/boostpower/debt/infrastructure/Storage.scala at lines 21 12
[info] More dependencies in file /home/circleci/project/debt/src/main/scala/uk/co/boostpower/debt/infrastructure/Reporting.scala at lines 100 123
[....] you get the idea...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.