|
| 1 | +# Table of contents |
| 2 | + |
| 3 | ++ [Methods](#methods) |
| 4 | + + [Definitions](#definitions) |
| 5 | + + [Compiler warnings](#compiler-warnings) |
| 6 | + + [Warning 26: unused-ancestor](#warning-36-unused-ancestor) |
| 7 | + + [Usage](#usage) |
| 8 | + |
| 9 | +# Methods |
| 10 | + |
| 11 | +## Definitions |
| 12 | + |
| 13 | +A **method** is declared using the `method` keyword in the definition of a class |
| 14 | +or an immediate object, or as a field of an object type. |
| 15 | + |
| 16 | +An **instance variable** is declared using the `val` keyword in the definition |
| 17 | +of a class or an immediate object. It does not appear in object types. |
| 18 | + |
| 19 | +A **public** method is not a private method. |
| 20 | +A **private** method is one declared with the `private` keyword. |
| 21 | + |
| 22 | +An **exported** method is one that exists in its compilation unit's signature |
| 23 | + |
| 24 | +A **use** is either : |
| 25 | +- An explicit reference. |
| 26 | + E.g. |
| 27 | + ```OCaml |
| 28 | + let o = object method answer = 42 end |
| 29 | + let () = print_int o#answer |
| 30 | + ``` |
| 31 | + The method `answer` is explicitly referenced in `o#answer`. |
| 32 | +- A requirement for that method to exist. |
| 33 | + E.g. |
| 34 | + ```OCaml |
| 35 | + let print_answer param = print_int param#answer |
| 36 | + let o = object method answer = 42 end |
| 37 | + let () = print_answer o |
| 38 | + ``` |
| 39 | + The type of `print_answer` is `< answer : int; .. > -> unit`, meaning that its |
| 40 | + arguments are required to at least provide a method named `answer`. Therefore, |
| 41 | + `o#answer` is used by requirement in `print_answer o`. If `o` did not provide |
| 42 | + method `answer`, then the compilation would fail with an error like : |
| 43 | + ``` |
| 44 | + File "requirement.ml", line 4, characters 22-23: |
| 45 | + 4 | let () = print_answer o |
| 46 | + ^ |
| 47 | + Error: This expression has type < > but an expression was expected of type |
| 48 | + < answer : int; .. > |
| 49 | + The first object type has no method answer |
| 50 | + ``` |
| 51 | + |
| 52 | +## Compiler warnings |
| 53 | + |
| 54 | +The analyzer reports unused exported public methods. The compiler does not |
| 55 | +report unused methods (private or public, exported or not, from a class, an |
| 56 | +immediate, or an object type), not instance vraiables. Thus, the 2 tools do not |
| 57 | +complement each other. |
| 58 | + |
| 59 | +> [!WARNING] |
| 60 | +> Only a portion of the unused object-related code can be reported using the |
| 61 | +> compiler and the analyzer : unused exported public methods. Unused private or |
| 62 | +> unexported methods, as well as unused instance variables will remain |
| 63 | +> undetected. |
| 64 | +
|
| 65 | +> [!IMPORTANT] |
| 66 | +> Exported values of object or class types belong to the |
| 67 | +> [Exported values](../exported_values/EXPORTED_VALUES.md) section. |
| 68 | +
|
| 69 | +Although the compiler does not report unused methods or instance variables, it |
| 70 | +still has a few object-related warnings, of which one is related to unused code |
| 71 | +constructs : warning 36. |
| 72 | + |
| 73 | +### Warning 36: unused-ancestor |
| 74 | + |
| 75 | +This warning is disabled by default. |
| 76 | +I can be enabled by passing the `-w +36` to the compiler. |
| 77 | + |
| 78 | +Description: |
| 79 | +``` |
| 80 | +36 [unused-ancestor] Unused ancestor variable. (since 4.00) |
| 81 | +``` |
| 82 | + |
| 83 | +Example: |
| 84 | +```OCaml |
| 85 | +(* warning36.ml *) |
| 86 | +class c1 = object end |
| 87 | +class c2 = object |
| 88 | + inherit c1 as super |
| 89 | +end |
| 90 | +``` |
| 91 | +``` |
| 92 | +$ ocamlopt -w +36 warning36.ml |
| 93 | +File "warning36.ml", line 4, characters 3-22: |
| 94 | +4 | inherit c1 as super |
| 95 | + ^^^^^^^^^^^^^^^^^^^ |
| 96 | +Warning 36 [unused-ancestor]: unused ancestor variable super. |
| 97 | +``` |
| 98 | + |
| 99 | +## Usage |
| 100 | + |
| 101 | +Unused exported public methods are reported by default. |
| 102 | +Their reports can be deactivated by using the `--nothing` or `-M nothing` |
| 103 | +command line arguments. |
| 104 | +They can be reactivated by using the `--all` or `-M all` command line arguments. |
| 105 | +For more details about the command line arguments see [the more general Usage |
| 106 | +documentation](../USAGE.md). |
| 107 | + |
| 108 | +The report section looks like: |
| 109 | + |
| 110 | +``` |
| 111 | +.> UNUSED METHODS: |
| 112 | +================= |
| 113 | +filepath:line: source#method |
| 114 | +
|
| 115 | +Nothing else to report in this section |
| 116 | +-------------------------------------------------------------------------------- |
| 117 | +``` |
| 118 | +The report line format is `filepath:line: value` with `filepath` the absolute |
| 119 | +path to the file (`.mli` if available, `.ml` otherwise) where `source` is |
| 120 | +declared, `line` the line index in `filepath` at which `source` is declared, |
| 121 | +`source` the path of the object/class within its compilation unit (e.g. `M.c`) |
| 122 | +which declares `method`, and `method` the unused method. |
| 123 | +There can be any number of such lines. |
| 124 | + |
| 125 | +The expected resolution for an unused exported public method is to remove it |
| 126 | +from the `.mli` if there is one and the `.ml`. |
| 127 | + |
| 128 | +> [!IMPORTANT] |
| 129 | +> Removing unused methods or values from the codebase may trigger the detection |
| 130 | +> of new unused methods, or remove some for values of object types. |
| 131 | +> Consequently, it is expected that a user might need to compile and analyze |
| 132 | +> their code multiple times when cleaning up their codebase. |
0 commit comments