idesupport.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 617 行 · 第 1/2 页

SCALA
617
字号
        if (existing.isMonomorphicType) existing.resetFlag(Flags.MONOMORPHIC)        assert(!existing.isPackage)        existing.attributes = Nil // reset attributes, we don't look at these.        existing.setInfo(if (other.hasRawInfo) other.rawInfo else NoType)        if (existing.isModule && existing.moduleClass != NoSymbol)          nuke(existing.moduleClass,symbol.moduleClass)      }            def reuse(existing : Symbol) : Symbol = {        def record(existing : Symbol) = if (existing.hasRawInfo &&           existing.rawInfo.isComplete && existing.rawInfo != NoType && !hasError(existing.rawInfo)) {          tracedTypes(existing) = existing.info        }        record(existing)        nuke(existing,symbol)        if (existing.pos == NoPosition) {          assert(true)          assert(true)         }                finish(existing)      }      val symX = lookup(symbol.name)      if (symX != NoSymbol) {        if (symX == symbol) return (symX)        if (!symbol.hasRawInfo && symX.hasRawInfo && symX.rawInfo.isComplete &&             symbol.pos.isInstanceOf[TrackedPosition] && symX.pos.isInstanceOf[TrackedPosition] &&            symbol.pos == symX.pos) compatible(symX, symbol) match {        case NotCompatible => // do nothing        case code@GoResult(existing0) =>          val existing = existing0          if (code.isInstanceOf[Updated]) {            invalidate(existing.name)          }          nuke(existing,symbol)          return (existing)        }      }      if (symbol == NoSymbol) return symbol      // catch double defs.      record(currentClient, symbol.name)      val i = reuseMap(this).elements      while (i.hasNext) {        var existing = i.next        if (existing == symbol) return {          assert(true)          i.remove          finish(existing)        }         else if ({          (symbol.pos,existing.pos) match {          case (apos : TrackedPosition, bpos : TrackedPosition) => apos == bpos          case (apos : OffsetPosition , bpos : OffsetPosition) => apos == bpos          case _ => existing.name == symbol.name          }        }) {          assert(existing != NoSymbol)          val oldName = existing.name          compatible(existing, symbol) match {          case NotCompatible =>            assert(true)            assert(true)          case code@GoResult(existing0) =>            i.remove            existing = existing0            if (code.isInstanceOf[Updated]) {              invalidate(oldName)              invalidate(existing.name)            }            return (reuse(existing))          }        }      }      if (true) {        assert(true)        //Console.println("NEW SYMBOL: " + symbol + ":" + symbol.id + " @ " + symbol.owner + " " + key);       }      invalidate(symbol.name)      return finish(symbol)    }  }  private val tops = new LinkedHashMap[OffsetPosition,Symbol]    protected def compatible(existing : Symbol, symbol : Symbol) : Result = {    import scala.tools.nsc.symtab.Flags._    if (existing.hasRawInfo && symbol.hasRawInfo) {                }        if (existing.getClass != symbol.getClass) (existing,symbol) match {    case (existing:TypeSkolem,symbol:TypeSymbol) =>       val other = existing.deSkolemize      return if (!other.isSkolem)        compatible(other,symbol)      else NotCompatible    case _ => return NotCompatible    }    if (existing.isGetter != symbol.isGetter) return NotCompatible    if (existing.isSetter != symbol.isSetter) return NotCompatible    if (existing.owner != symbol.owner) return NotCompatible    if (existing.name != symbol.name || existing.name.length != symbol.name.length) {      val ret = (!existing.name.toString.contains('$') &&         !symbol.name.toString.contains('$') &&          !(existing hasFlag SYNTHETIC) && !(symbol hasFlag SYNTHETIC) && {        existing.name.isTypeName == symbol.name.isTypeName &&          nme.isSetterName(existing.name) == nme.isSetterName(symbol.name) &&            nme.isLocalName(existing.name) == nme.isLocalName(symbol.name)      })      if (!ret) return NotCompatible    }    // because module var shares space with monomorphic.    if (existing.isModuleVar != symbol.isModuleVar) return NotCompatible    if ((existing.flags|LOCKED|INTERFACE|MONOMORPHIC|DEFERRED|ABSTRACT|PRIVATE|PROTECTED|FINAL|SEALED|CASE) !=         (symbol.  flags|LOCKED|INTERFACE|MONOMORPHIC|DEFERRED|ABSTRACT|PRIVATE|PROTECTED|FINAL|SEALED|CASE)) {      return NotCompatible    }    if (((existing.flags&(MONOMORPHIC|INTERFACE)) != 0) ||        ((symbol  .flags&(MONOMORPHIC|INTERFACE)) != 0)) {      assert(true)      assert(true)    }    val ret = (existing.owner == symbol.owner || {      existing.owner.name == symbol.owner.name && // why????        (existing.owner.name == nme.ANON_FUN_NAME||symbol.owner.name == nme.ANON_FUN_NAME) &&          existing.owner.pos == symbol.owner.pos    })    if (!ret) return NotCompatible    existing.setPos(symbol.pos) // not significant for updating purposes.    if ((existing.privateWithin != symbol.privateWithin ||         existing.name != symbol.name || ((existing.flags|LOCKED|MONOMORPHIC|INTERFACE) != (symbol.flags|LOCKED|MONOMORPHIC|INTERFACE)))) {      existing.name = (symbol.name)      // don't reset the monomorphic bit until we reset the type.      existing.flags = symbol.flags      existing.privateWithin = symbol.privateWithin      return new Updated(existing)    }    return new Compatible(existing)  }  protected object CompatibleResult {    abstract class Result {      def map(symbol : Symbol) : Result = this    }    case object NotCompatible extends Result    case class GoResult(val symbol : Symbol) extends Result {    }    class Compatible(override val symbol : Symbol) extends GoResult(symbol) {      override def map(symbol : Symbol) = new Compatible(symbol)    }    class Updated(override val symbol : Symbol) extends GoResult(symbol) {      override def map(symbol : Symbol) = new Updated(symbol)    }  }    private class DefInfo extends ReallyHasClients {    var ref : scala.ref.WeakReference[Symbol] = _    var scopes : List[(PersistentScope)] = Nil    def scope(kind : ScopeKind) = scopes.find(_.key == kind) match {    case Some(scope) => scope    case None =>       val scope = new PersistentScope(kind,this)      assert(scope.key == kind)      scopes = (scope) :: scopes      scope    }  }    private val defMap = new WeakHashMap[Symbol,DefInfo] {    override def default(clazz : Symbol) = {      val ref = new scala.ref.WeakReference(clazz)      val info = new DefInfo      this(clazz) = info      info.ref = ref      info    }  }  override def newClassScope(clazz : Symbol) = {    newDefScope0({      if (clazz.isModuleClass && !clazz.isPackageClass) {        assert(true)        clazz      } else if (clazz.isModule && !clazz.isPackage) {        assert(true)        clazz.moduleClass      } else clazz    }, ClassKind)  }  private lazy val ClassKind = allocateScopeKind("class")  private def newDefScope0(sym : Symbol, key : ScopeKind) = reuse(defMap(sym).scope(key))  override def recycle(sym : Symbol) = sym.pos match {  case pos : TrackedPosition => pos.recycle(sym)  case _ => super.recycle(sym)  }  override def newLocalDummy(clazz : Symbol, pos : util.Position) =     recycle(super.newLocalDummy(clazz,pos)).asInstanceOf[TermSymbol]  def newScope(pos : Position, key : (ScopeKind,AnyRef), old : Option[Scope]) : Scope = pos match {  case pos : TrackedPosition => pos.scopeFor(key)  case _ if old.isEmpty => newScope(null : ScopeEntry)  case _ => super.scopeFor(old.get, null,key._1)  }    private def scopeFor00(tree : Tree, old : Option[Scope], kind : ScopeKind) = (tree,tree.symbol) match {  case (_,null|NoSymbol) => newScope(tree.pos, (kind,tree.getClass), (old))  case (tree : DefTree, sym) => newDefScope0((sym),kind) // indexed by symbol   case _ => newScope(tree.pos, (kind,tree.getClass), old)  }    override def scopeFor(old : Scope, tree : Tree, kind : ScopeKind) = scopeFor00(tree, Some(old), kind)  override def scopeFor(tree : Tree, kind : ScopeKind) = scopeFor00(tree, None, kind)  override def newScope(initElements : ScopeEntry) : Scope = {    object owner extends ReallyHasClients    new PersistentScope(null, owner)  }  override def newTempScope : Scope = new TemporaryScope  private class TemporaryScope extends HookedScope(null) {    override def hashCode = toList.map(_.hashCode).foldLeft(0)(_ + _)    override def equals(that : Any) = that match {    case that : TemporaryScope if this eq that => true    case that : TemporaryScope => // do a brute force comparison      val l0 = this.toList      val l1 = that.toList      l0.size == l1.size && l0.forall(l1.contains)    case _ => false    }  }   private class ThrowAwayScope(decls : List[Symbol]) extends HookedScope(null:ScopeEntry) {    decls.foreach(d => enter(d))  }  override def newThrowAwayScope(decls : List[Symbol]) : Scope= new ThrowAwayScope(decls)    private val trackedTypes = new LinkedHashMap[Symbol,LinkedHashSet[ScopeClient]] {    override def default(sym : Symbol) = {      val set = new LinkedHashSet[ScopeClient]      this(sym) = set; set    }  }  // trace symbols whose types are watched!  private val tracedTypes = new LinkedHashMap[Symbol,Type]  override def trackTypeIDE(sym : Symbol): Boolean = if (sym != NoSymbol && !sym.isPackageClass && !sym.isPackage) {    // will wind up watching a lot of stuff!    currentClient.addTo(trackedTypes(sym))    super.trackTypeIDE(sym)  } else super.trackTypeIDE(sym)  override def mkConstantType(value: Constant): ConstantType = {    super.mkConstantType(Constant(value.value match {    case _ : Int => 0 : Int    case _ : Long => 0 : Long    case _ : Byte => 0 : Byte    case _ : Char => 0 : Char    case _ : Short => 0 : Short    case _ : Float => 0 : Float    case _ : Double => 0 : Double    case _ : String => "string"    case _ : scala.Symbol => Symbol("symbol")    case value => value    }))  }  // mostly intellisense hacks.   override def verifyAndPrioritize[T](verify : Symbol => Symbol)(pt : Type)(f : => T) : T = {    currentClient.verifyAndPrioritize(verify)(pt)(f)  }  override def compare(sym : Symbol, name : Name) = {    val client = currentClient    sym.info.decls match {    case scope : HookedScope =>       scope.record(client, name)    case _ =>     }    client.notify(name, sym)    super.compare(sym, name)  }   override def notifyImport(what : Name, container : Type, from : Name, to : Name) : Unit = {    super.notifyImport(what, container, from, to)    val from0 = if (what.isTypeName) from.toTypeName else from.toTermName    val result = container.member(from0)    if (result != NoSymbol)      currentClient.notify(what, result)  }    object lightDuplicator extends Transformer {    override val copy = new StrictTreeCopier  }  // make the trees less detailed.  override def sanitize(tree : Tree) : Tree = lightDuplicator.transform(tree match {  case Template(_,vdef,_) => Template(Nil, sanitize(vdef).asInstanceOf[ValDef], Nil)  case PackageDef(nme, _) => PackageDef(nme, Nil)  case DefDef(mods, _, _, _, _:TypeTree, _) => DefDef(NoMods, nme.ERROR, Nil, Nil, TypeTree(), Literal(()))  case DefDef(mods, _, _, _, restpt, _) => DefDef(NoMods, nme.ERROR, Nil, Nil, sanitize(restpt), Literal(()))  case ValDef(_, _, _ : TypeTree, _) => ValDef(NoMods, nme.ERROR, TypeTree(), EmptyTree)  case ValDef(_, _, restpt, _) => ValDef(NoMods, nme.ERROR, sanitize(restpt), EmptyTree)  case ModuleDef(_, _, impl) =>    ModuleDef(NoMods, nme.ERROR, sanitize(impl).asInstanceOf[Template])  case ClassDef(_, _, tparams, impl) =>    ClassDef(NoMods, nme.ERROR.toTypeName, Nil, sanitize(impl).asInstanceOf[Template])  case DocDef(_, definition) => sanitize(definition)  case CaseDef(x, y, z) => CaseDef(Literal(()), EmptyTree, Literal(()))  case Block(_, _) => Block(Nil, Literal(()))  case Function(vparams,body) =>     Function(vparams.map(sanitize).asInstanceOf[List[ValDef]],Literal(()))   case _ => tree  }).setPos(tree.pos)}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?