modelextractor.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 450 行 · 第 1/2 页
SCALA
450 行
this.toList foreach (this removeAll _.parents) } object constructorArgs extends jcl.LinkedHashMap[Symbol, ValueParam] { import symtab.Flags._ sym.constrParamAccessors.filter(arg => ! (arg hasFlag SYNTHETIC)).foreach(arg => { val str = flagsToString(arg.flags) assert((arg hasFlag PRIVATE) && (arg hasFlag LOCAL), arg) val argName = arg.name.toString.trim val actual = sym.tpe.decls.elements.find(e => { val eName = e.name.toString.trim; argName == eName && { val str = flagsToString(e.flags); !e.hasFlag(LOCAL); } }); val param = actual getOrElse arg this(param) = new ConstructorParam(param) }); } object decls extends jcl.LinkedHashMap[Symbol, Member] { sym.tpe.decls.elements.foreach(e => { if (!constructorArgs.contains(e)) { val m = Member(e) if (!m.isEmpty && !this.contains(e)) this.put(e, m.get) } }); } def members0(f: Symbol => Boolean) = decls.projection.filterKeys(f).valueSet def members(c: Category): Iterable[Member] = members0(c.f) object inherited extends jcl.LinkedHashMap[Symbol, List[Member]]() { override def default(tpe: Symbol) = Nil for (m <- sym.tpe.members if !sym.tpe.decls.elements.contains(m) && (Values.f(m) || Methods.f(m))) { val o = m.overridingSymbol(sym) if (o == NoSymbol) { val parent = decode(m.enclClass) val mo = Member(m) if (!mo.isEmpty) { this(parent) = mo.get :: this(parent) } } } } override def parents = freshParents abstract class Member(sym: Symbol) extends Entity(sym) { private def overriding = sym.allOverriddenSymbols override def comment = super.comment match { case ret @ Some(comment) => ret case None => val o = overriding.find(comments.contains) o.map(comments.apply) } } abstract class ValDef(sym: Symbol) extends Member(sym) { override def resultType = Some(resultType0) protected def resultType0: Type override def overridden: Iterable[Symbol] = { var ret: jcl.LinkedHashSet[Symbol] = null for (parent <- ClassOrObject.this.parents) { val sym0 = sym.overriddenSymbol(parent.typeSymbol) if (sym0 != NoSymbol) { if (ret == null) ret = new jcl.LinkedHashSet[Symbol]; ret += sym0 } } if (ret == null) Nil else ret.readOnly } } case class Def(override val sym : TermSymbol) extends ValDef(sym) { override def resultType0 = sym.tpe.finalResultType override def typeParams = sym.tpe.typeParams.map(TypeParam) override def valueParams = methodArgumentNames.get(sym) match { case Some(argss) if argss.length > 1 || (!argss.isEmpty && !argss(0).isEmpty) => argss map (_.map(ValueParam)) case _ => var i = 0 val ret = for (tpe <- sym.tpe.paramTypes) yield { val ret = sym.newValueParameter(sym.pos, newTermName("arg" + i)); ret setInfo tpe i += 1 ValueParam(ret) } if (ret.isEmpty) Nil else ret :: Nil } override def kind = "def" } case class Val(override val sym: TermSymbol) extends ValDef(sym) { import symtab.Flags._ def resultType0: Type = sym.tpe override def kind: String = if (sym hasFlag ACCESSOR) { val setterName = nme.getterToSetter(sym.name) val setter = sym.owner.info.decl(setterName) val lazyMod = if (sym hasFlag LAZY) "lazy " else "" lazyMod + (if (setter == NoSymbol) "val" else "var") } else { assert(sym hasFlag JAVA) if (sym hasFlag FINAL) "val" else "var" } } case class AbstractType(override val sym: Symbol) extends Member(sym) { override def kind = "type" } abstract class NestedClassOrObject(override val sym: Symbol) extends Member(sym) with ClassOrObject { override def path: List[ClassOrObject] = ClassOrObject.this.path ::: super.path } case class NestedClass(override val sym: ClassSymbol) extends NestedClassOrObject(sym) with Clazz case class NestedObject(override val sym: ModuleSymbol) extends NestedClassOrObject(sym) with Object { override def attributes = sym.moduleClass.attributes } def isVisible(sym: Symbol): Boolean = { import symtab.Flags._ if (sym.isLocalClass) return false if (sym.isLocal) return false if (sym.isPrivateLocal) return false if (sym hasFlag PRIVATE) return !inIDE //false if (sym hasFlag SYNTHETIC) return false if (sym hasFlag BRIDGE) return false if ((sym.nameString indexOf "$") != -1) return false if ((sym hasFlag CASE) && sym.isMethod) return false true } def Member(sym: Symbol): Option[Member] = { import global._ import symtab.Flags if (!isVisible(sym)) None else if (!isAccessible(sym)) None else if (sym hasFlag Flags.ACCESSOR) { if (sym.isSetter) return None; assert(sym.isGetter); Some[Member](new Val(sym.asInstanceOf[TermSymbol])) } else if (sym.isValue && !sym.isMethod && !sym.isModule) { if (!sym.hasFlag(Flags.JAVA)) { Console.println("SYM: " + sym + " " + sym.fullNameString('.')) Console.println("FLA: " + Flags.flagsToString(sym.flags)) } assert(sym hasFlag Flags.JAVA) Some[Member](new Val(sym.asInstanceOf[TermSymbol])) } else if (sym.isValue && !sym.isModule) { val str = Flags.flagsToString(sym.flags) assert(sym.isMethod) Some[Member](new Def(sym.asInstanceOf[TermSymbol])) } else if (sym.isAliasType || sym.isAbstractType) Some(new AbstractType(sym)) else if (sym.isClass) Some(new NestedClass(sym.asInstanceOf[ClassSymbol])) else if (sym.isModule) Some(new NestedObject(sym.asInstanceOf[ModuleSymbol])) else None } } case class Category(label: String)(g: Symbol => Boolean) { val f = g def plural = label + "s" } val Constructors = new Category("Additional Constructor")(e => e.isConstructor && !e.isPrimaryConstructor) { // override def plural = "Additional Constructors"; } val Objects = Category("Object")(_.isModule); val Classes = new Category("Class")(sym => sym.isClass || (sym == definitions.AnyRefClass)) { override def plural = "Classes" } val Values = new Category("Value")(e => e.isValue && e.hasFlag(symtab.Flags.ACCESSOR)) { override def plural = "Values and Variables" } val Methods = Category("Method")(e => e.isValue && e.isMethod && !e.isConstructor && !e.hasFlag(symtab.Flags.ACCESSOR)); val Types = Category("Type")(e => e.isAliasType || e.isAbstractType); val categories = Constructors :: Types :: Values :: Methods :: Classes :: Objects :: Nil; import java.util.regex.Pattern // patterns for standard tags with 1 and 2 arguments private val pat1 = Pattern.compile( "[ \t]*@(author|deprecated|pre|return|see|since|todo|version|ex|note)[ \t]*(.*)") private val pat2 = Pattern.compile( "[ \t]*@(exception|param|throws)[ \t]+(\\p{Graph}*)[ \t]*(.*)") def sort[E <: Entity](entities: Iterable[E]): Iterable[E] = { val set = new jcl.TreeSet[E]()({eA: E => new Ordered[E] { def compare(eB: E): Int = { if (eA eq eB) return 0; (eA, eB) match { case (eA: ClassOrObject, eB: ClassOrObject) => val diff = ModelExtractor.this.compare(eA.path, eB.path) if (diff!= 0) return diff case _ => } if (eA.getClass != eB.getClass) { val diff = eA.getClass.getName.compare(eB.getClass.getName) assert(diff != 0) return diff } if (!eA.sym0.isPackage) { val diff = eA.sym0.nameString compare eB.sym0.nameString if (diff != 0) return diff } val diff0 = eA.sym0.fullNameString compare eB.sym0.fullNameString assert(diff0 != 0) diff0 } override def equals(other: Any) : Boolean = eA.equals(other) || (other match { case that: AnyRef => this.eq(that) case _ => false }) }}) set addAll entities; set }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?