aboutsummaryrefslogtreecommitdiff
path: root/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala
blob: ad8d993411ce1c8de9a26526df51411d6e92f2de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package dotty.tools
package dottydoc
package util

import dotc.config.Printers.dottydoc
import dotc.core.Contexts.Context
import dotc.core.Flags
import dotc.core.Names._
import dotc.core.Symbols._
import dotc.core.Types._
import dotc.core.Names._
import dotc.util.Positions._
import model.comment._
import model.Entities._

trait MemberLookup {
  def lookup(
    entity: Entity,
    packages: Map[String, Package],
    query: String,
    pos: Position
  ): LinkTo = {
    val notFound: LinkTo = Tooltip(query)
    val querys = query.split("\\.").toList

    def localLookup(ent: Entity with Members, searchStr: String): LinkTo =
      ent.members.find(_.name == searchStr).fold(notFound)(e => LinkToEntity(e))

    def downwardLookup(ent: Entity with Members, search: List[String]): LinkTo =
      search match {
        case Nil => notFound
        case x :: Nil =>
          localLookup(ent, x)
        case x :: xs  =>
          ent
            .members
            .collect { case e: Entity with Members => e }
            .find(_.name == x)
            .fold(notFound)(e => downwardLookup(e, xs))
      }

    def globalLookup: LinkTo = {
      def longestMatch(list: List[String]): List[String] =
        if (list == Nil) Nil
        else
          packages
          .get(list.mkString("."))
          .map(_ => list)
          .getOrElse(longestMatch(list.dropRight(1)))

      longestMatch(querys) match {
        case Nil => notFound
        case xs  => downwardLookup(packages(xs.mkString(".")), querys diff xs)
      }
    }

    (querys, entity) match {
      case (x :: Nil, e: Entity with Members) =>
        localLookup(e, x)
      case (x :: _, e: Entity with Members) if x == entity.name =>
        downwardLookup(e, querys)
      case _ =>
        globalLookup
    }
  }

  def makeEntityLink(
    entity: Entity,
    packages: Map[String, Package],
    title: Inline,
    pos: Position,
    query: String
  ): Inline = EntityLink(title, lookup(entity, packages, query, pos))
}