Skip to content

Commit e762224

Browse files
authored
Merge pull request #15 from cristianoc/type_corresp_impl_intf
Dependencies between types in interface and implementation files.
2 parents a3083ee + 701a3ed commit e762224

File tree

10 files changed

+595
-582
lines changed

10 files changed

+595
-582
lines changed

examples/deadcode/src/DeadTest.bs.js

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/deadcode/src/DeadTest.re

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,6 @@ let () = Js.log(make);
170170

171171
let theSideEffectIsLogging = Js.log(123);
172172

173-
let stringLengthNoSideEffects = String.length("sdkdl");
173+
let stringLengthNoSideEffects = String.length("sdkdl");
174+
175+
Trace.infok("", "", ({pf}) => pf("%s", ""));

examples/deadcode/src/deadcode.txt

Lines changed: 453 additions & 535 deletions
Large diffs are not rendered by default.

examples/deadcode/src/trace.bs.js

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/deadcode/src/trace.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type ('a, 'b) fmt = ('a, Format.formatter, unit, 'b) format4
2+
type 'a printf = ('a, unit) fmt -> 'a
3+
type pf = {pf: 'a. 'a printf}
4+
5+
let infok _mod_name _fun_name k = k {pf= Format.eprintf}

examples/deadcode/src/trace.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type ('a, 'b) fmt = ('a, Format.formatter, unit, 'b) format4
2+
type 'a printf = ('a, unit) fmt -> 'a
3+
type pf = {pf: 'a. 'a printf}
4+
5+
val infok : string -> string -> (pf -> 'a) -> 'a

src/DeadCode.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ let loadCmtFile = cmtFilePath => {
7575
(cmtFilePath |> Filename.chop_extension) ++ ".cmti",
7676
);
7777
ProcessDeadAnnotations.structure(~doGenType=!cmtiExists, structure);
78-
processSignature(~doValues=true, ~doTypes=true, structure.str_type);
78+
processSignature(~doValues=true, ~doTypes=false, structure.str_type);
7979
DeadValue.processStructure(
8080
~doTypes=true,
8181
~doValues=true,

src/DeadCommon.re

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ module Decl = {
850850
~orderedFiles,
851851
{
852852
declKind: kind1,
853-
path: path1,
853+
path: _path1,
854854
pos: {
855855
pos_fname: fname1,
856856
pos_lnum: lnum1,
@@ -860,7 +860,7 @@ module Decl = {
860860
},
861861
{
862862
declKind: kind2,
863-
path: path2,
863+
path: _path2,
864864
pos: {
865865
pos_fname: fname2,
866866
pos_lnum: lnum2,
@@ -871,29 +871,15 @@ module Decl = {
871871
) => {
872872
let findPosition = fn => Hashtbl.find(orderedFiles, fn);
873873

874-
let pathIsImplementationOf = (path1, path2) =>
875-
switch (path1, path2) {
876-
| ([name1, ...restPath1], [name2, ...restPath2]) =>
877-
!Name.isInterface(name1)
878-
&& Name.isInterface(name2)
879-
&& List.length(restPath1) > 1
880-
&& restPath1 == restPath2
881-
| ([], _)
882-
| (_, []) => false
883-
};
884-
885874
/* From the root of the file dependency DAG to the leaves.
886875
From the bottom of the file to the top. */
887876
let (position1, position2) = (
888877
fname1 |> findPosition,
889878
fname2 |> findPosition,
890879
);
891-
let (p1, p2) =
892-
pathIsImplementationOf(path1, path2)
893-
? (1, 0) : pathIsImplementationOf(path2, path1) ? (0, 1) : (0, 0);
894880
compare(
895-
(position1, p1, lnum2, bol2, cnum2, kind1),
896-
(position2, p2, lnum1, bol1, cnum1, kind2),
881+
(position1, lnum2, bol2, cnum2, kind1),
882+
(position2, lnum1, bol1, cnum1, kind2),
897883
);
898884
};
899885

src/DeadType.re

Lines changed: 94 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,101 @@ let addTypeReference = (~posFrom, ~posTo) => {
1515
PosHash.addSet(typeReferences, posTo, posFrom);
1616
};
1717

18-
let addDeclaration =
19-
(
20-
~isInterface,
21-
~path as path_,
22-
{type_kind, type_manifest}: Types.type_declaration,
23-
) => {
24-
let save = (~declKind, ~loc: Location.t, ~name) => {
25-
let name = name |> Name.create(~isInterface);
26-
let path = [name, ...path_] |> pathToString;
27-
if (type_manifest == None) {
28-
addTypeDeclaration(~declKind, ~path=path_, ~loc, name);
18+
let pathModuleToImplementation = path =>
19+
switch (path |> List.rev) {
20+
| [moduleName, ...rest] =>
21+
[moduleName |> Name.toImplementation, ...rest] |> List.rev
22+
| [] => path
23+
};
24+
25+
let pathModuleToInterface = path =>
26+
switch (path |> List.rev) {
27+
| [moduleName, ...rest] =>
28+
[moduleName |> Name.toInterface, ...rest] |> List.rev
29+
| [] => path
30+
};
31+
32+
let pathTypeToInterface = path =>
33+
switch (path) {
34+
| [typeName, ...rest] => [typeName |> Name.toInterface, ...rest]
35+
| [] => path
36+
};
37+
38+
let pathTypeToImplementation = path =>
39+
switch (path) {
40+
| [typeName, ...rest] => [typeName |> Name.toImplementation, ...rest]
41+
| [] => path
42+
};
43+
44+
let extendTypeDependencies = (loc1: Location.t, loc2: Location.t) =>
45+
if (loc1.loc_start != loc2.loc_start) {
46+
if (verbose) {
47+
Log_.item(
48+
"extendTypeDependencies %s --> %s@.",
49+
loc1.loc_start |> posToString,
50+
loc2.loc_start |> posToString,
51+
);
2952
};
30-
Hashtbl.replace(fields, path, loc);
53+
typeDependencies := [(loc1, loc2), ...typeDependencies^];
54+
};
55+
56+
let addTypeDependenciesImplementationInterface = (~loc, ~name, path_) => {
57+
let isInterface = Filename.check_suffix(currentSrc^, "i");
58+
if (!isInterface) {
59+
let path_1 = path_ |> pathModuleToInterface;
60+
let path_2 = path_1 |> pathTypeToInterface;
61+
let path1 = [name, ...path_1] |> pathToString;
62+
let path2 = [name, ...path_2] |> pathToString;
63+
64+
switch (Hashtbl.find_opt(fields, path1)) {
65+
| None =>
66+
switch (Hashtbl.find_opt(fields, path2)) {
67+
| None => ()
68+
| Some(loc2) =>
69+
extendTypeDependencies(loc, loc2);
70+
if (!reportTypesDeadOnlyInInterface) {
71+
extendTypeDependencies(loc2, loc);
72+
};
73+
}
74+
| Some(loc1) =>
75+
extendTypeDependencies(loc, loc1);
76+
if (!reportTypesDeadOnlyInInterface) {
77+
extendTypeDependencies(loc1, loc);
78+
};
79+
};
80+
} else {
81+
let path_1 = path_ |> pathModuleToImplementation;
82+
let path_2 = path_1 |> pathTypeToImplementation;
83+
let path1 = [name, ...path_1] |> pathToString;
84+
let path2 = [name, ...path_2] |> pathToString;
85+
switch (Hashtbl.find_opt(fields, path1)) {
86+
| None =>
87+
switch (Hashtbl.find_opt(fields, path2)) {
88+
| None => ()
89+
| Some(loc2) =>
90+
extendTypeDependencies(loc2, loc);
91+
if (!reportTypesDeadOnlyInInterface) {
92+
extendTypeDependencies(loc, loc2);
93+
};
94+
}
95+
| Some(loc1) =>
96+
extendTypeDependencies(loc1, loc);
97+
if (!reportTypesDeadOnlyInInterface) {
98+
extendTypeDependencies(loc, loc1);
99+
};
100+
};
101+
};
102+
};
103+
104+
let addDeclaration = (~path as path_, {type_kind}: Types.type_declaration) => {
105+
let save = (~declKind, ~loc: Location.t, ~name) => {
106+
let name = name |> Name.create;
107+
let path = [name, ...path_];
108+
addTypeDeclaration(~declKind, ~path=path_, ~loc, name);
109+
110+
path_ |> addTypeDependenciesImplementationInterface(~loc, ~name);
111+
112+
Hashtbl.replace(fields, path |> pathToString, loc);
31113
};
32114

33115
switch (type_kind) {
@@ -48,18 +130,6 @@ let addDeclaration =
48130
};
49131

50132
let processTypeDeclaration = (typeDeclaration: Typedtree.type_declaration) => {
51-
let extendTypeDependencies = (loc1: Location.t, loc2: Location.t) =>
52-
if (loc1.loc_start != loc2.loc_start) {
53-
if (verbose) {
54-
Log_.item(
55-
"extendTypeDependencies %s --> %s@.",
56-
loc1.loc_start |> posToString,
57-
loc2.loc_start |> posToString,
58-
);
59-
};
60-
61-
typeDependencies := [(loc1, loc2), ...typeDependencies^];
62-
};
63133
let updateDependencies = (name, loc) => {
64134
let path2 =
65135
[

src/DeadValue.re

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,6 @@ let rec processSignatureItem =
335335
let (id, t) = si |> Compat.getSigType;
336336
if (analyzeTypes^) {
337337
DeadType.addDeclaration(
338-
~isInterface=true,
339338
~path=[id |> Ident.name |> Name.create, ...path],
340339
t,
341340
);
@@ -443,8 +442,7 @@ let traverseStructure = (~doTypes, ~doValues) => {
443442
|> Name.create(~isInterface),
444443
...currentModulePath^ @ [currentModuleName^],
445444
];
446-
typeDeclaration.typ_type
447-
|> DeadType.addDeclaration(~isInterface, ~path);
445+
typeDeclaration.typ_type |> DeadType.addDeclaration(~path);
448446
});
449447
}
450448
| Tstr_include(_) =>

0 commit comments

Comments
 (0)