private def collectRewriteTargets()

in scalafix/rules/src/main/scala/rsc/rules/RscCompat.scala [100:212]


  private def collectRewriteTargets(ctx: RuleCtx): List[RewriteTarget] = {
    val buf = List.newBuilder[RewriteTarget]
    def loop(env: Env, tree: Tree): Env = {
      tree match {
        case Source(stats) =>
          val rootScope = PackageScope(symbols, "_root_/")
          val javaLangScope = ImporterScope(symbols, "java/lang/", List(Importee.Wildcard()))
          val scalaScope = ImporterScope(symbols, "scala/", List(Importee.Wildcard()))
          val predefScope = ImporterScope(symbols, "scala/Predef.", List(Importee.Wildcard()))
          val env1 = predefScope :: scalaScope :: javaLangScope :: rootScope :: env
          stats.foldLeft(env1)(loop)
        case Import(importers) =>
          return importers.foldLeft(env)(loop)
        case Importer(ref, importees) =>
          return ImporterScope(symbols, ref.name.symbol.get.syntax, importees) :: env
        case Pkg(ref, stats) =>
          val env1 = PackageScope(symbols, ref.name.symbol.get.syntax) :: env
          stats.foldLeft(env1)(loop)
        case Pkg.Object(_, name, templ) =>
          loop(env, templ)
        case defn @ Defn.Class(_, _, _, ctor, templ) if defn.isVisible =>
          loop(env, ctor)
          loop(env, templ)
        case ctor: Ctor =>
          buf ++= targetsForPolymorphicDefaultParams(env, ctor.name, ctor.tparams, ctor.paramss)
        case defn @ Defn.Trait(_, _, _, _, templ) if defn.isVisible =>
          loop(env, templ)
        case defn @ Defn.Object(_, _, templ) if defn.isVisible =>
          loop(env, templ)
        case templ @ Template(early, inits, _, stats) =>
          val name = templ.name.get
          inits.headOption.foreach { init =>
            val tokens = init.tpe.tokens
            //TODO getOrElse is a workaround for a bug in semanticdb that may cause symbols to
            //be incorrect in some cases https://github.com/scalameta/scalameta/issues/1887
            lazy val isTrait = (for {
              symbol <- init.symbol
              info <- symbols.info(symbol.syntax)
            } yield info.kind == Kind.TRAIT).getOrElse(false)
            // If type params of init may be inferred and init is not a trait
            if (!tokens.exists(_.is[Token.LeftBracket]) && !isTrait) {
              buf += RewriteInit(env, name, tokens.last)
            }
          }
          val env1 = TemplateScope(symbols, name.symbol.get.syntax) :: env
          (early ++ stats).foldLeft(env1)(loop)
        case defn @ InferredDefnField(name, body) if defn.isVisible =>
          val before = name.tokens.head
          val after = name.tokens.last
          buf += RewriteDefn(env, before, name, after, body, parens = false, varDefnPat = false)
        case defn @ InferredDefnPat(fnames, pnames, body) if defn.isVisible =>
          // Apparently, we only need to be worried about patterns with only one symbol
          val varDefnPat = defn.is[Defn.Var] && fnames.isEmpty && pnames.size == 1
          if (fnames.nonEmpty) {
            val name = fnames.head
            val before = name.tokens.head
            val after = {
              val start = name.tokens.head
              val end = body.tokens.head
              val slice = ctx.tokenList.slice(start, end)
              slice.reverse
                .find(x => !x.is[Token.Equals] && !x.is[Trivia])
                .get
            }
            buf += RewriteDefn(
              env,
              before,
              name,
              after,
              body,
              parens = false,
              varDefnPat = varDefnPat
            )
          }
          pnames.foreach { name =>
            val before = name.tokens.head
            val after = name.tokens.last
            // FIXME: https://github.com/twitter/rsc/issues/142
            buf += RewriteDefn(
              env,
              before,
              name,
              after,
              body,
              parens = true,
              varDefnPat = varDefnPat
            )
          }
        case defn @ InferredDefnDef(name, body, tparams, paramss) if defn.isVisible =>
          val before = name.tokens.head
          val after = {
            val start = name.tokens.head
            val end = body.tokens.head
            val slice = ctx.tokenList.slice(start, end)
            slice.reverse
              .find(x => !x.is[Token.Equals] && !x.is[Trivia])
              .get
          }
          buf += RewriteDefn(env, before, name, after, body, parens = false, varDefnPat = false)
          buf ++= targetsForPolymorphicDefaultParams(env, name, tparams, paramss)
        // FIXME: https://github.com/twitter/rsc/issues/358
        case defn @ Defn.Def(_, name, tparams, paramss, _, _) =>
          buf ++= targetsForPolymorphicDefaultParams(env, name, tparams, paramss)
        case decl @ Decl.Def(_, name, tparams, paramss, _) =>
          buf ++= targetsForPolymorphicDefaultParams(env, name, tparams, paramss)
        case _ =>
          ()
      }
      env
    }
    loop(Env(Nil), ctx.tree)
    buf.result
  }