diff options
author | ilyas <ilyas@epfl.ch> | 2009-01-15 14:13:37 +0000 |
---|---|---|
committer | ilyas <ilyas@epfl.ch> | 2009-01-15 14:13:37 +0000 |
commit | e877601ffbf61d79c8241bcce948cdde99efb0f1 (patch) | |
tree | 55a7cc2ef8ddb5229b1bdf89336837671eeca186 /src/compiler/scalax/rules/scalasig/ScalaSigPrinter.scala | |
parent | 5e9bf6564f03456355d63a58944d2f5d2202732d (diff) | |
download | scala-e877601ffbf61d79c8241bcce948cdde99efb0f1.tar.gz scala-e877601ffbf61d79c8241bcce948cdde99efb0f1.tar.bz2 scala-e877601ffbf61d79c8241bcce948cdde99efb0f1.zip |
scalap classes added
Diffstat (limited to 'src/compiler/scalax/rules/scalasig/ScalaSigPrinter.scala')
-rw-r--r-- | src/compiler/scalax/rules/scalasig/ScalaSigPrinter.scala | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/src/compiler/scalax/rules/scalasig/ScalaSigPrinter.scala b/src/compiler/scalax/rules/scalasig/ScalaSigPrinter.scala new file mode 100644 index 0000000000..9dbdbfd25a --- /dev/null +++ b/src/compiler/scalax/rules/scalasig/ScalaSigPrinter.scala @@ -0,0 +1,277 @@ +package scalax.rules.scalasig + +import _root_.scala.Symbol +import util.StringUtil +import java.io.PrintStream +import java.util.regex.Pattern + +class ScalaSigPrinter(stream: PrintStream) { + import stream._ + + case class TypeFlags(printRep: Boolean) + + def printSymbol(symbol: Symbol) {printSymbol(0, symbol)} + + def printSymbol(level: Int, symbol: Symbol) { + if (!symbol.isLocal) { + def indent() {for (i <- 1 to level) print(" ")} + + symbol match { + case o: ObjectSymbol => indent; printObject(level, o) + case c: ClassSymbol if !refinementClass(c) && !c.isModule => indent; printClass(level, c) + case m: MethodSymbol => printMethod(level, m, indent) + case a: AliasSymbol => indent; printAlias(level, a) + case t: TypeSymbol => () + case s => {} + } + } + } + + def printChildren(level: Int, symbol: Symbol) { + for (child <- symbol.children) printSymbol(level + 1, child) + } + + def printWithIndent(level: Int, s: String) { + def indent() {for (i <- 1 to level) print(" ")} + indent; + print(s) + } + + def printModifiers(symbol: Symbol) { + if (symbol.isSealed) print("sealed ") + if (symbol.isImplicit) print("implicit ") + if (symbol.isFinal) print("final ") + if (symbol.isPrivate) print("private ") + else if (symbol.isProtected) print("protected ") + if (symbol.isOverride) print("override ") + if (symbol.isAbstract) symbol match { + case c@(_: ClassSymbol | _: ObjectSymbol) if !c.isTrait => print("abstract ") + case _ => () + } + if (symbol.isCase && !symbol.isMethod) print("case ") + } + + private def refinementClass(c: ClassSymbol) = c.name == "<refinement>" + + def printClass(level: Int, c: ClassSymbol) { + printModifiers(c) + if (c.isTrait) print("trait ") else print("class ") + print(processName(c.name)) + printType(c) + print(" {") + //Print class selftype + c.selfType match { + case Some(t: Type) => print("\n"); print(" this : " + toString(t) + " =>") + case None => + } + print("\n") + printChildren(level, c) + printWithIndent(level, "}\n") + } + + def printObject(level: Int, o: ObjectSymbol) { + printModifiers(o) + print("object ") + print(processName(o.name)) + val TypeRefType(prefix, classSymbol: ClassSymbol, typeArgs) = o.infoType + printType(classSymbol) + print(" {\n") + printChildren(level, classSymbol) + printWithIndent(level, "}\n") + } + + def genParamNames(t: {def paramTypes: Seq[Type]}): List[String] = t.paramTypes.toList.map(x => { + var str = toString(x) + val j = str.indexOf("[") + if (j > 0) str = str.substring(0, j) + str = StringUtil.trimStart(str, "=> ") + var i = str.lastIndexOf(".") + val res = if (i > 0) str.substring(i + 1) else str + if (res.length > 1) StringUtil.decapitalize(res.substring(0, 1)) else res.toLowerCase + }) + + def printMethodType(t: Type, printResult: Boolean): Unit = { + def _pmt(mt: Type {def resultType: Type; def paramTypes: Seq[Type]}) = { + print(genParamNames(mt).zip(mt.paramTypes.toList.map(toString(_)(TypeFlags(true)))).map(p => p._1 + " : " + p._2).mkString( + "(" + (mt match {case ImplicitMethodType(_, _) => "implicit "; case _ => ""}) + , ", ", ")")) + mt.resultType match { + case mt: MethodType => printMethodType(mt, printResult) + case imt: ImplicitMethodType => printMethodType(imt, printResult) + case x => if (printResult) { + print(" : "); + printType(x) + } + } + } + t match { + case mt@MethodType(resType, paramTypes) => _pmt(mt) + case mt@ImplicitMethodType(resType, paramTypes) => _pmt(mt) + case pt@PolyType(mt, typeParams) => { + print(typeParamString(typeParams)) + printMethodType(mt, printResult) + } + //todo consider another method types + case x => print(" : "); printType(x) + } + } + + def printMethod(level: Int, m: MethodSymbol, indent : () => Unit): Unit = { + val n = m.name + if (m.isAccessor && n.endsWith("_$eq")) return + indent() + printModifiers(m) + if (m.isAccessor) { + val indexOfSetter = m.parent.get.children.findIndexOf(x => x.isInstanceOf[MethodSymbol] && + x.asInstanceOf[MethodSymbol].name == n + "_$eq") + print(if (indexOfSetter > 0) "var " else "val ") + } else { + print("def ") + } + n match { + case "<init>" => { + print("this") + printMethodType(m.infoType, false) + print(" = { /* compiled code */ }") + } + case name => { + val nn = processName(name) + print(nn) + printMethodType(m.infoType, true) + if (!m.isAbstract) { // Print body for non-abstract metods + print(" = { /* compiled code */ }") + } + } + } + print("\n") + printChildren(level, m) + } + + def printAlias(level: Int, a: AliasSymbol) { + print("type ") + print(processName(a.name)) + printType(a.infoType, " = ") + print("\n") + printChildren(level, a) + } + + def printAttributes(sym: SymbolInfoSymbol) { + for (attrib <- sym.attributes) printAttribute(attrib) + } + + def printAttribute(attrib: AttributeInfo) { + printType(attrib.typeRef, "@") + if (attrib.value.isDefined) { + print("(") + printValue(attrib.value.get) + print(")") + } + if (!attrib.values.isEmpty) { + print(" {") + for (name ~ value <- attrib.values) { + print(" val ") + print(processName(name)) + print(" = ") + printValue(value) + } + printValue(attrib.value) + print(" }") + } + print(" ") + } + + def printValue(value: Any): Unit = value match { + case t: Type => printType(t) + // TODO string, char, float, etc. + case _ => print(value) + } + + implicit object _tf extends TypeFlags(false) + + def printType(sym: SymbolInfoSymbol)(implicit flags: TypeFlags): Unit = printType(sym.infoType)(flags) + + def printType(t: Type)(implicit flags: TypeFlags): Unit = print(toString(t)(flags)) + + def printType(t: Type, sep: String)(implicit flags: TypeFlags): Unit = print(toString(t, sep)(flags)) + + def toString(t: Type)(implicit flags: TypeFlags): String = toString(t, "")(flags) + + def toString(t: Type, sep: String)(implicit flags: TypeFlags): String = t match { + case ThisType(symbol) => sep + symbol.path + ".type" + case SingleType(typeRef, symbol) => sep + symbol.path + ".type" + case ConstantType(constant) => sep + (constant match { + case null => "scala.Null" + case _: Unit => "scala.Unit" + case _: Boolean => "scala.Boolean" + case _: Byte => "scala.Byte" + case _: Char => "scala.Char" + case _: Short => "scala.Short" + case _: Int => "scala.Int" + case _: Long => "scala.Long" + case _: Float => "scala.Float" + case _: Double => "scala.Double" + case _: String => "java.lang.String" + case c: Class[_] => "java.lang.Class[" + c.getComponentType.getCanonicalName.replace("$", ".") + "]" + }) + case TypeRefType(prefix, symbol, typeArgs) => sep + (symbol.path match { + case "scala.<repeated>" => flags match { + case TypeFlags(true) => toString(typeArgs.first) + "*" + case _ => "scala.Seq" + typeArgString(typeArgs) + } + case "scala.<byname>" => "=> " + toString(typeArgs.first) + case _ => StringUtil.trimStart(processName(symbol.path) + typeArgString(typeArgs), "<empty>.") + }) + case TypeBoundsType(lower, upper) => " >: " + toString(lower) + " <: " + toString(upper) + case RefinedType(classSym, typeRefs) => sep + typeRefs.map(toString).mkString("", " with ", "") + case ClassInfoType(symbol, typeRefs) => sep + typeRefs.map(toString).mkString(" extends ", " with ", "") + + case ImplicitMethodType(resultType, _) => toString(resultType, sep) + case MethodType(resultType, _) => toString(resultType, sep) + + case PolyType(typeRef, symbols) => typeParamString(symbols) + toString(typeRef, sep) + case AnnotatedType(typeRef, attribTreeRefs) => toString(typeRef, sep) + case AnnotatedWithSelfType(typeRef, symbol, attribTreeRefs) => toString(typeRef, sep) + //case DeBruijnIndexType(typeLevel, typeIndex) => + case ExistentialType(typeRef, symbols) => { + val refs = symbols.map(toString _).filter(!_.startsWith("_ ")).map("type " + _) + toString(typeRef, sep) + (if (refs.size > 0) refs.mkString(" forSome {", "; ", "}") else "") + } + case _ => sep + t.toString + } + + def getVariance(t: TypeSymbol) = if (t.isCovariant) "+" else if (t.isContravariant) "-" else "" + + def toString(symbol: Symbol): String = symbol match { + case symbol: TypeSymbol => getVariance(symbol) + processName(symbol.name) + toString(symbol.infoType) + case s => symbol.toString + } + + def typeArgString(typeArgs: Seq[Type]): String = + if (typeArgs.isEmpty) "" + else typeArgs.map(toString).map(StringUtil.trimStart(_, "=> ")).mkString("[", ", ", "]") + + def typeParamString(params: Seq[Symbol]): String = + if (params.isEmpty) "" + else params.map(toString).mkString("[", ", ", "]") + + val _syms = Map("\\$bar" -> "|", "\\$tilde" -> "~", + "\\$bang" -> "!", "\\$up" -> "^", "\\$plus" -> "+", + "\\$minus" -> "-", "\\$eq" -> "=", "\\$less" -> "<", + "\\$times" -> "*", "\\$div" -> "/", "\\$bslash" -> "\\\\", + "\\$greater" -> ">", "\\$qmark" -> "?", "\\$percent" -> "%", + "\\$amp" -> "&", "\\$colon" -> ":", "\\$u2192" -> "→") + val pattern = Pattern.compile(_syms.keySet.foldLeft("")((x, y) => if (x == "") y else x + "|" + y)) + val placeholderPattern = "_\\$(\\d)+" + + def processName(name: String) = { + val m = pattern.matcher(name) + var temp = name + while (m.find) { + val key = m.group + val re = "\\" + key + temp = temp.replaceAll(re, _syms(re)) + } + temp.replaceAll(placeholderPattern, "_") + } + +} |