Skip to content

Commit

Permalink
Merge pull request #264 from zehkae/issue101
Browse files Browse the repository at this point in the history
Fix #101: Remove SimpleType
  • Loading branch information
jvican authored Apr 4, 2017
2 parents c9d567f + fcae48d commit 172cc90
Show file tree
Hide file tree
Showing 14 changed files with 145 additions and 83 deletions.
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,10 @@ lazy val zincBenchmarks = (project in internalPath / "zinc-benchmarks").
enablePlugins(JmhPlugin).
settings(
name := "Benchmarks of Zinc and the compiler bridge",
libraryDependencies +=
libraryDependencies ++= Seq(
"org.eclipse.jgit" % "org.eclipse.jgit" % "4.6.0.201612231935-r",
"net.openhft" % "affinity" % "3.0.6"
),
scalaVersion := scala212,
crossScalaVersions := Seq(scala211, scala212),
publish := {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,6 @@ class ExtractAPI[GlobalType <: Global](
if (sym == NoSymbol || sym.isRoot || sym.isEmptyPackageClass || sym.isRootPackage) postfix
else pathComponents(sym.owner, new xsbti.api.Id(simpleName(sym)) :: postfix)
}
private def simpleType(in: Symbol, t: Type): SimpleType =
processType(in, t) match {
case s: SimpleType => s
case x => log("Not a simple type:\n\tType: " + t + " (" + t.getClass + ")\n\tTransformed: " + x.getClass); Constants.emptyType
}
private def types(in: Symbol, t: List[Type]): Array[xsbti.api.Type] = t.toArray[Type].map(processType(in, _))
private def projectionType(in: Symbol, pre: Type, sym: Symbol) =
{
Expand All @@ -192,7 +187,7 @@ class ExtractAPI[GlobalType <: Global](
reference(sym)
}
} else if (sym.isRoot || sym.isRootPackage) Constants.emptyType
else new xsbti.api.Projection(simpleType(in, pre), simpleName(sym))
else new xsbti.api.Projection(processType(in, pre), simpleName(sym))
}
private def reference(sym: Symbol): xsbti.api.ParameterRef = new xsbti.api.ParameterRef(tparamID(sym))

Expand Down
82 changes: 39 additions & 43 deletions internal/compiler-interface/src/main/contraband/type.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,47 @@

"types": [
{
"name": "SimpleType",
"name": "Projection",
"namespace": "xsbti.api",
"target": "Java",
"type": "interface",

"types": [
{
"name": "Projection",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "prefix", "type": "SimpleType" },
{ "name": "id", "type": "String" }
]
},
{
"name": "ParameterRef",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "id", "type": "String" }
]
},
{
"name": "Singleton",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "path", "type": "Path" }
]
},
{ "name": "EmptyType", "namespace": "xsbti.api", "target": "Java", "type": "record" },
{
"name": "Parameterized",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "baseType", "type": "SimpleType" },
{ "name": "typeArguments", "type": "Type*" }
]
}
"type": "record",
"fields": [
{ "name": "prefix", "type": "Type" },
{ "name": "id", "type": "String" }
]
},
{
"name": "ParameterRef",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "id", "type": "String" }
]
},
{
"name": "Singleton",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "path", "type": "Path" }
]
},
{
"name": "EmptyType",
"namespace": "xsbti.api",
"target": "Java",
"type": "record"
},
{
"name": "Parameterized",
"namespace": "xsbti.api",
"target": "Java",
"type": "record",
"fields": [
{ "name": "baseType", "type": "Type" },
{ "name": "typeArguments", "type": "Type*" }
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ object ClassToAPI {
private val emptyTypeArray = new Array[xsbti.api.Type](0)
private val emptyAnnotationArray = new Array[xsbti.api.Annotation](0)
private val emptyTypeParameterArray = new Array[xsbti.api.TypeParameter](0)
private val emptySimpleTypeArray = new Array[xsbti.api.SimpleType](0)
private val lzyEmptyTpeArray = lzyS(emptyTypeArray)
private val lzyEmptyDefArray = lzyS(new Array[xsbti.api.ClassDefinition](0))

Expand Down Expand Up @@ -239,7 +238,7 @@ object ClassToAPI {
def parameter(annots: Array[Annotation], parameter: Type, varArgs: Boolean): api.MethodParameter =
new api.MethodParameter("", annotated(reference(parameter), annots), false, if (varArgs) api.ParameterModifier.Repeated else api.ParameterModifier.Plain)

def annotated(t: api.SimpleType, annots: Array[Annotation]): api.Type = (
def annotated(t: api.Type, annots: Array[Annotation]): api.Type = (
if (annots.length == 0) t
else new api.Annotated(t, annotations(annots))
)
Expand Down Expand Up @@ -306,7 +305,7 @@ object ClassToAPI {
*
* We need this logic to trigger recompilation due to changes to pattern exhaustivity checking results.
*/
private def childrenOfSealedClass(c: Class[_]): Seq[api.SimpleType] = if (!c.isEnum) emptySimpleTypeArray else {
private def childrenOfSealedClass(c: Class[_]): Seq[api.Type] = if (!c.isEnum) emptyTypeArray else {
// Calling getCanonicalName() on classes from enum constants yields same string as enumClazz.getCanonicalName
// Moreover old behaviour create new instance of enum - what may fail (e.g. in static block )
Array(reference(c))
Expand All @@ -316,14 +315,14 @@ object ClassToAPI {
def javaAnnotation(s: String): api.AnnotationArgument =
new api.AnnotationArgument("toString", s)

def array(tpe: api.Type): api.SimpleType = new api.Parameterized(ArrayRef, Array(tpe))
def reference(c: Class[_]): api.SimpleType =
def array(tpe: api.Type): api.Type = new api.Parameterized(ArrayRef, Array(tpe))
def reference(c: Class[_]): api.Type =
if (c.isArray) array(reference(c.getComponentType))
else if (c.isPrimitive) primitive(c.getName)
else reference(classCanonicalName(c))

// does not handle primitives
def reference(s: String): api.SimpleType =
def reference(s: String): api.Type =
{
val (pkg, cls) = packageAndName(s)
pkg match {
Expand All @@ -340,7 +339,7 @@ object ClassToAPI {
val base = reference(t.getRawType)
new api.Parameterized(base, args)
}
def reference(t: Type): api.SimpleType =
def reference(t: Type): api.Type =
t match {
case _: WildcardType => reference("_")
case tv: TypeVariable[_] => new api.ParameterRef(typeVariable(tv))
Expand Down Expand Up @@ -381,7 +380,7 @@ object ClassToAPI {
private[this] def PrimitiveNames = Seq("boolean", "byte", "char", "short", "int", "long", "float", "double")
private[this] def PrimitiveMap = PrimitiveNames.map(j => (j, j.capitalize)) :+ ("void" -> "Unit")
private[this] val PrimitiveRefs = PrimitiveMap.map { case (n, sn) => (n, reference("scala." + sn)) }.toMap
def primitive(name: String): api.SimpleType = PrimitiveRefs(name)
def primitive(name: String): api.Type = PrimitiveRefs(name)

// Workarounds for https://github.com/sbt/sbt/issues/1035
// these catch the GenericSignatureFormatError and return the erased type
Expand Down
37 changes: 16 additions & 21 deletions internal/zinc-apiinfo/src/main/scala/xsbt/api/SameAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,20 @@ class SameAPI(includePrivate: Boolean, includeParamNames: Boolean) {
def sameType(a: Type, b: Type): Boolean =
samePending(a, b)(sameTypeDirect)
def sameTypeDirect(a: Type, b: Type): Boolean =
(a, b) match {
case (sa: SimpleType, sb: SimpleType) => debug(sameSimpleTypeDirect(sa, sb), "Different simple types: " + DefaultShowAPI(sa) + " and " + DefaultShowAPI(sb))
case (ca: Constant, cb: Constant) => debug(sameConstantType(ca, cb), "Different constant types: " + DefaultShowAPI(ca) + " and " + DefaultShowAPI(cb))
case (aa: Annotated, ab: Annotated) => debug(sameAnnotatedType(aa, ab), "Different annotated types")
case (sa: Structure, sb: Structure) => debug(sameStructureDirect(sa, sb), "Different structure type")
case (ea: Existential, eb: Existential) => debug(sameExistentialType(ea, eb), "Different existential type")
case (pa: Polymorphic, pb: Polymorphic) => debug(samePolymorphicType(pa, pb), "Different polymorphic type")
case _ => differentCategory("type", a, b)
{
(a, b) match {
case (pa: Projection, pb: Projection) => debug(sameProjection(pa, pb), "Different projection")
case (pa: ParameterRef, pb: ParameterRef) => debug(sameParameterRef(pa, pb), "Different parameter ref")
case (pa: Polymorphic, pb: Polymorphic) => debug(samePolymorphicType(pa, pb), "Different polymorphic type")
case (pa: Parameterized, pb: Parameterized) => debug(sameParameterized(pa, pb), "Different parameterized")
case (sa: Singleton, sb: Singleton) => debug(sameSingleton(sa, sb), "Different singleton")
case (ca: Constant, cb: Constant) => debug(sameConstantType(ca, cb), "Different constant types: " + DefaultShowAPI(ca) + " and " + DefaultShowAPI(cb))
case (aa: Annotated, ab: Annotated) => debug(sameAnnotatedType(aa, ab), "Different annotated types")
case (sa: Structure, sb: Structure) => debug(sameStructureDirect(sa, sb), "Different structure type")
case (ea: Existential, eb: Existential) => debug(sameExistentialType(ea, eb), "Different existential type")
case (_: EmptyType, _: EmptyType) => true
case _ => differentCategory("type", a, b)
}
}

def sameConstantType(ca: Constant, cb: Constant): Boolean =
Expand Down Expand Up @@ -296,28 +302,17 @@ class SameAPI(includePrivate: Boolean, includeParamNames: Boolean) {
def sameMembers(a: Seq[Definition], b: Seq[Definition]): Boolean =
sameDefinitions(a, b, topLevel = false)

def sameSimpleType(a: SimpleType, b: SimpleType): Boolean =
samePending(a, b)(sameSimpleTypeDirect)
def sameSimpleTypeDirect(a: SimpleType, b: SimpleType): Boolean =
(a, b) match {
case (pa: Projection, pb: Projection) => debug(sameProjection(pa, pb), "Different projection")
case (pa: ParameterRef, pb: ParameterRef) => debug(sameParameterRef(pa, pb), "Different parameter ref")
case (sa: Singleton, sb: Singleton) => debug(sameSingleton(sa, sb), "Different singleton")
case (_: EmptyType, _: EmptyType) => true
case (pa: Parameterized, pb: Parameterized) => debug(sameParameterized(pa, pb), "Different parameterized")
case _ => differentCategory("simple type", a, b)
}
def differentCategory(label: String, a: AnyRef, b: AnyRef): Boolean =
debug(flag = false, "Different category of " + label + " (" + a.getClass.getName + " and " + b.getClass.getName + ") for (" + a + " and " + b + ")")

def sameParameterized(a: Parameterized, b: Parameterized): Boolean =
sameSimpleType(a.baseType, b.baseType) &&
sameType(a.baseType, b.baseType) &&
sameSeq(a.typeArguments, b.typeArguments)(sameType)
def sameParameterRef(a: ParameterRef, b: ParameterRef): Boolean = sameTags(a.id, b.id)
def sameSingleton(a: Singleton, b: Singleton): Boolean =
samePath(a.path, b.path)
def sameProjection(a: Projection, b: Projection): Boolean =
sameSimpleType(a.prefix, b.prefix) &&
sameType(a.prefix, b.prefix) &&
(a.id == b.id)

def samePath(a: Path, b: Path): Boolean =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package xsbt

import net.openhft.affinity.AffinityLock
import org.openjdk.jmh.annotations._
import java.io.File

Expand All @@ -18,8 +19,13 @@ class BenchmarkBase {
var _setup: ProjectSetup = _
var _subprojectsSetup: List[ProjectSetup] = _

/* Java thread affinity (install JNA to run this benchmark). */
var _lock: AffinityLock = _

@Setup(Level.Trial)
def setUpCompilerRuns(): Unit = {
_lock = AffinityLock.acquireLock()

assert(_project != null, "_project is null, set it.")
assert(_subprojectToRun != null, "_subprojectToRun is null, set it.")

Expand Down Expand Up @@ -48,6 +54,7 @@ class BenchmarkBase {

@TearDown(Level.Trial)
def tearDown(): Unit = {
_lock.release()
// Remove the directory where all the class files have been compiled
sbt.io.IO.delete(_setup.at)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ object BenchmarkProjects {
"fb109614dd6efbb97c5b4f164b7adfc284982b25",
List("coreJVM")
)

object Scalac
extends BenchmarkProject(
"scala/scala",
"827d69d48e96d9add75ce19e06b374610784c936",
List("library")
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package xsbt

import java.io.File

import xsbt.BenchmarkProjects.Shapeless
import xsbt.BenchmarkProjects.{ Scalac, Shapeless }

object GlobalBenchmarkSetup {

/** Update this list every time you add a new benchmark. */
val projects = List(Shapeless)
val projects = List(Scalac)

def runSetup(setupDir: File): (Int, String) = {
val projectsPreparation = projects.map { project =>
Expand Down
48 changes: 48 additions & 0 deletions internal/zinc-benchmarks/src/main/scala/xsbt/ScalacBenchmark.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package xsbt

import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations._

class ScalacBenchmark extends BenchmarkBase {
_project = BenchmarkProjects.Scalac
}

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.SingleShotTime))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(value = 10, jvmArgs = Array("-XX:CICompilerCount=2"))
class ColdScalacBenchmark extends ScalacBenchmark {
_subprojectToRun = _project.subprojects.head
@Benchmark
override def compile(): Unit = {
super.compile()
}
}

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.SampleTime))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 0)
@Measurement(iterations = 1, time = 30, timeUnit = TimeUnit.SECONDS)
@Fork(value = 3)
class WarmScalacBenchmark extends ScalacBenchmark {
_subprojectToRun = _project.subprojects.head
@Benchmark
override def compile(): Unit = {
super.compile()
}
}

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.SampleTime))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 6, time = 10, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 6, time = 10, timeUnit = TimeUnit.SECONDS)
@Fork(value = 3)
class HotScalacBenchmark extends ScalacBenchmark {
_subprojectToRun = _project.subprojects.head
@Benchmark
override def compile(): Unit = {
super.compile()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package xsbt
/*package xsbt
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations._
Expand Down Expand Up @@ -45,4 +45,4 @@ class HotShapelessBenchmark extends ShapelessBenchmark {
override def compile(): Unit = {
super.compile()
}
}
}*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object A {
def m: ({type T <: Int})#T = ???
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object B {
val x: Int = A.m
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object A {
def m: ({type T <: String})#T = ???
}
4 changes: 4 additions & 0 deletions zinc/src/sbt-test/source-dependencies/struct-projection/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
> compile
$ copy-file changes/A.scala A.scala
# Compilation of B.scala should fail because type of A.m changed
-> compile

0 comments on commit 172cc90

Please sign in to comment.