Skip to content

Commit

Permalink
tek#43 - part 1
Browse files Browse the repository at this point in the history
add 4 test cases for singleton & witness value types

base and plugin now defaults to default tests and bytecode directories, allowing tests to be run in IDE

add special handling for SingletonType (for displaying term.type) & RefinedType (for displaying Witness value type)
  • Loading branch information
Peng Cheng committed Feb 2, 2021
1 parent 382e0b0 commit fef1ccc
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 22 deletions.
70 changes: 53 additions & 17 deletions src/main/scala/splain/format/Formatting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,6 @@ with ImplicitMsgCompat
.takeWhile(_ != "type")
.filterNot(_.contains("$"))

def modulePath: (Type, Symbol) => List[String] = {
case (TypeRef(pre, _, _), _) if !pre.toString.isEmpty =>
sanitizePath(pre.toString.split("\\.").toList)
case (SingleType(_, _), sym) =>
symbolPath(sym).dropRight(1)
case (_, _) =>
Nil
}

def pathPrefix: List[String] => String = {
case Nil =>
""
Expand All @@ -141,7 +132,7 @@ with ImplicitMsgCompat
}

def qualifiedName(path: List[String], name: String): String =
s"${pathPrefix(path)}$name"
s"${pathPrefix(path)}$name"

def stripModules(path: List[String], name: String): Option[Int] => String = {
case Some(keep) =>
Expand All @@ -150,14 +141,59 @@ with ImplicitMsgCompat
name
}

case class TypeParts(sym: Symbol, tt: Type) {

def modulePath: List[String] = (tt, sym) match {
case (TypeRef(pre, _, _), _) if !pre.toString.isEmpty =>
sanitizePath(pre.toString.split("\\.").toList)
case (SingleType(_, _), sym) =>
symbolPath(sym).dropRight(1)
case (_, _) =>
Nil
}

def ownerPath: List[String] = {
val chain = sym.ownerChain.reverse
val parts = chain.map(_.name.decodedName.toString)
val (paths, names) = parts.splitAt(
Math.max(0,parts.size - 1)
)
paths
}

def shortName: String = {
val prefixes = tt.prefixString.split('.').dropRight(1)
val prefix = prefixes.mkString(".") + "."
val name = tt.safeToString
name.stripPrefix(prefix)
}
}

def stripType(tpe: Type): (List[String], String) = {
val sym = if (tpe.takesTypeArgs) tpe.typeSymbolDirect else tpe.typeSymbol
val symName = sym.name.decodedName.toString
val path = modulePath(tpe, sym)
val name =
if (sym.isModuleClass) s"$symName.type"
else symName
(path, name)
tpe match {
case tt: SingletonType =>
val sym = tt.termSymbol
val parts = TypeParts(sym, tt)

parts.modulePath -> parts.shortName

case tt: RefinedType =>
val sym = tt.typeSymbol
val parts = TypeParts(sym, tt)

parts.modulePath -> parts.shortName

case _ =>
// TODO: should this also use TypeParts ?
val sym = if (tpe.takesTypeArgs) tpe.typeSymbolDirect else tpe.typeSymbol
val symName = sym.name.decodedName.toString
val parts = TypeParts(sym, tpe)

val name =
if (sym.isModuleClass) s"$symName.type"
else symName
(parts.modulePath, name)
}
}

def formatNormalSimple(tpe: Type): (List[String], String) =
Expand Down
23 changes: 21 additions & 2 deletions src/test/scala/splain/ErrorsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import org.specs2._

object Helpers
{
def base = System.getProperty("splain.tests")
lazy val userDir = System.getProperty("user.dir").stripSuffix("/")

def base = Option(System.getProperty("splain.tests"))
.getOrElse(userDir + "/" + "tests")

def fileContent(name: String, fname: String): Path = {
FileSystems.getDefault.getPath(base, name, fname)
Expand Down Expand Up @@ -38,7 +41,14 @@ import types._

val cm = universe.runtimeMirror(getClass.getClassLoader)

val plugin = System.getProperty("splain.jar")
val plugin = Option(System.getProperty("splain.jar")).getOrElse {
val dir = FileSystems.getDefault.getPath(userDir + "/target/scala-2.13")
val file = Files.list(dir).toArray
.map(v => v.asInstanceOf[Path])
.filter(v => v.toString.endsWith(".jar")).head

file.toAbsolutePath.toString
}

val opts = s"-Xplugin:$plugin -P:splain:color:false -P:splain:bounds -P:splain:tree:false"

Expand Down Expand Up @@ -84,6 +94,7 @@ extends Specification
class ErrorsSpec
extends SpecBase
{

def is = s2"""
implicit resolution chains ${checkError("chain")}
found/required type diff ${checkError("foundreq")}
Expand All @@ -102,7 +113,15 @@ extends SpecBase
truncate refined type ${checkError("truncrefined", "-P:splain:truncrefined:10")}
byname higher order ${checkError("byname-higher")}
Tuple1 ${checkError("tuple1")}
single types ${checkError("single")}
single types in function ${checkError("single-fn")}
single types with free symbol ${checkError("single-free")}
witness value types ${checkError("witness-value")}
"""

// def is = s2"""
// single types ${checkError("witness-value")}
// """
}

class DevSpec
Expand Down
2 changes: 1 addition & 1 deletion tests/byname-higher/code.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ object Foo
type A
type B
def f(g: (=> A) => B): Unit = ()
f(1)
f(1: Int)
}
2 changes: 1 addition & 1 deletion tests/disambiguate/code.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ object A
}
def f(a: B.X.Y.T): Unit = ()
val x: C.X.Y.T = ???
f(x)
f(x: C.X.Y.T)
}
12 changes: 12 additions & 0 deletions tests/single-fn/code.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import shapeless._
import shapeless.ops.hlist._

object SingleImp
{
def fn(): Unit= {
val a = 1
val b = 2

implicitly[a.type *** b.type]
}
}
2 changes: 2 additions & 0 deletions tests/single-fn/error
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
implicit error;
!I e: a.type *** b.type
10 changes: 10 additions & 0 deletions tests/single-free/code.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import shapeless._
import shapeless.ops.hlist._

object SingleImp
{
def fn[A, B](a: A, b: B) = {

implicitly[a.type *** b.type]
}
}
2 changes: 2 additions & 0 deletions tests/single-free/error
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
implicit error;
!I e: a.type *** b.type
10 changes: 10 additions & 0 deletions tests/single/code.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import shapeless._
import shapeless.ops.hlist._

object SingleImp
{
val a = 1
val b = 2

implicitly[a.type *** b.type]
}
2 changes: 2 additions & 0 deletions tests/single/error
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
implicit error;
!I e: a.type *** b.type
2 changes: 1 addition & 1 deletion tests/tuple1/code.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
object Tup1
{
val a: Tuple1[String] = "Tuple1"
val a: Tuple1[String] = "Tuple1": String
}
9 changes: 9 additions & 0 deletions tests/witness-value/code.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import shapeless._
import shapeless.ops.hlist._

object WitnessImp
{
def fn[A, B](a: A, b: B)(implicit ev: A *** B) = ???

fn(Witness(3).value, Witness(4).value)
}
2 changes: 2 additions & 0 deletions tests/witness-value/error
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
implicit error;
!I ev: Int(3) *** Int(4)

0 comments on commit fef1ccc

Please sign in to comment.