packages feed

lambdabot-4.1: scripts/hoogle/src/Hoogle/MatchName.hs

{-
    This file is part of Hoogle, (c) Neil Mitchell 2004-2005
    http://www.cs.york.ac.uk/~ndm/hoogle/
    
    This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
    To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
    or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
-}

module Hoogle.MatchName(
    NameTable,
    buildName, -- build a name table
    lookupName -- lookup a name
    ) where


import Hoogle.Result
import Hoogle.TypeSig

import Data.Char
import Data.List
import Data.Maybe


-- | The abstract data type
data NameTable = NameTable [(String, String, Result, Bool)]
                 deriving Show

-- | build a 'NameTable'
buildName :: [(ModuleName, Item)] -> NameTable
buildName xs = NameTable $ map f xs
    where
        lcase = map toLower
    
        f (_, Module x) = (lcase name, name,
            Result (Str $ showModuleName (init x)) (Str $ last x)
                   (Tag "u" $ Str "module") "module" [] 0 0,
            False)
            where name = last x
                   
        
        f (modu, x) = (lcase name, name,
            Result (Str $ showModuleName modu) (Str $ getName x)
                   (getType x) (getMode x) [] 0 (0 - length modu),
            head (asString x) == '(')
            where name = getName x


        getName x = noBracket $ asString x
        
        getType (Func _ x) = Str $ showConType x
        getType (Keyword x) = Tag "u" $ Str "keyword"
        getType (Class x) =
            Tags [Tag "u" $ Str "class", Str $ " " ++ showConType x]
        getType (TypeAlias name args _) =
            Tags [Tag "u" $ Str "type", Str $ concatMap (' ':) (name:args)]
        getType (Data b x) = 
            Tags [Tag "u" $ Str (if b then "newtype" else "data"), Str $ " " ++ showConType x]
        
        getMode (Func{}) = "func"
        getMode (Keyword{}) = "keyword"
        getMode (Class{}) = "class"
        getMode (TypeAlias{}) = "type"
        getMode (Data b x) = if b then "newtype" else "data"



noBracket ('(':xs) = init xs
noBracket x = x


-- | lookup an entry in a 'NameTable'
lookupName :: NameTable -> String -> [Result]
lookupName (NameTable xs) find = catMaybes $ map f xs
    where
        findc = noBracket find
        find2 = map toLower findc
    
        f (fnd, orig, res, b) =
            do (reason, pos) <- getMatch fnd orig
               return $ res{
                   resultName = brack b $ h pos (length find) (fromStr (resultName res)),
                   resultInfo = [ReasonText reason],
                   resultScore = score [ReasonText reason]
                 }
                            
        fromStr (Str x) = x

        getMatch :: String -> String -> Maybe (TextAmount, Int)
        getMatch fnd orig
            | findc == orig = Just (TextFullCase, 0)
            | find2 == fnd  = Just (TextFull, 0)
            | findc `isPrefixOf` orig = Just (TextPrefixCase, 0)
            | find2 `isPrefixOf` fnd  = Just (TextPrefix, 0)
            | find2 `isSuffixOf` fnd  = Just (TextSuffix, length fnd - length find2)
            | otherwise = g fnd 0
                     
              
        g [] n = Nothing
        g xs n | find2 `isPrefixOf` xs = Just (TextSome, n)
               | otherwise = g (tail xs) (n+1)
                   
                   
        h pos len xs = Tags $ [
                Str $ take pos2 xs,
                Tag "b" $ Str $ take len $ drop pos2 xs,
                Str $ drop (len+pos2) xs]
            where pos2 = pos + (if head xs == '(' then 1 else 0)


        brack True x = Tags [Str "(", x, Str ")"]
        brack _ x = x