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
|
/**
* Implement the `-deps` and `-makedeps` switches, which output dependencies of modules for build tools.
*
* The grammar of the `-deps` output is:
* ---
* ImportDeclaration
* ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
* ModuleAliasIdentifier ] "\n"
*
* BasicImportDeclaration
* ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection|"string"
* " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
*
* FilePath
* - any string with '(', ')' and '\' escaped with the '\' character
* ---
*
* Make dependencies as generated by `-makedeps` look like this:
* ---
* source/app.d:
* source/importa.d \
* source/importb.d
* ---
*
* Copyright: Copyright (C) 1999-2025 by The D Language Foundation, All Rights Reserved
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/compiler/src/dmd/deps.d, makedeps.d)
* Documentation: https://dlang.org/phobos/dmd_deps.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/compiler/src/dmd/deps.d
*/
module dmd.deps;
import core.stdc.stdio : printf;
import core.stdc.string : strcmp;
import dmd.common.outbuffer;
import dmd.dimport : Import;
import dmd.dmodule : Module;
import dmd.globals : Param, Output;
import dmd.hdrgen : visibilityToBuffer;
import dmd.id : Id;
import dmd.utils : escapePath;
/**
* Add an import expression to module dependencies
* Params:
* moduleDeps = output settings for `-deps`
* makeDeps = output settings for `-makedeps`
* fileNameZ = 0-termminated string containing the import expression's resolved filename
* importString = raw string passed to import exp
* imod = module import exp is in
*/
void addImportExpDep(ref Output moduleDeps, ref Output makeDeps, const(char)[] fileNameZ, const(char)[] importString, Module imod)
{
if (moduleDeps.buffer !is null)
{
OutBuffer* ob = moduleDeps.buffer;
if (!moduleDeps.name)
ob.writestring("depsFile ");
ob.writestring(imod.toPrettyChars());
ob.writestring(" (");
escapePath(ob, imod.srcfile.toChars());
ob.writestring(") : ");
if (moduleDeps.name)
ob.writestring("string : ");
ob.write(importString);
ob.writestring(" (");
escapePath(ob, fileNameZ.ptr);
ob.writestring(")");
ob.writenl();
}
if (makeDeps.doOutput)
{
makeDeps.files.push(fileNameZ.ptr);
}
}
/**
* Add an import statement to module dependencies
* Params:
* moduleDeps = output settings
* imp = import to add
* imod = module that the import is in
*/
void addImportDep(ref Output moduleDeps, Import imp, Module imod)
{
// object self-imports itself, so skip that
// https://issues.dlang.org/show_bug.cgi?id=7547
// don't list pseudo modules __entrypoint.d, __main.d
// https://issues.dlang.org/show_bug.cgi?id=11117
// https://issues.dlang.org/show_bug.cgi?id=11164
if (moduleDeps.buffer is null || (imp.id == Id.object && imod.ident == Id.object) ||
strcmp(imod.ident.toChars(), "__main") == 0)
return;
OutBuffer* ob = moduleDeps.buffer;
if (!moduleDeps.name)
ob.writestring("depsImport ");
ob.writestring(imod.toPrettyChars());
ob.writestring(" (");
escapePath(ob, imod.srcfile.toChars());
ob.writestring(") : ");
// use visibility instead of sc.visibility because it couldn't be
// resolved yet, see the comment above
visibilityToBuffer(*ob, imp.visibility);
ob.writeByte(' ');
if (imp.isstatic)
{
ob.writestring("static ");
}
ob.writestring(": ");
foreach (pid; imp.packages)
{
ob.printf("%s.", pid.toChars());
}
ob.writestring(imp.id.toString());
ob.writestring(" (");
if (imp.mod)
escapePath(ob, imp.mod.srcfile.toChars());
else
ob.writestring("???");
ob.writeByte(')');
foreach (i, name; imp.names)
{
if (i == 0)
ob.writeByte(':');
else
ob.writeByte(',');
auto _alias = imp.aliases[i];
if (!_alias)
{
ob.printf("%s", name.toChars());
_alias = name;
}
else
ob.printf("%s=%s", _alias.toChars(), name.toChars());
}
if (imp.aliasId)
ob.printf(" -> %s", imp.aliasId.toChars());
ob.writenl();
}
|