diff --git a/.gitattribute b/.gitattribute index ccd5ce6..2d60869 100644 --- a/.gitattribute +++ b/.gitattribute @@ -5,5 +5,7 @@ *.xml text eol=lf *.py text eol=lf *.R text eol=lf - # from apache spark + +*.sh text eol=lf +* text eol=lf \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 22c6fcd..cbd6188 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,9 +33,9 @@ plugins { `maven-publish` id("io.github.gradle-nexus.publish-plugin") version "1.3.0" - id("com.github.ben-manes.versions") version "0.50.0" + id("com.github.ben-manes.versions") version "0.51.0" - id("io.github.cosmicsilence.scalafix") version "0.1.14" + id("io.github.cosmicsilence.scalafix") version "0.2.0" } val sonatypeApiUser = providers.gradleProperty("sonatypeApiUser") @@ -77,7 +77,6 @@ allprojects { version = vs.projectV repositories { - mavenLocal() mavenCentral() // jcenter() maven("https://dl.bintray.com/kotlin/kotlin-dev") @@ -131,16 +130,15 @@ allprojects { dependencies { - // see https://github.com/gradle/gradle/issues/13067 - fun bothImpl(constraintNotation: Any) { - implementation(constraintNotation) - testFixturesImplementation(constraintNotation) - } - constraints {} - bothImpl("${vs.scalaGroup}:scala-compiler:${vs.scalaV}") - bothImpl("${vs.scalaGroup}:scala-library:${vs.scalaV}") + // see https://github.com/gradle/gradle/issues/13067 +// fun bothImpl(constraintNotation: Any) { +// implementation(constraintNotation) +// testFixturesImplementation(constraintNotation) +// } + + implementation("${vs.scalaGroup}:scala-library:${vs.scalaV}") val scalaTestV = "3.2.11" testFixturesApi("org.scalatest:scalatest_${vs.scalaBinaryV}:${scalaTestV}") @@ -314,8 +312,6 @@ subprojects { artifactId = moduleID version = project.version.toString() - println("=== $version ===") - pom { licenses { license { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 3533533..f127112 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,10 +2,18 @@ val vs: Versions = versions() dependencies { + // see https://github.com/gradle/gradle/issues/13067 + fun bothImpl(constraintNotation: Any) { + implementation(constraintNotation) + testFixturesImplementation(constraintNotation) + } + + bothImpl("${vs.scalaGroup}:scala-compiler:${vs.scalaV}") + // testImplementation("${vs.scalaGroup}:scala-library:${vs.scalaV}") testFixturesApi("com.chuusai:shapeless_${vs.scalaBinaryV}:2.3.7") - testFixturesApi("dev.zio:zio_${vs.scalaBinaryV}:1.0.4") + testFixturesApi("dev.zio:zio_${vs.scalaBinaryV}:1.0.18") testFixturesApi("org.slf4j:slf4j-api:2.0.9") testRuntimeOnly("org.slf4j:slf4j-simple:2.0.9") diff --git a/core/src/main/scala-2.13.7+/latest/splain/SplainFormattingExtension.scala b/core/src/main/scala-2.13.7+/latest/splain/SplainFormattingExtension.scala index b563c36..4cb9850 100644 --- a/core/src/main/scala-2.13.7+/latest/splain/SplainFormattingExtension.scala +++ b/core/src/main/scala-2.13.7+/latest/splain/SplainFormattingExtension.scala @@ -12,6 +12,9 @@ object SplainFormattingExtension { import scala.reflect.internal.TypeDebugging.AnsiColor._ val ELLIPSIS: String = "⋮".blue + + val | = "┃" + val vertical_| = "━━━━━━━━:" } trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with SplainFormattersExtension { @@ -476,7 +479,7 @@ trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with override protected def formattedHeader_Body(break: Boolean): (String, Seq[TypeRepr]) = { lazy val infixText = infixOpt match { - case None => "|" + case None => | case Some(ii) => " " + showFormattedLImpl(ii, break).flat + " " } @@ -484,7 +487,7 @@ trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with .split("\n") .filter(_ != ";") - s"(comparing $infixText)" -> indented.map(v => FlatType(v)) + s"(comparing $infixText)" -> indented.toSeq.map(v => FlatType(v)) } } @@ -672,7 +675,14 @@ trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with } } - override def showFormattedLImpl(ft: Formatted, break: Boolean): TypeRepr = { + case class ShowFormattedHelper(break: Boolean) { + + import scala.reflect.internal.TypeDebugging.AnsiColor._ + + def _decideBreak(flat: FlatType, broken: BrokenType): TypeRepr = { + + if (break) decideBreak(flat, broken) else flat + } def appendLastLine(lines: List[String], suffix: String): List[String] = { lines match { @@ -682,6 +692,67 @@ trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with } } + def withVerticalDelimiter(v: TypeRepr): String = { + v.lines + .map { ll => + | + ll + } + .mkString("\n") + } + + def showDiff(left: Formatted, right: Formatted): TypeRepr = { + + val (ll, rr) = (left, right) match { + case (Qualified(lpath, lname), Qualified(rpath, rname)) if lname == rname => + val prefix = lpath.reverseIterator.zip(rpath.reverseIterator).takeWhile { case (l, r) => l == r }.size + 1 + FlatType(s"${qualifiedName(lpath.takeRight(prefix), lname).red}") -> + FlatType(s"${qualifiedName(rpath.takeRight(prefix), rname).green}") + + case (left, right) => + _showFormattedL(left) -> + _showFormattedL(right) + } + + lazy val flat = + FlatType(s"${ll.flat}${|}${rr.flat}") + + lazy val broken: BrokenType = { + + val Seq(_ll, _rr) = Seq(ll, rr).map { v => + v.indent.indent.indent.indent.indent.joinLines.trim + } + + val result = + s""" + |found : ${_ll} + |${vertical_|} + |required: ${_rr}""".stripMargin.trim + + BrokenType(result.split("\n").toList) + } + + val result = _decideBreak(flat, broken) + result + } + + case class Tree( + header: String, + body: Seq[TypeRepr] + ) { + + lazy val flat: String = { + + if (body.isEmpty) header + else s"$header { ${body.map(v => v.flat).mkString(";")} }" + } + + lazy val broken: Seq[String] = { + val result = indentTree(List((header, body.flatMap(_.lines).toList, 0)), 1) + + result + } + } + /** * If the args of an applied type constructor are multiline, create separate lines for the constructor name and the * closing bracket; else return a single line. @@ -702,7 +773,27 @@ trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with def broken = BrokenType(appendLastLine(base.lines, brackets._1) ::: indent(brokenArgs) ::: List(brackets._2)) - if (break) decideBreak(flat, broken) else flat + _decideBreak(flat, broken) + } + + // TODO: let Based use this? + def showTree( + base: String, + body: Seq[TypeRepr], + brackets: (String, String) = "" -> "" + ): TypeRepr = { + + def flat = FlatType { + + if (body.isEmpty) base + else s"$base ${brackets._1}${body.map(v => v.flat).mkString(";")}${brackets._2}" + } + + def broken = BrokenType { + indentTree(List((base, body.flatMap(_.lines).toList, 0)), 1) + } + + _decideBreak(flat, broken) } def showCompound( @@ -712,75 +803,100 @@ trait SplainFormattingExtension extends typechecker.splain.SplainFormatting with val infixWithSpace = s" $infixText " def flat = FlatType(types.map(_.flat).mkString(infixWithSpace)) + def broken = BrokenType( types.map(_.lines).reduceLeft((z, a) => appendLastLine(z, infixWithSpace) ::: a) ) - if (break) decideBreak(flat, broken) else flat + _decideBreak(flat, broken) } - def _showFormattedL(v: Formatted) = showFormattedL(v, break) + def _showFormattedL(v: Formatted): TypeRepr = showFormattedL(v, break) - val raw = ft match { - case Simple(name) => FlatType(name.name) - case Qualified(path, name) => showFormattedQualified(path, name) - case Applied(cons, args) => showEnclosed(_showFormattedL(cons), args.map(_showFormattedL)) - case tpe @ Infix(_, _, _, top) => - wrapParensRepr( - if (break) breakInfix(flattenInfix(tpe)) else FlatType(flattenInfix(tpe).map(showFormatted).mkString(" ")), - top - ) - case UnitForm => FlatType("Unit") - case FunctionForm(args, ret, top) => - FlatType(wrapParens(s"${showFuncParams(args.map(showFormatted))} => ${showFormatted(ret)}", top)) - case TupleForm(elems) => - val formattedElems = elems.map(_showFormattedL) - - if (elems.size == 1) { - FlatType(showTuple(formattedElems.map(_.flat))) // TODO: the name showTuple is obsolete - } else { - showEnclosed(FlatType(""), formattedElems, brackets = "(" -> ")") - } + def showTuple(elems: List[Formatted]): TypeRepr = { + val formattedElems = elems.map(_showFormattedL) - case RefinedForm(elems, decls) => - val compound = showCompound(elems.map(_showFormattedL)) - - val refined = - if (decls.isEmpty) - compound - else if (truncateDecls(decls)) - showEnclosed(compound, List(FlatType("...")), brackets = " {" -> "}", splitter = ";") - else - showEnclosed(compound, decls.map(_showFormattedL), brackets = " {" -> "}", splitter = ";") + elems match { + case List(_) => + showEnclosed(FlatType("Tuple1"), formattedElems) + case _ => + showEnclosed(FlatType(""), formattedElems, brackets = "(" -> ")") + } + } - refined + def apply(ft: Formatted): TypeRepr = { + + val raw = ft match { + case Simple(name) => FlatType(name.name) + case Qualified(path, name) => showFormattedQualified(path, name) + case Applied(cons, args) => showEnclosed(_showFormattedL(cons), args.map(_showFormattedL)) + case tpe @ Infix(_, _, _, top) => + wrapParensRepr( + if (break) breakInfix(flattenInfix(tpe)) else FlatType(flattenInfix(tpe).map(showFormatted).mkString(" ")), + top + ) + case UnitForm => FlatType("Unit") + case FunctionForm(args, ret, top) => + FlatType(wrapParens(s"${showFuncParams(args.map(showFormatted))} => ${showFormatted(ret)}", top)) + case TupleForm(elems) => + showTuple(elems) + + case RefinedForm(elems, decls) => + val compound = showCompound(elems.map(_showFormattedL)) + + val refined = + if (decls.isEmpty) + compound + else if (truncateDecls(decls)) + showEnclosed(compound, List(FlatType("...")), brackets = " {" -> "}", splitter = ";") + else + showEnclosed(compound, decls.map(_showFormattedL), brackets = " {" -> "}", splitter = ";") + + refined + + case Diff(left, right) => showDiff(left, right) + case Decl(sym, rhs) => + showTree( + s"type ${showFormatted(sym)} =", + Seq(_showFormattedL(rhs)) + ) + + case DeclDiff(sym, left, right) => + val diff = showDiff(left, right) + showTree( + s"type ${showFormatted(sym)} =", + Seq(diff) + ) + + case ByName(tpe) => FlatType(s"(=> ${showFormatted(tpe)})") + } - case Diff(left, right) => FlatType(formattedDiff(left, right)) - case Decl(sym, rhs) => FlatType(s"type ${showFormatted(sym)} = ${showFormatted(rhs)}") - case DeclDiff(sym, left, right) => FlatType(s"type ${showFormatted(sym)} = ${formattedDiff(left, right)}") - case ByName(tpe) => FlatType(s"(=> ${showFormatted(tpe)})") - } + val index = FormattedIndex(ft) + val basedOn = Based.getAll(index) - val index = FormattedIndex(ft) - val basedOn = Based.getAll(index) + val result = { - val result = { + basedOn match { + case Nil => + raw + case _ => + def flat = FlatType(raw.flat + " " + basedOn.map(_.flat).mkString(" ")) - basedOn match { - case Nil => - raw - case _ => - def flat = FlatType(raw.flat + " " + basedOn.map(_.flat).mkString(" ")) - def broken = BrokenType(raw.lines ++ basedOn.flatMap(_.broken)) + def broken = BrokenType(raw.lines ++ basedOn.flatMap(_.broken)) - raw match { - case _: BrokenType => broken - case _ if !break => flat - case _ => decideBreak(flat, broken) - } + raw match { + case _: BrokenType => broken + case _ => _decideBreak(flat, broken) + } + } } + + result } - result + } + + override def showFormattedLImpl(ft: Formatted, break: Boolean): TypeRepr = { + ShowFormattedHelper(break)(ft) } } diff --git a/core/src/test/resources/splain/builtin/BasicSpec/__direct/check b/core/src/test/resources/splain/builtin/BasicSpec/__direct/check index 8935e74..ed7f0fa 100644 --- a/core/src/test/resources/splain/builtin/BasicSpec/__direct/check +++ b/core/src/test/resources/splain/builtin/BasicSpec/__direct/check @@ -7,9 +7,27 @@ ImplicitChain.g invalid because implicitly[II] ^ newSource1.scala:6: error: type mismatch; - FoundReq.L|FoundReq.R + FoundReq.L┃FoundReq.R f(new L) ^ +newSource1.scala:13: error: type mismatch; + Long.VeryLong[ + Long.VeryLong[ + found : Long.VeryLong[ + Long.VeryLong[ + Long.VeryLong[Long.VeryLong[Long.VeryLong[Long.VeryLong[String]]]] + ] + ] + ━━━━━━━━: + required: Long.VeryLong2[ + Long.VeryLong[ + Long.VeryLong[Long.VeryLong[Long.VeryLong[Long.VeryLong[String]]]] + ] + ] + ] + ] + val str: Req = ??? : Found + ^ newSource1.scala:4: error: implicit error; !I e: Long.VeryLong[ @@ -24,11 +42,11 @@ newSource1.scala:4: error: implicit error; implicitly[VeryLong[ ^ newSource1.scala:7: error: type mismatch; - Compound.y.type|String + Compound.y.type┃String f(y) ^ newSource1.scala:10: error: type mismatch; - Compound.T| with Int|String + Compound.T┃ with Int┃String f(z) ^ newSource1.scala:4: error: implicit error; @@ -76,7 +94,7 @@ newSource1.scala:16: error: type mismatch; Long.VeryLong[ Long.VeryLong[ Long.VeryLong[ - Long.VeryLong[Long.VeryLong[Long.VeryLong[Long.VeryLong[Int|String]]]] + Long.VeryLong[Long.VeryLong[Long.VeryLong[Long.VeryLong[Int┃String]]]] ] ] ] @@ -85,7 +103,7 @@ newSource1.scala:16: error: type mismatch; ) = x ^ newSource1.scala:11: error: type mismatch; - B.this.t1.type|B.this.t.TT + B.this.t1.type┃B.this.t.TT val t2: t.TT = t1 ^ newSource1.scala:7: error: implicit error; @@ -155,22 +173,22 @@ Aux.f invalid because newSource1.scala:11: error: type mismatch; Refined.A with Refined.B with - Refined.E|Refined.C with - Refined.F| { - type X = Int|String; + Refined.E┃Refined.C with + Refined.F┃ { + type X = Int┃String; type Y = String; - type Z = |String + type Z = ┃String } f(x) ^ newSource1.scala:21: error: type mismatch; - Refined.E|Refined.C with - Refined.F| with + Refined.E┃Refined.C with + Refined.F┃ with Refined.Sub1.A with Refined.Sub1.Sub2.B { - type X = Int|String; + type X = Int┃String; type Y = String; - type Z = |String + type Z = ┃String } f(x) ^ @@ -179,19 +197,19 @@ newSource1.scala:10: error: implicit error; implicitly[NodeLt[Int]] ^ newSource1.scala:12: error: type mismatch; - Int(1)|Refined.Node{type T = _$2} forSome { type _$2 <: Int } + Int(1)┃Refined.Node{type T = _$2} forSome { type _$2 <: Int } val k: NodeLt[Int] = 1 ^ newSource1.scala:25: error: type mismatch; - C.X.Y.T|B.X.Y.T + C.X.Y.T┃B.X.Y.T f(x: C.X.Y.T) ^ newSource1.scala:6: error: type mismatch; - Int|(=> Foo.A) => Foo.B + Int┃(=> Foo.A) => Foo.B f(1: Int) ^ newSource1.scala:3: error: type mismatch; - String|Tuple1[String] + String┃Tuple1[String] val a: Tuple1[String] = "Tuple1": String ^ newSource1.scala:7: error: implicit error; diff --git a/core/src/test/resources/splain/builtin/MaxRefinedSpec/__direct/check b/core/src/test/resources/splain/builtin/MaxRefinedSpec/__direct/check index 74481c8..b0a95d4 100644 --- a/core/src/test/resources/splain/builtin/MaxRefinedSpec/__direct/check +++ b/core/src/test/resources/splain/builtin/MaxRefinedSpec/__direct/check @@ -1,11 +1,11 @@ newSource1.scala:7: error: type mismatch; - TruncRefined.D|TruncRefined.C { + TruncRefined.D┃TruncRefined.C { type X = TruncRefined.C; type Y = TruncRefined.D } f(new D { type X = C; type Y = D }) ^ newSource1.scala:7: error: type mismatch; - TruncRefined.D|TruncRefined.C {...} + TruncRefined.D┃TruncRefined.C {...} f(new D { type X = C; type Y = D }) ^ \ No newline at end of file diff --git a/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/code.scala b/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/code.scala index b3ffc44..9eebb89 100644 --- a/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/code.scala +++ b/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/code.scala @@ -4,7 +4,7 @@ object Annotation { trait Arg - @implicitNotFound("A\n | B\n | C") + @implicitNotFound("A\n ┃ B\n ┃ C") trait F[A] trait G[A] diff --git a/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/error b/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/error index d9cf8f2..2623d7f 100644 --- a/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/error +++ b/core/src/test/resources/splain/plugin/PluginSpec/implicit-ctrl-char/error @@ -3,8 +3,8 @@ newSource1.scala:25: error: implicit error; Annotation.f invalid because !I ev: Annotation.F[Annotation.Arg] A - | B - | C + ┃ B + ┃ C implicitly[G[Arg]] ^ \ No newline at end of file diff --git a/core/src/test/resources/splain/plugin/ShapelessSpec/record/error b/core/src/test/resources/splain/plugin/ShapelessSpec/record/error index 3276e41..b231904 100644 --- a/core/src/test/resources/splain/plugin/ShapelessSpec/record/error +++ b/core/src/test/resources/splain/plugin/ShapelessSpec/record/error @@ -1,7 +1,7 @@ newSource1.scala:26: error: type mismatch; ('sym ->> String) :: ("str" ->> ShapelessRecord.Value.type) :: - (ShapelessRecord.Key.type ->> Long|Int) :: + (ShapelessRecord.Key.type ->> Long┃Int) :: shapeless.HNil show(a) ^ \ No newline at end of file diff --git a/core/src/test/resources/splain/plugin/VTypeDetailPositionSpec/__direct/check b/core/src/test/resources/splain/plugin/VTypeDetailPositionSpec/__direct/check index 24444a5..60a24de 100644 --- a/core/src/test/resources/splain/plugin/VTypeDetailPositionSpec/__direct/check +++ b/core/src/test/resources/splain/plugin/VTypeDetailPositionSpec/__direct/check @@ -5,7 +5,7 @@ newSource1.scala:12: error: implicit error; implicitly[e1.VV =:= String] ^ newSource1.scala:13: error: type mismatch; - String|Diff.e1.VV + String┃Diff.e1.VV val x: e1.VV = ??? : String ^ newSource1.scala:12: error: implicit error; @@ -15,6 +15,6 @@ newSource1.scala:12: error: implicit error; implicitly[e1.VV =:= String] ^ newSource1.scala:13: error: type mismatch; - String|Diff.e1.VV (defined at newSource1.scala:9:10) + String┃Diff.e1.VV (defined at newSource1.scala:9:10) val x: e1.VV = ??? : String ^ diff --git a/core/src/test/resources/splain/plugin/VTypeDetailReductionSpec/__direct/check b/core/src/test/resources/splain/plugin/VTypeDetailReductionSpec/__direct/check index e83b701..9ac56a8 100644 --- a/core/src/test/resources/splain/plugin/VTypeDetailReductionSpec/__direct/check +++ b/core/src/test/resources/splain/plugin/VTypeDetailReductionSpec/__direct/check @@ -5,7 +5,7 @@ newSource1.scala:8: error: implicit error; implicitly[vecInt.Head =:= Option[String]] ^ newSource1.scala:10: error: type mismatch; - Option[String|Int] + Option[String┃Int] val x: vecInt.Head = ??? : Option[String] ^ newSource1.scala:8: error: implicit error; @@ -17,7 +17,7 @@ newSource1.scala:8: error: implicit error; implicitly[vecInt.Head =:= Option[String]] ^ newSource1.scala:10: error: type mismatch; - Option[String|Int] + Option[String┃Int] ――(right side reduced from) FoundReqVsImplicit.vecInt.Head val x: vecInt.Head = ??? : Option[String] diff --git a/core/src/test/resources/splain/plugin/VTypeDetailSpec/__direct/check b/core/src/test/resources/splain/plugin/VTypeDetailSpec/__direct/check index 0956114..193117b 100644 --- a/core/src/test/resources/splain/plugin/VTypeDetailSpec/__direct/check +++ b/core/src/test/resources/splain/plugin/VTypeDetailSpec/__direct/check @@ -1,6 +1,6 @@ newSource1.scala:15: error: type mismatch; - Test.F[Test.a.type|a.type] + Test.F[Test.a.type┃a.type] wrongf(new A)(new F[AA]) ^ newSource1.scala:16: error: implicit error; @@ -9,7 +9,9 @@ newSource1.scala:16: error: implicit error; ^ newSource1.scala:15: error: type mismatch; Test.F[ - Test.a.type (with underlying type Test.A)|a.type (with underlying type a.type) + found : Test.a.type (with underlying type Test.A) + ━━━━━━━━: + required: a.type (with underlying type a.type) ] wrongf(new A)(new F[AA]) ^ @@ -19,7 +21,9 @@ newSource1.scala:16: error: implicit error; ^ newSource1.scala:15: error: type mismatch; Test.F[ - Test.a.type (with underlying type Test.A)|a.type (with underlying type a.type) where val a: Test.A + found : Test.a.type (with underlying type Test.A) + ━━━━━━━━: + required: a.type (with underlying type a.type) where val a: Test.A ] wrongf(new A)(new F[AA]) ^ @@ -29,7 +33,9 @@ newSource1.scala:16: error: implicit error; ^ newSource1.scala:15: error: type mismatch; Test.F[ - Test.a.type (with underlying type Test.A)|a.type (with underlying type a.type) where val a: Test.A + found : Test.a.type (with underlying type Test.A) + ━━━━━━━━: + required: a.type (with underlying type a.type) where val a: Test.A ――(left side reduced from) Test.AA ] @@ -42,7 +48,10 @@ newSource1.scala:16: error: implicit error; newSource1.scala:15: error: type mismatch; Test.F[ - Test.a.type (with underlying type Test.A)|a.type (with underlying type a.type) where val a: Test.A (defined at newSource1.scala:13:18) + found : Test.a.type (with underlying type Test.A) + ━━━━━━━━: + required: a.type (with underlying type a.type) where val a: Test.A + ――(defined at newSource1.scala:13:18) ――(left side reduced from) Test.AA ] @@ -60,7 +69,10 @@ newSource1.scala:16: error: implicit error; newSource1.scala:15: error: type mismatch; Test.F[ - Test.a.type (with underlying type Test.A)|a.type (with underlying type a.type) where val a: Test.A (defined at newSource1.scala:13:18) + found : Test.a.type (with underlying type Test.A) + ━━━━━━━━: + required: a.type (with underlying type a.type) where val a: Test.A + ――(defined at newSource1.scala:13:18) ――(left side reduced from) Test.AA (which expands to) Test.a.type @@ -81,7 +93,7 @@ newSource1.scala:5: error: implicit error; implicitly[K] ^ newSource1.scala:7: error: type mismatch; - String("abc")|String :: Int :: Boolean + String("abc")┃String :: Int :: Boolean def v: K = "abc" ^ newSource1.scala:5: error: implicit error; @@ -89,7 +101,7 @@ newSource1.scala:5: error: implicit error; implicitly[K] ^ newSource1.scala:7: error: type mismatch; - String("abc")|String :: Int :: Boolean + String("abc")┃String :: Int :: Boolean (reduced from) { Test.K } ――(right side reduced from) Test.K def v: K = "abc" diff --git a/core/src/test/resources/splain/plugin/VTypeDiffsDetailSpec/__direct/check b/core/src/test/resources/splain/plugin/VTypeDiffsDetailSpec/__direct/check index df4bedf..a8408d9 100644 --- a/core/src/test/resources/splain/plugin/VTypeDiffsDetailSpec/__direct/check +++ b/core/src/test/resources/splain/plugin/VTypeDiffsDetailSpec/__direct/check @@ -1,9 +1,9 @@ newSource1.scala:6: error: type mismatch; - Long|Long + Long┃Long else add2(x.head, y.head) :: add(x.tail, y.tail) ^ newSource1.scala:6: error: type mismatch; - Long|Long + Long┃Long else add2(x.head, y.head) :: add(x.tail, y.tail) ^ newSource1.scala:16: error: implicit error; @@ -19,11 +19,11 @@ newSource1.scala:27: error: implicit error; add2(x.head) ^ newSource1.scala:6: error: type mismatch; - Long(in method add)|scala.Long + Long(in method add)┃scala.Long else add2(x.head, y.head) :: add(x.tail, y.tail) ^ newSource1.scala:6: error: type mismatch; - Long(in method add)|scala.Long + Long(in method add)┃scala.Long else add2(x.head, y.head) :: add(x.tail, y.tail) ^ newSource1.scala:16: error: implicit error; @@ -40,15 +40,15 @@ newSource1.scala:27: error: implicit error; ^ newSource1.scala:6: error: type mismatch; - Long(in method add)|scala.Long - ――(comparing |) + Long(in method add)┃scala.Long + ――(comparing ) found : Long(in method add) required: scala.Long else add2(x.head, y.head) :: add(x.tail, y.tail) ^ newSource1.scala:6: error: type mismatch; - Long(in method add)|scala.Long - ――(comparing |) + Long(in method add)┃scala.Long + ――(comparing ) found : Long(in method add) required: scala.Long else add2(x.head, y.head) :: add(x.tail, y.tail) diff --git a/core/src/test/resources/splain/plugin/ZIOSpec/zlayer/error b/core/src/test/resources/splain/plugin/ZIOSpec/zlayer/error index fafb69a..4e78752 100644 --- a/core/src/test/resources/splain/plugin/ZIOSpec/zlayer/error +++ b/core/src/test/resources/splain/plugin/ZIOSpec/zlayer/error @@ -2,7 +2,7 @@ newSource1.scala:19: error: type mismatch; zio.ZLayer[ Any, Nothing, - |zio.Has[layers.Service4] with + ┃zio.Has[layers.Service4] with zio.Has[layers.Service1] with zio.Has[layers.Service2] with zio.Has[layers.Service3] diff --git a/core/src/test/scala/splain/builtin/BasicSpec.scala b/core/src/test/scala/splain/builtin/BasicSpec.scala index 9c1efdc..5659261 100644 --- a/core/src/test/scala/splain/builtin/BasicSpec.scala +++ b/core/src/test/scala/splain/builtin/BasicSpec.scala @@ -6,9 +6,14 @@ class BasicSpec extends SpecBase.Direct with BasicFixture { check(chain) - check(foundReq) + describe("#121") { - check(LongArg) + check(foundReq) + + check(longFoundReq) + } + + check(longArg) describe("#34") { check(compoundDiff, numberOfErrors = 2) diff --git a/core/src/test/scala/splain/test/TryCompileSpec.scala b/core/src/test/scala/splain/test/TryCompileSpec.scala index 701ca7c..2fe6b77 100644 --- a/core/src/test/scala/splain/test/TryCompileSpec.scala +++ b/core/src/test/scala/splain/test/TryCompileSpec.scala @@ -58,6 +58,7 @@ class TryCompileSpec extends SpecBase { """ |Success | --- + | |""".stripMargin } diff --git a/core/src/testFixtures/scala/splain/TestHelpers.scala b/core/src/testFixtures/scala/splain/TestHelpers.scala index 2bbdb63..c255e3a 100644 --- a/core/src/testFixtures/scala/splain/TestHelpers.scala +++ b/core/src/testFixtures/scala/splain/TestHelpers.scala @@ -131,7 +131,9 @@ trait TestHelpers extends Suite { def stripSpaceAtEnd(v: String): String = { - v.reverse.dropWhile(v => v == ' ').reverse + v.reverse.dropWhile { v => + (v == ' ') || (v == '\r') + }.reverse } def canonize(v: String): String = { @@ -215,7 +217,7 @@ trait TestHelpers extends Suite { regex ) .toSeq - .filter(_.nonEmpty) + .filter(_.trim.nonEmpty) .map { line => (startsWith + line).trim } diff --git a/core/src/testFixtures/scala/splain/builtin/BasicFixture.scala b/core/src/testFixtures/scala/splain/builtin/BasicFixture.scala index 9438521..9e1b142 100644 --- a/core/src/testFixtures/scala/splain/builtin/BasicFixture.scala +++ b/core/src/testFixtures/scala/splain/builtin/BasicFixture.scala @@ -1,7 +1,5 @@ package splain.builtin -object BasicFixture extends BasicFixture - trait BasicFixture { // from scalac tests START HERE @@ -34,7 +32,7 @@ object FoundReq } """ - final val LongArg = + final val longArg = """ object Long { class VeryLong[T] @@ -43,6 +41,24 @@ object Long { VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[String]]]]]]] ]] } +""" + + final val longFoundReq = + """ +object Long { + class VeryLong[T] + class VeryLong2[T] + + type Found = VeryLong[ + VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[String]]]]]]] + ] + + type Req = VeryLong[ + VeryLong[VeryLong2[VeryLong[VeryLong[VeryLong[VeryLong[VeryLong[String]]]]]]] + ] + + val str: Req = ??? : Found +} """ final val compoundDiff = diff --git a/dev/gradle-versions.sh b/dev/gradle-versions.sh index e751b94..9025897 100755 --- a/dev/gradle-versions.sh +++ b/dev/gradle-versions.sh @@ -5,6 +5,6 @@ FWDIR="$( pwd )" -${FWDIR}/gradlew wrapper --gradle-version=8.4 +${FWDIR}/gradlew wrapper --gradle-version=8.5 ${FWDIR}/gradlew dependencyUpdates "$@" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135..d64cd49 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3fa8f86..1af9e09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 6689b85..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/testing/acceptance/src/test/resources/splain/builtin/BasicSpec/__direct/check b/testing/acceptance/src/test/resources/splain/builtin/BasicSpec/__direct/check index df600d5..a485bcf 100644 --- a/testing/acceptance/src/test/resources/splain/builtin/BasicSpec/__direct/check +++ b/testing/acceptance/src/test/resources/splain/builtin/BasicSpec/__direct/check @@ -7,9 +7,41 @@ ImplicitChain.g invalid because implicitly[II] ^ newSource1.scala:6: error: type mismatch; - splain.acceptance.builtin.StaticBasicSpec.FoundReq.L|splain.acceptance.builtin.StaticBasicSpec.FoundReq.R + found : splain.acceptance.builtin.StaticBasicSpec.FoundReq.L + ━━━━━━━━: + required: splain.acceptance.builtin.StaticBasicSpec.FoundReq.R f(new L) ^ +newSource1.scala:13: error: type mismatch; + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + found : splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[String] + ] + ] + ] + ] + ] + ━━━━━━━━: + required: splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong2[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[String] + ] + ] + ] + ] + ] + ] + ] + val str: Req = ??? : Found + ^ newSource1.scala:4: error: implicit error; !I e: splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ @@ -30,7 +62,7 @@ newSource1.scala:4: error: implicit error; implicitly[VeryLong[ ^ newSource1.scala:7: error: type mismatch; - splain.acceptance.builtin.StaticBasicSpec.Compound.y.type|String + splain.acceptance.builtin.StaticBasicSpec.Compound.y.type┃String f(y) ^ newSource1.scala:4: error: implicit error; @@ -93,7 +125,7 @@ newSource1.scala:16: error: type mismatch; splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[ - splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[Int|String] + splain.acceptance.builtin.StaticBasicSpec.Long.VeryLong[Int┃String] ] ] ] @@ -105,7 +137,7 @@ newSource1.scala:16: error: type mismatch; ) = x ^ newSource1.scala:11: error: type mismatch; - B.this.t1.type|B.this.t.TT + B.this.t1.type┃B.this.t.TT val t2: t.TT = t1 ^ newSource1.scala:7: error: implicit error; @@ -189,11 +221,13 @@ Aux.f invalid because newSource1.scala:11: error: type mismatch; splain.acceptance.builtin.StaticBasicSpec.Refined.A with splain.acceptance.builtin.StaticBasicSpec.Refined.B with - splain.acceptance.builtin.StaticBasicSpec.Refined.E|splain.acceptance.builtin.StaticBasicSpec.Refined.C with - splain.acceptance.builtin.StaticBasicSpec.Refined.F| { - type X = Int|String; + found : splain.acceptance.builtin.StaticBasicSpec.Refined.E + ━━━━━━━━: + required: splain.acceptance.builtin.StaticBasicSpec.Refined.C with + splain.acceptance.builtin.StaticBasicSpec.Refined.F┃ { + type X = Int┃String; type Y = String; - type Z = |String + type Z = ┃String } f(x) ^ @@ -202,15 +236,17 @@ newSource1.scala:10: error: implicit error; implicitly[NodeLt[Int]] ^ newSource1.scala:25: error: type mismatch; - C.X.Y.T|B.X.Y.T + C.X.Y.T┃B.X.Y.T f(x: C.X.Y.T) ^ newSource1.scala:6: error: type mismatch; - Int|(=> splain.acceptance.builtin.StaticBasicSpec.Foo.A) => splain.acceptance.builtin.StaticBasicSpec.Foo.B + found : Int + ━━━━━━━━: + required: (=> splain.acceptance.builtin.StaticBasicSpec.Foo.A) => splain.acceptance.builtin.StaticBasicSpec.Foo.B f(1: Int) ^ newSource1.scala:3: error: type mismatch; - String|Tuple1[String] + String┃Tuple1[String] val a: Tuple1[String] = "Tuple1": String ^ newSource1.scala:7: error: implicit error; diff --git a/testing/acceptance/src/test/scala/splain/acceptance/builtin/StaticBasicSpec.scala b/testing/acceptance/src/test/scala/splain/acceptance/builtin/StaticBasicSpec.scala index f3c32d3..e529cd8 100644 --- a/testing/acceptance/src/test/scala/splain/acceptance/builtin/StaticBasicSpec.scala +++ b/testing/acceptance/src/test/scala/splain/acceptance/builtin/StaticBasicSpec.scala @@ -1,20 +1,29 @@ package splain.acceptance.builtin import splain.acceptance.Acceptance +import splain.builtin.BasicFixture -object StaticBasicSpec {} +object StaticBasicSpec { + + object Delegate extends BasicFixture +} class StaticBasicSpec extends Acceptance.SpecBase { override lazy val suiteCanonicalName: String = "splain.builtin.BasicSpec" - import splain.builtin.BasicFixture._ + import StaticBasicSpec.Delegate._ check(chain) - check(foundReq) + describe("#121") { + + check(foundReq) + + check(longFoundReq) + } - check(LongArg) + check(longArg) describe("#34") { check(compoundDiff, numberOfErrors = 2)