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