mirror of https://github.com/sbt/sbt.git
221 lines
12 KiB
Scala
221 lines
12 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2010 Mark Harrah
|
|
*/
|
|
package xsbt.api
|
|
|
|
import Predef.{implicitly => ??, _}
|
|
import sbt.Using
|
|
import xsbti.api._
|
|
import sbinary._
|
|
import DefaultProtocol._
|
|
import java.io.File
|
|
import scala.collection.mutable
|
|
|
|
trait FormatExtra
|
|
{
|
|
def p2[A,B,R](unapply: R => (A,B))( apply: (A,B) => R)(implicit fa: Format[A], fb: Format[B]): Format[R] =
|
|
asProduct2(apply)(unapply)(fa, fb)
|
|
def p3[A,B,C,R](unapply: R => (A,B,C))( apply: (A,B,C) => R)(implicit fa: Format[A], fb: Format[B], fc: Format[C]): Format[R] =
|
|
asProduct3(apply)(unapply)(fa, fb, fc)
|
|
def p4[A,B,C,D,R](unapply: R => (A,B,C,D))( apply: (A,B,C,D) => R)(implicit fa: Format[A], fb: Format[B], fc: Format[C], fd: Format[D]): Format[R] =
|
|
asProduct4(apply)(unapply)(fa, fb, fc, fd)
|
|
def p5[A,B,C,D,E,R](unapply: R => (A,B,C,D,E))( apply: (A,B,C,D,E) => R)(implicit fa: Format[A], fb: Format[B], fc: Format[C], fd: Format[D], fe: Format[E]): Format[R] =
|
|
asProduct5(apply)(unapply)(fa, fb, fc, fd, fe)
|
|
def p6[A,B,C,D,E,F,R](unapply: R => (A,B,C,D,E,F))( apply: (A,B,C,D,E,F) => R)(implicit fa: Format[A], fb: Format[B], fc: Format[C], fd: Format[D], fe: Format[E], ff: Format[F]): Format[R] =
|
|
asProduct6(apply)(unapply)(fa, fb, fc, fd, fe, ff)
|
|
def p7[A,B,C,D,E,F,G,R](unapply: R => (A,B,C,D,E,F,G))( apply: (A,B,C,D,E,F,G) => R)(implicit fa: Format[A], fb: Format[B], fc: Format[C], fd: Format[D], fe: Format[E], ff: Format[F], fg: Format[G]): Format[R] =
|
|
asProduct7(apply)(unapply)(fa, fb, fc, fd, fe, ff, fg)
|
|
def p8[A,B,C,D,E,F,G,H,R](unapply: R => (A,B,C,D,E,F,G,H))( apply: (A,B,C,D,E,F,G,H) => R)(implicit fa: Format[A], fb: Format[B], fc: Format[C], fd: Format[D], fe: Format[E], ff: Format[F], fg: Format[G], fh: Format[H]): Format[R] =
|
|
asProduct8(apply)(unapply)(fa, fb, fc, fd, fe, ff, fg, fh)
|
|
}
|
|
trait APIFormats extends FormatExtra
|
|
{
|
|
implicit def formatStructure(implicit fi: Format[Int], references: References): Format[Structure] =
|
|
wrap(references.id, references.structure)
|
|
implicit def formatClassLike(implicit fi: Format[Int], references: References): Format[ClassLike] =
|
|
wrap(references.id, references.classLike)
|
|
|
|
// cyclic with formatSuper, so it is not implicit by default
|
|
def formatPath(implicit pc: Format[Array[PathComponent]]): Format[Path] =
|
|
wrap[Path, Array[PathComponent]]( _.components, x => new Path(x))(pc)
|
|
|
|
implicit def formatComponent(implicit t: Format[This], s: Format[Super], i: Format[Id]): Format[PathComponent] =
|
|
asUnion(t, s, i)
|
|
def formatSuper(implicit p: Format[Path]): Format[Super] =
|
|
wrap[Super, Path](_.qualifier, q => new Super(q))(p)
|
|
implicit def formatId(implicit s: Format[String]): Format[Id] =
|
|
wrap[Id, String](_.id, i => new Id(i))(s)
|
|
implicit val formatThis: Format[This] = asSingleton(new This)
|
|
|
|
implicit def formatSource(implicit pa: Format[Array[Package]], da: Format[Array[Definition]]): Format[Source] =
|
|
p2( (s: Source) => (s.packages, s.definitions))( (p, d) => new Source(p, d) )(pa, da)
|
|
|
|
implicit def formatAnnotated(implicit t: Format[SimpleType], as: Format[Array[Annotation]]): Format[Annotated] =
|
|
p2( (a: Annotated) => (a.baseType,a.annotations))(new Annotated(_,_))(t,as)
|
|
|
|
implicit def formatPolymorphic(implicit t: Format[Type], tps: Format[Array[TypeParameter]]): Format[Polymorphic] =
|
|
p2( (p: Polymorphic) => (p.baseType, p.parameters) )( new Polymorphic(_,_) )(t, tps)
|
|
|
|
implicit def formatExistential(implicit t: Format[Type], tps: Format[Array[TypeParameter]]): Format[Existential] =
|
|
p2( (e: Existential) => (e.baseType, e.clause) )( new Existential(_,_) )(t,tps)
|
|
|
|
implicit def formatParameterRef(implicit i: Format[Int]): Format[ParameterRef] =
|
|
wrap[ParameterRef, Int](_.id, new ParameterRef(_))(i)
|
|
|
|
// cyclic with many formats
|
|
def formatType(implicit s: Format[SimpleType], a: Format[Annotated], st: Format[Structure], e: Format[Existential], po: Format[Polymorphic]): Format[Type] =
|
|
asUnion(s, a, st, e, po)
|
|
|
|
implicit def formatDef(implicit acs: Format[Access], ms: Format[Modifiers], ans: Format[Array[Annotation]], tp: Format[Array[TypeParameter]], vp: Format[Array[ParameterList]], t: Format[Type], fs: Format[String]): Format[Def] =
|
|
p7( (d: Def) => (d.valueParameters, d.returnType, d.typeParameters, d.name, d.access, d.modifiers, d.annotations))( new Def(_,_,_,_,_,_,_) )(vp, t, tp, fs, acs, ms, ans)
|
|
|
|
implicit def formatVal(implicit acs: Format[Access], ms: Format[Modifiers], ans: Format[Array[Annotation]], t: Format[Type], ts: Format[String]): Format[Val] =
|
|
fieldLike( new Val(_,_,_,_,_) )(acs, ms, ans, ts, t)
|
|
|
|
implicit def formatVar(implicit acs: Format[Access], ms: Format[Modifiers], ans: Format[Array[Annotation]], t: Format[Type], ts: Format[String]): Format[Var] =
|
|
fieldLike( new Var(_,_,_,_,_) )(acs, ms, ans, ts, t)
|
|
|
|
def fieldLike[F <: FieldLike](construct: (Type, String, Access, Modifiers, Array[Annotation]) => F)(implicit acs: Format[Access], ms: Format[Modifiers], ans: Format[Array[Annotation]], nme: Format[String], tpe: Format[Type]): Format[F] =
|
|
asProduct5(construct)( d => (d.tpe, d.name, d.access, d.modifiers, d.annotations))(tpe, nme, acs, ms, ans)
|
|
|
|
def formatDefinition(implicit vl: Format[Val], vr: Format[Var], ds: Format[Def], cl: Format[ClassLike], ta: Format[TypeAlias], td: Format[TypeDeclaration]): Format[Definition] =
|
|
asUnion(vl, vr, ds, cl, ta, td)
|
|
|
|
def formatSimpleType(implicit pr: Format[Projection], pa: Format[ParameterRef], si: Format[Singleton], et: Format[EmptyType], p: Format[Parameterized]): Format[SimpleType] =
|
|
asUnion(pr, pa, si, et, p)
|
|
|
|
implicit def formatEmptyType: Format[EmptyType] = asSingleton(new EmptyType)
|
|
implicit def formatSingleton(implicit p: Format[Path]): Format[Singleton] = wrap[Singleton, Path](_.path, new Singleton(_))
|
|
|
|
def formatProjection(implicit t: Format[SimpleType], s: Format[String]): Format[Projection] =
|
|
p2( (p: Projection) => (p.prefix, p.id))(new Projection(_,_))(t, s)
|
|
|
|
def formatParameterized(implicit t: Format[SimpleType], tps: Format[Array[Type]]): Format[Parameterized] =
|
|
p2( (p: Parameterized) => (p.baseType, p.typeArguments))(new Parameterized(_,_))(t, tps)
|
|
|
|
implicit def formatTypeAlias(implicit acs: Format[Access], ms: Format[Modifiers], ans: Format[Array[Annotation]], tps: Format[Array[TypeParameter]], t: Format[Type], n: Format[String]): Format[TypeAlias] =
|
|
p6( (ta: TypeAlias) => (ta.tpe, ta.typeParameters, ta.name, ta.access, ta.modifiers, ta.annotations))( new TypeAlias(_,_,_,_,_,_) )(t, tps, n, acs, ms, ans)
|
|
|
|
implicit def formatTypeDeclaration(implicit acs: Format[Access], ms: Format[Modifiers], ans: Format[Array[Annotation]], tps: Format[Array[TypeParameter]], t: Format[Type], n: Format[String]): Format[TypeDeclaration] =
|
|
p7( (td: TypeDeclaration) => (td.lowerBound, td.upperBound, td.typeParameters, td.name, td.access, td.modifiers, td.annotations))( new TypeDeclaration(_,_,_,_,_,_,_))(t,t,tps,n,acs,ms,ans)
|
|
|
|
// cyclic with SimpleType
|
|
def formatAnnotation(implicit t: Format[SimpleType], af: Format[Array[AnnotationArgument]]): Format[Annotation] =
|
|
p2( (a: Annotation) => (a.base, a.arguments) )( (a,b) => new Annotation(a,b) )(t, af)
|
|
|
|
implicit def formatAnnotationArgument(implicit sf: Format[String]): Format[AnnotationArgument] =
|
|
p2( (aa: AnnotationArgument) => (aa.name, aa.value))( (a,b) => new AnnotationArgument(a,b))(sf, sf)
|
|
|
|
|
|
implicit def formatVariance(implicit b: Format[Byte]): Format[Variance] =
|
|
wrap[Variance, Byte]( v => v.ordinal.toByte, b => Variance.values.apply(b.toInt) )(b)
|
|
|
|
implicit def formatDefinitionType(implicit b: Format[Byte]): Format[DefinitionType] =
|
|
wrap[DefinitionType, Byte]( dt => dt.ordinal.toByte, b => DefinitionType.values.apply(b.toInt) )(b)
|
|
|
|
implicit def formatPackage(implicit fs: Format[String]): Format[Package] =
|
|
wrap[Package, String]( _.name, n => new Package(n) )(fs)
|
|
|
|
implicit def formatAccess(implicit fs: Format[String]): Format[Access] =
|
|
new Format[Access]
|
|
{
|
|
val unqualified = new Unqualified
|
|
val ths = new ThisQualifier
|
|
|
|
val public = new Public
|
|
val privateUn = new Private(unqualified)
|
|
val protectedUn = new Protected(unqualified)
|
|
val privateThis = new Private(ths)
|
|
val protectedThis = new Protected(ths)
|
|
|
|
def reads(in: Input): Access =
|
|
{
|
|
def qualifier() = new IdQualifier(fs.reads(in))
|
|
import AccessIDs._
|
|
AccessIDs(in.readByte) match
|
|
{
|
|
case PublicID => public
|
|
case PrivateID => privateUn
|
|
case ProtectedID => protectedUn
|
|
case PrivateThisID => privateThis
|
|
case ProtectedThisID => protectedThis
|
|
case QPrivateID => new Private(qualifier())
|
|
case QProtectedID => new Protected(qualifier())
|
|
}
|
|
}
|
|
def writes(out: Output, a: Access)
|
|
{
|
|
import AccessIDs._
|
|
def w(id: AccessIDs.Value) = out.writeByte(id.id.toByte)
|
|
def qualified(un: Value, ths: Value, qual: Value, qualifier: Qualifier): Unit =
|
|
qualifier match
|
|
{
|
|
case _: Unqualified => w(un)
|
|
case _: ThisQualifier => w(ths)
|
|
case i: IdQualifier => w(qual); fs.writes(out, i.value)
|
|
}
|
|
a match
|
|
{
|
|
case _: Public => w(PublicID)
|
|
case q: Qualified => q match {
|
|
case p: Private => qualified(PrivateID, PrivateThisID, QPrivateID, p.qualifier)
|
|
case p: Protected => qualified(ProtectedID, ProtectedThisID, QProtectedID, p.qualifier)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
import APIUtil._
|
|
implicit def formatModifiers(implicit bf: Format[Byte]): Format[Modifiers] =
|
|
wrap[Modifiers, Byte]( modifiersToByte, byteToModifiers )
|
|
|
|
def formatTypeParameter(tps: Format[TypeParameter] => Format[Array[TypeParameter]])(implicit as: Format[Array[Annotation]], t: Format[Type], v: Format[Variance], i: Format[Int]): Format[TypeParameter] =
|
|
{
|
|
lazy val ltps: Format[Array[TypeParameter]] = lazyFormat( tps(ltp) )
|
|
lazy val ltp = p6( (tp: TypeParameter) => (tp.id, tp.annotations, tp.typeParameters, tp.variance, tp.lowerBound, tp.upperBound))(new TypeParameter(_,_,_,_,_,_))(i, as, ltps, v, t, t)
|
|
ltp
|
|
}
|
|
|
|
implicit def formatParameterList(implicit mp: Format[Array[MethodParameter]], bf: Format[Boolean]): Format[ParameterList] =
|
|
p2( (pl: ParameterList) => (pl.parameters, pl.isImplicit) )( (ps, impl) => new ParameterList(ps, impl) )
|
|
|
|
implicit def formatMethodParameter(implicit s: Format[String], b: Format[Boolean], m: Format[ParameterModifier], t: Format[Type]): Format[MethodParameter] =
|
|
p4( (mp: MethodParameter) => (mp.name, mp.tpe, mp.hasDefault, mp.modifier) )( new MethodParameter(_,_,_,_) )(s,t,b,m)
|
|
|
|
implicit def formatParameterModifier(implicit bf: Format[Byte]): Format[ParameterModifier] =
|
|
wrap[ParameterModifier, Byte]( dt => dt.ordinal.toByte, b => ParameterModifier.values.apply(b.toInt) )(bf)
|
|
}
|
|
private object AccessIDs extends Enumeration
|
|
{
|
|
val PublicID, PrivateID, ProtectedID, QPrivateID, QProtectedID, PrivateThisID, ProtectedThisID = Value
|
|
}
|
|
|
|
// construct a concrete Format[Source], handling cycles
|
|
// ?? (Predef.implicitly) is used for implicits the compiler should infer
|
|
class DefaultAPIFormats(implicit val references: References) extends APIFormats
|
|
{
|
|
import sbinary.DefaultProtocol._
|
|
|
|
implicit lazy val tpf: Format[TypeParameter] = formatTypeParameter(array)
|
|
|
|
// SimpleType is cyclic with Projection and Parameterized
|
|
implicit lazy val stf: Format[SimpleType] = lazyFormat(formatSimpleType(projf, ??, ??, ??, paramf))
|
|
// Type is cyclic with a lot, including SimpleType and TypeParameter
|
|
implicit lazy val tf: Format[Type] = lazyFormat( formatType(stf, ??, ??, ??, ??) )
|
|
|
|
implicit lazy val df: Format[Definition] = lazyFormat( formatDefinition )
|
|
|
|
// Projection, Annotation, and Parameterized are cyclic with SimpleType
|
|
// Parameterized is also cyclic with Type
|
|
implicit lazy val projf: Format[Projection] = formatProjection(stf, ??)
|
|
implicit lazy val af: Format[Annotation] = formatAnnotation(stf, ??)
|
|
implicit lazy val paramf: Format[Parameterized] = formatParameterized(stf, array(tf))
|
|
|
|
// Super and Path are cyclic
|
|
implicit lazy val sf: Format[Super] = lazyFormat(formatSuper(pathf))
|
|
implicit lazy val pathf: Format[Path] = formatPath
|
|
|
|
implicit val srcFormat: Format[Source] = formatSource(??, array(df))
|
|
|
|
private[this] def array[T](format: Format[T])(implicit mf: Manifest[T]): Format[Array[T]] = arrayFormat(format, mf)
|
|
} |