This file is indexed.

/usr/share/gps/library/filedeps.py is in gnat-gps-common 6.1.2016-1ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""This plug-in adds a menu for computing the dependencies between two files

When you modify some source files, it often happens that the compiler will
decide to recompile other files that depended on it. Finding out why there is
such a dependency is not always obvious, and this plug-in will help you in
that respect.

Once it has been activated, select the new menu
   /Navigate/Show File Dependency Path...
and in the dialog that appears enter the two source files you are interested
in. This will then list in the console why the first file depends on the
second (for instance "file1" depends on "file2", which depends on "file3")
"""

#############################################################################
# No user customization below this line
#############################################################################

import GPS
import os.path


def internal_dependency_path(from_file, to_file, include_implicit):
    # We do the computation starting from to_file, since it is more efficient
    # to compute "imported" files than "importing files". Since we want to
    # compute the path itself, do not do a recursive search.
    deps = dict()

    # List of files to analyze. This is a list of tuples, the first element of
    # which is the name of the file to analyze, and the second is the name of
    # the parent that put it in the list
    to_analyze = [(from_file, None)]

    while len(to_analyze) != 0:
        (file, because_of) = to_analyze.pop()
        imports = file.imports(include_implicit=include_implicit,
                               include_system=False)

        # imports does not list the dependency from body to spec, so we add it
        # explicitly if from_file is a body.

        ext = os.path.splitext(from_file.name())
        if ext[1] == ".adb" or (ext[1] == ".ada" and ext[0][-2:] == ".2"):
            imports.append(from_file.other_file())

        deps[file] = because_of
        if file == to_file:
            break

        for f in imports:
            if f and not deps.has_key(f):
                to_analyze.append((f, file))

    target = to_file
    added = False
    result = ""
    targets = []

    while target:
        targets.append(target)
        result = " -> " + target.name() + "\n" + result
        if not deps.has_key(target):
            result = "No dependency between these two files"
            break
        target = deps[target]
    return (result, targets)


def dependency_path(from_file, to_file, fill_location=False, title=""):
    """Shows why modifying to_file implies that from_file needs to be
       recompiled. This information is computed from the cross-references
       database, and requires your application to have been compiled
       properly. This function does not attempt to compute the shortest
       dependency path, and just returns the first one it finds.
       FROM_FILE and TO_FILE must be instances of GPS.File.
       If FILL_LOCATION is True, then the locations view will also be filled."""

    if not isinstance(from_file, GPS.File):
        from_file = GPS.File(from_file)
    if not isinstance(to_file, GPS.File):
        to_file = GPS.File(to_file)

    if from_file == to_file:
        return "Same file"

    # First, try without implicit dependencies, this gives better results
    # in general, and then fallback to implicit deps if needed.

    (result, targets) = internal_dependency_path(from_file, to_file,
                                                 include_implicit=False)

    if result == "No dependency between these two files":
        (result, targets) = internal_dependency_path(from_file, to_file,
                                                     include_implicit=True)

    if fill_location and result != "No dependency between these two files":
        target = targets.pop()

        # Fill the locations view with the result
        while len(targets) != 0:
            prev_target = target
            target = targets.pop()

            # Assume simple naming schemes:
            #   - parent-child.ads -> parent.child
            #   - parent.child.1.ada -> parent.child
            # ??? Would be good to have a file_to_unit API instead
            unit = os.path.splitext(os.path.basename(target.name()))[0]

            if len(unit) > 2 and (unit[-2:] == ".1" or unit[-2:] == ".2"):
                unit = unit[0:len(unit) - 2]

            unit = unit.split('-')[-1].split('.')[-1]

            # Find the 'with <unit>' clause in prev_target and fill the
            # location view
            for e in prev_target.entities(local=False):
                if e.category() == "package/namespace" \
                        and e.name().lower() == unit \
                        and e.declaration().file() == target:
                    refs = e.references(in_file=prev_target)

                    if len(refs) > 1:
                        r = refs[1]
                        GPS.Locations.add(category=title,
                                          file=prev_target,
                                          line=r.line(),
                                          column=r.column(),
                                          message="with " + unit,
                                          highlight="",
                                          length=0)
                        added = True
                        break
        if added:
            GPS.MDI.get("Locations").raise_window()
    return result


def print_dependency_path(from_file, to_file):
    title = "Dependencies from " + os.path.basename (from_file.name()) + \
        " to " + os.path.basename(to_file.name())
    result = dependency_path(from_file, to_file, True, title)
    GPS.Console().write(title + "\n" + result + "\n")


def interactive_dependency_path(menu):
    try:
        (file1, file2) = GPS.MDI.input_dialog("Show file dependency path",
                                              "From File", "To File")
    except:
        return

    print_dependency_path(GPS.File(file1), GPS.File(file2))

GPS.Menu.create("/Navigate/Show File Dependency Path...",
                interactive_dependency_path)