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 + -
显示快捷键?