semantictokens.scala

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

SCALA
719
字号
          case tpe0 : RefinedType => tree match {              case cpt : CompoundTypeTree =>                   buildTs(cpt.templ.parents, tpe0.parents);                      case _ : TypeTree =>                 // Console.err.println("UNKNOWN TPE13: " + dbg(tree) + " tpe0=" + tpe0 + " " + tpe0.parents);              case _ =>                  if (false) Console.err.println("UNKNOWN TPE5: " + dbg(tree) + " tpe0=" + tpe0 + " " + tpe0.parents);          }          case tpe0 : ThisType => tree match {            case stt : SingletonTypeTree => stt.ref match {                case ths : This => build(ths);          case _ => Console.err.println("UNKNOWN TPE11: " + tpe0 + " " + stt + " " + stt.ref + " " + stt.ref.getClass() + " " + (tree.pos).dbgString);        }        case tt : This =>         case _ : Ident =>        case _ : Select =>        case tt : TypeTree =>           if (false) Console.err.println("UNKNOWN TPE12: " + tpe0 + " " + tree + " " + tree.getClass() + " " + (tree.pos).dbgString);        case _ =>           if (false) Console.err.println("UNKNOWN TPE10: " + tpe0 + " " + tree + " " + tree.getClass() + " " + (tree.pos).dbgString);          }        case tpe0 : SingleType => tree match {          case ident  : Ident  => buildUse(tpe0.sym, ident.pos.offset.getOrElse(-1), tpe0);          case select : Select =>            buildUse(tpe0.termSymbol, selectPos(select), tpe0);            //Console.err.println("QUALIFIER-0: " + select.qualifier + " " + unit.source.dbg(select.qualifier.pos) + " " + tpe0.prefix + " " + tpe0.prefix.getClass() + " " + tpe0.prefix.getClass().getSuperclass() +" " + tpe0.prefix.widen + " " + tpe0.prefix.toLongString);                        buildT(select.qualifier, tpe0.prefix);          case _ =>            if (false) Console.err.println("UNKNOWN TPE8: " + tree + " " + (tree.pos).dbgString + " TPE=" + tpe0 + " PRE=" + tpe0.pre + " SYM=" + tpe0.sym);                      }      case ctype : ConstantType =>          case ErrorType =>           case _ => {        if (false) Console.err.println("UNKNOWN TPE4: " + tree + " " + tpe + " " + tpe.getClass() + " " + (tree.pos).dbgString);          }        };    def buildTs(trees : List[Tree], types : List[Type]): Unit = if (!trees.isEmpty && !types.isEmpty) {              buildT (trees.head, types.head);              buildTs(trees.tail, types.tail);        } else if (trees.isEmpty != types.isEmpty) {             if (false && doLog) {        Console.println("" + treex + " vs. " + treex.original);        if (treex.original ne null)          Console.println("" + treex.tpe + " vs. " + treex.original.tpe);               logError("Tree vs. Type mismatch: " + trees + " " + types + " " + (tree.pos).dbgString, null);        doLog = false;      }    };/*  Martin to Sean: I don't understand why AbsTypeDef is different from AliasTypeDef.  Why is the order reversed? Why two buildDefs for tree.symbol vs one for AliasTypeDef?      case tree: AbsTypeDef =>        //Console.err.println("ABS: " + tree.symbol + " " + unit.source.dbg(tree.namePos) + " " + tree.pos.dbgString);        buildDef(tree.symbol, tree.namePos)        buildDef(tree.symbol, tree.pos.offset.getOrElse(-1))        build(tree.tparams); //@M        build(tree.lo)        build(tree.hi)*/      case tree: Bind =>        buildDef(tree.symbol, tree.pos.offset.getOrElse(-1))        build(tree.body)      case tree: Ident =>        buildUse(tree.symbol, tree.pos.offset.getOrElse(-1), tree.tpe)      case tree: Select =>        try {          build(tree.qualifier)            } catch {              case e : Error => Console.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + (tree.qualifier.pos).dbgString); throw e;            }            try {              if (tree.pos.offset.isDefined && tree.pos.offset.get >= unit.source.length) {                if (false) Console.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + (tree.pos).dbgString);                  } else {          //Console.err.println("SELECT-0: " + tree.symbol + " " + tree.pos.dbgString + " " + (tree.pos - selectPos(tree)));                    buildUse(tree.symbol, selectPos(tree), tree.tpe);              }            } catch {              case e : Error => Console.err.println("SELECTU: " + tree + " " + tree.symbol + " " + tree.pos.dbgString); throw e;            }    case tree: TypeApply =>      //Console.err.println("TYPE_APPLY: " + tree + " " + tree.pos.dbgString);          if (!tree.args.isEmpty) {        //Console.err.println("ARGS: " + unit.source.dbg(tree.args0.head.pos));          }      build(tree.fun)      build(tree.args)    case tree: Apply =>      build(tree.fun)      build(tree.args)      case tree: GenericApply =>        build(tree.fun)        build(tree.args)      case tree: Typed =>        build(tree.expr)        build(tree.tpt)      case tree: Block =>        if (false) {          if (!tree.stats.isEmpty)            Console.err.println("BLOCKS: " + tree.stats.head + " " + tree.stats.head.getClass());          Console.err.println("BLOCKE: " + tree.expr + " " + tree.expr.getClass())        }        build(tree.stats)        build(tree.expr)      case tree: CaseDef =>        build(tree.pat)        build(tree.guard)        build(tree.body)      case tree : Sequence   => build(tree.trees);      case tree : Assign     => build(tree.lhs); build(tree.rhs);      case tree : If         => build(tree.cond); build(tree.thenp); build(tree.elsep);      case tree : New        =>         //Console.err.println("NEW: " + tree.tpt + " " + tree.tpt.getClass());      build(tree.tpt);      case tree : Match      => build(tree.selector); build(tree.cases);      case tree : Return     => build(tree.expr);      case tree : LabelDef   => build(tree.rhs);      case tree : Throw      => build(tree.expr);      case tree : Try        => build(tree.block); build(tree.catches); build(tree.finalizer);      case tree : Alternative => build(tree.trees);      case tree : This    =>         if (tree.symbol ne null) buildUse(tree.symbol, tree.pos.offset.getOrElse(-1), tree.tpe);        //Thread.dumpStack();      case tree : TypeDef =>         //Console.err.println("ALIAS: " + tree);        build(tree.rhs); build(tree.tparams); buildDef(tree.symbol, tree.pos.offset.getOrElse(-1));      case tree : DocDef     => build(tree.definition);      case tree: Import => build(tree.expr)      case tree: AppliedTypeTree => ;      case tree: Annotated => ;      case tree: SingletonTypeTree => ;      case tree: Super   => ;      case tree: Literal => ;      case EmptyTree => ;      case _ => ;        Console.err.println("BAIL: " + (tree0.pos) + " " + tree0 + " " + tree0.getClass());    }  } catch {    case t: Throwable =>      logError("Error occured at " + (tree0.pos), t)  }  def buildUse(term: Symbol, pos: Int, tpe: Type) = buildSym(term, pos, false, tpe)  def buildDef(term: Symbol, pos: Int) = buildSym(term, pos, true, null)  def buildSym(term: Symbol, pos: Int, isDef: Boolean, tpe: Type): Unit =    if (term.hasFlag(Flags.ACCESSOR))      buildSym(analyzer.underlying(term), pos, isDef, tpe)    else if (pos == -1) {      //Console.err.println("NOPOS: " + term)      //Thread.dumpStack()    }    else if (term != NoSymbol) {      val name = NameTransformer.decode(term.name.toString).trim()      val buf = unit.source.asInstanceOf[BatchSourceFile].content      val cs = name.toChars      var idx = 0      if (cs.length + pos > buf.length) return      else while (idx < cs.length) {        if (buf(pos + idx) != cs(idx)) {          //Console.err.println("MISMATCH: " + name + "[" + idx + "] " + unit.source.dbg(pos));          //Thread.dumpStack();          return;        }        else idx = idx + 1;      }      if (cs.length + pos + 1 < buf.length) {        if (isJavaIdentifierPart(buf(pos + cs.length))) {          //Console.err.println("MISMATCH: " + name + "[last] " + unit.source.dbg(pos));          return;        }      }      try {        list.put(pos, (if (isDef) new Def(term) else new Use(term, tpe)));      } catch {        case e : Error => e.printStackTrace();      }    }  def selectPos(tree: Select): Int = if (tree.pos == NoPosition) -1 else {    val buf = unit.source.asInstanceOf[BatchSourceFile].content    if (tree.pos.offset.get >= buf.length) {      if (false) {        Console.err.println("" + tree + "@" + tree.pos + " not in " +                           unit.source.file.name + "[" + buf.length + "]");        Thread.dumpStack()        throw new Error()      }      return 0    }    val pos : Int =      if (buf(tree.pos.offset.get) != '.') tree.pos.offset.get      else {        def f(x : Int) : Int = {          if (buf(x).isWhitespace) f(x + 1)          else x        }        f(tree.pos.offset.get + 1)      }    pos  };  class TokenList {    object begin extends HasNext {      def prev = this      def length = 0    }    object end extends HasPrev {      def next = this      def length = 0    }    // initialize    begin.next0 = end    end.prev0 = begin    def tokenAt(offset: Int) = {      cursor.seek(offset)      if (cursor.token.isInstanceOf[Semantic]) cursor.token.asInstanceOf[Semantic]      else null    }    def put(offset: Int, tok: Actual): Unit = tok match {      case tok0: Semantic => put(offset, tok0)      case gap: Gap      =>    }    def put(offset: Int, tok: Semantic) {      cursor.seek(offset);      if (cursor.token == end) {        assert(offset >= cursor.offset);        if (offset > cursor.offset) {          // add a gap.          val gap = new Gap(end.prev);          gap.setLength(offset - cursor.offset);          cursor.offset = offset;        }        // append.        tok.insert(end.prev);        cursor.offset = cursor.offset + tok.length;      } else if (!cursor.token.isInstanceOf[Gap]) {        val sem = cursor.token.asInstanceOf[Semantic];        if (sem.symbol == tok.symbol) return;        if (sem.symbol != tok.symbol &&            sem.symbol.getClass() == tok.symbol.getClass() &&            sem.symbol.pos == tok.symbol.pos) return;      } else {        val gap = cursor.token.asInstanceOf[Gap];        if (!(offset - cursor.offset + tok.length <= gap.length)) {          Console.err.println("LIST  =" + this);          Console.err.println("OFFSET=" + offset + " " + tok + " " + tok.length);          Console.err.println("       " + cursor.offset + " " + gap.length);          gap.length0 = offset - cursor.offset + tok.length          //throw new Error();        }        if (offset == cursor.offset) {          // replace or prepend          tok.prev0 = gap.prev0;          if (tok.length == gap.length) { // replace gap            tok.next0 = gap.next0;          } else {            gap.setLength(gap.length - tok.length);            tok.next0 = gap;          }          tok.next0.prev0 = tok;          tok.prev0.next0 = tok;          cursor.token = tok;        } else {          // append          val diff = (cursor.offset + gap.length) - (offset + tok.length);          gap.setLength(gap.length - tok.length - diff);          tok.prev0 = gap;          tok.next0 = gap.next;          tok.next0.prev0 = tok;          tok.prev0.next0 = tok;          if (diff != 0) {            val gap0 = new Gap(tok);            gap0.setLength(diff);          }        }      }    }    override def toString(): String = {      var node = begin.next      var str = ""      while (node != end) {        str = str + " " + node        node = node.next      }      str    }    object cursor {      var token: Token = end      var offset: Int = 0      def next: Unit = if (token == end) end else {        offset = offset + token.length        token  = token.next      }      def prev: Unit = if (token.prev == begin) token else {        offset = offset - token.prev.length        token = token.prev      }      def seek(soffset: Int): Unit = if (soffset == 0) {        token = begin.next        offset = 0      } else {        assert(soffset > 0)        while (offset                >  soffset) prev;        while (offset + token.length <= soffset && token != end) {          val len0 = offset;          next;        }      }      def convertToGap = if (token.isInstanceOf[Actual]) {        val ret = token.asInstanceOf[Actual].convertToGap;        offset  = offset - ret._1;        token   = ret._2;      }    }    // add or delete characters    def adjust(offset: Int, /* where */               length: Int, /* how many characters are modified */               to    : Int  /* length of new string */) = {      cursor.seek(offset)      if (cursor.token != end) {        cursor.convertToGap        while (cursor.offset + cursor.token.length < offset + length && cursor.token.next != end) {          val save = cursor.offset          cursor.next          cursor.convertToGap          assert(cursor.offset == save)        }         if (length != to && cursor.token != end) {           val diff = to - length;           val gap = cursor.token.asInstanceOf[Gap];           gap.setLength(gap.length + diff);         };      }    }  } // TokenList  }}

⌨️ 快捷键说明

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