Changes between Version 2 and Version 3 of Commentary/Compiler/UnusedImports

Jul 1, 2009 12:16:18 PM (5 years ago)



  • Commentary/Compiler/UnusedImports

    v2 v3  
    113113seeing the RdrNames, not by knowing that the name 'x' is used. 
    115 I think that all lookups go through a single function,  
    116    `RnEnv.lookupGreRn_maybe` 
    117 So in `RnEnv.lookupGreRn_maybe`, if `(gre_prov gre)` is `(Imported _)` 
    118 hen put `rdr_name` in a new 
    119 {{{ 
    120 tcg_used_imports :: TcRef (Set RdrName) 
    121 }}} 
    122 in `TcGblEnv`.  All the `tcg_used_imports` are in scope; if not, 
    123 we report an error and do not add it to `tct_used_imports`. 
     115I think that all lookups go through either, `RnEnv.lookupGreRn_maybe` or `RnEnv.lookup_sub_bndr`. 
     116So in `RnEnv.lookupGreRn_maybe`, if `(gre_prov gre)` is `(Imported _)`, 
     117and in `RnEnv.lookup_sub_bndr`, 
     118put `rdr_name` in a new 
     120tcg_used_rdrnames :: TcRef (Set RdrName) 
     122in `TcGblEnv`.  All the `tcg_used_rdrnames` are in scope; if not, 
     123we report an error and do not add it to `tcg_used_rdrnames`. 
    125125Other notes 
    137137  * We can compare `ImportSpecs` for equality by their `SrcSpans` 
    140 Also perhpas: 
    142139  * In `TcRnDriver.tcRnImports`, save import_decls in a new 
    143140  `tcg_rn_rdr_imports :: Maybe [LImportDecl RdrName]` 
    144141  in `TcGblEnv` 
    146   * In `RnNames.reportUnusedNames`, call a function that actually does the 
    147   hard work. The ugly part is when we have an import of Foo(..). Then we 
    148   need to dig through the environments, similar to what 
    149   `RnNames.exports_from_avail` does, so that we can expand the (..). 
     145The algorithm for deciding which imports have been used is based around this datatype: 
     147data ImportInfo = ImportInfo SrcSpan 
     148                             SDoc 
     149                             [RdrName] -- The names the import provides 
     150                             Bool -- Has it been used yet? 
     151                             [ImportInfo] -- Child import infos 
     153Here are how some example imports map to trees of `ImportInfo`, assuming `Foo` exports `a`, `b`, `D(c1, c2)`: 
     155import Foo 
     157ImportInfo "Foo" ["a", "b", "D", "c1", "c2", "Foo.a", "Foo.b", "Foo.D", "Foo.c1", "Foo.c2"] 
     159import qualified Foo as Bar 
     161ImportInfo "Foo" ["Bar.a", "Bar.b", "Bar.D", "Bar.c1", "Bar.c2"] 
     163import qualified Foo (a, D) 
     165ImportInfo "Foo" [] 
     166    ImportInfo "Foo" ["Foo.a"] 
     167    ImportInfo "Foo" ["Foo.D"] 
     169import qualified Foo hiding (a, D(..)) 
     171ImportInfo "Foo" ["Foo.b"] 
     173import Foo (D(c1, c2)) 
     175ImportInfo "Foo" [] 
     176    ImportInfo "Foo" ["D", "Foo.D"] 
     177        ImportInfo "Foo" ["c1", "Foo.c1"] 
     178        ImportInfo "Foo" ["c2", "Foo.c2"] 
     180import qualified Foo (D(..)) 
     182ImportInfo "Foo" [] 
     183    ImportInfo "Foo" ["Foo.D", "Foo.c1", "Foo.c2"] 
     186If a node in the tree is marked as used, then so are all nodes above it. For example, given the tree 
     188ImportInfo "Foo" [] 
     189    ImportInfo "Foo" ["D", "Foo.D"] 
     190        ImportInfo "Foo" ["c1", "Foo.c1"] 
     191        ImportInfo "Foo" ["c2", "Foo.c2"] 
     193a use of `"D"` marks both the first and second lines as used. 
     195When we come to giving warnings, if a node is unused then we warn about it, and do not descend into the rest of that subtree, as the node we warn about subsumes its children. If the node is marked as used then we descend, looking to see if any of its children are unused. 
     197These trees are built by `RnNames.mkImportInfo`. In `RnNames.warnUnusedImportDecls` we make two lists of `ImportInfo`s; one list contains all the explicit imports, e.g. 
     199import Foo (a, b) 
     201and the other contains the implicit imports, e.g. 
     203import Foo 
     204import Foo hiding (a, b) 
     207Then `RnNames.markUsages` is called for each `RdrName` that was used in the program. The current implementation marks all explicit import as used unless there are no such imports, in which case it marks all implicit imports as used. A small tweak to `markUsages` would allow it to mark only the first import it finds as used. 
     209As well as the `RdrName`s used in the source, we also need to mark as used the names that are exported. We first call `RnNames.expandExports` to expand `D(..)` into `D(c1, c2)`, and then call `RnNames.markExportUsages`. Normally this just marks the `RdrName`s as used in the same way that uses in the module body are handled, but it is also possible for an entire module to be "used", if `module Foo` is in the export list. In this case `RnNames.markModuleUsed` does the hard work, marking every module imported with that name as used.