module FreeNames(module FreeNames,NameSpace(..)) where import HsIdent import TypedIds(NameSpace(..),namespace) import List(nub) import MUtils(mapSnd) import DefinedNames import Recursive {-+ This modules defines a class for extensible extraction of free names from expressions, type expressions, etc. By free names, we mean names that occur in an expression and need to be defined/introduced elsewhere. For example, the constructors that appear in a pattern are considered free names, while the variables in a pattern are considered defined names rather than free names. While it would make sense for method #freeNames# to return a set instead of a list, there are currently some places in the code where the free names are assumed to be listed in the order they appeared in the expression (.e.g. in the definition of TiFreeNames.typeParams). -} type FreeName i = (HsIdentI i, NameSpace) class Eq i => FreeNames i t | t -> i where freeNames :: t -> [FreeName i] {-+ Instances for collecting free names from lists, pairs and sums of things: -} instance FreeNames i t => FreeNames i [t] where freeNames = nub . concatMap freeNames instance (FreeNames i a, FreeNames i b) => FreeNames i (a,b) where freeNames (x,y) = nub (freeNames x ++ freeNames y) instance (FreeNames i a, FreeNames i b,FreeNames i c) => FreeNames i (a,b,c) where freeNames (x,y,z) = nub (freeNames x ++ freeNames y ++ freeNames z) instance (FreeNames i a, FreeNames i b) => FreeNames i (Either a b) where freeNames = either freeNames freeNames instance FreeNames i a => FreeNames i (Maybe a) where freeNames = maybe [] freeNames {-+ Auxiliary functions: -} defs x = mapSnd namespace . definedNames $ x freeValues x = map fst . filter ((==ValueNames).snd) . freeNames $ x freeNamesRec x = freeNames (struct x) freeCons x = filter (isHsCon.fst) . freeNames $ x freeVars x = filter (isHsVar.fst) . freeNames $ x istyvar (x,sp) = isHsVar x && sp==ClassOrTypeNames -- utils --------------------------------------- tcon = typ . HsCon tvar = typ . HsVar con = val . HsCon var = val . HsVar val x = (x, ValueNames) typ x = (x, ClassOrTypeNames)