hoogle 5.0.12 → 5.0.13
raw patch · 14 files changed
+66/−47 lines, 14 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGES.txt +6/−0
- README.md +1/−1
- cbits/text_search.c +1/−1
- hoogle.cabal +3/−3
- src/Action/CmdLine.hs +2/−2
- src/Action/Generate.hs +1/−4
- src/Action/Search.hs +10/−4
- src/Action/Server.hs +3/−1
- src/General/Conduit.hs +2/−5
- src/General/Store.hs +1/−1
- src/General/Timing.hs +1/−0
- src/General/Util.hs +4/−8
- src/Output/Tags.hs +26/−16
- src/Query.hs +5/−1
CHANGES.txt view
@@ -1,5 +1,11 @@ Changelog for Hoogle +5.0.13+ #219, treat the query "a->b" the same as "a -> b"+ #215, if a specified module/package is missing, give no results+ #220, start on port 8080 by default+ Rely on the fact ghc API is now on Hackage+ #217, fix the mode tag propagating to child links 5.0.12 #210, expose targetInfo and targetSearchDisplay 5.0.11
README.md view
@@ -67,7 +67,7 @@ To ensure you have data files for the Hackage modules, you will first need to type: - hoogle data+ hoogle generate Which will download and build Hoogle databases.
cbits/text_search.c view
@@ -30,7 +30,7 @@ for (char* cs = xs; ; cs++) {- char c = *cs;+ unsigned char c = *cs; if (c == 0) { if (cs[1] == 0) break;
hoogle.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.18 build-type: Simple name: hoogle-version: 5.0.12+version: 5.0.13 license: BSD3 license-file: LICENSE category: Development@@ -15,7 +15,7 @@ or by approximate type signature. homepage: http://hoogle.haskell.org/ bug-reports: https://github.com/ndmitchell/hoogle/issues-tested-with: GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3+tested-with: GHC==8.2.1, GHC==8.0.2, GHC==7.10.3 extra-doc-files: README.md CHANGES.txt@@ -66,13 +66,13 @@ directory, extra >= 1.4, filepath,+ old-locale, haskell-src-exts >= 1.18 && < 1.20, http-conduit, http-types, js-flot, js-jquery, mmap,- old-locale, process, process-extras, resourcet,
src/Action/CmdLine.hs view
@@ -118,13 +118,13 @@ {download = def &= help "Download all files from the web" ,insecure = def &= help "Allow insecure HTTPS connections" ,include = def &= args &= typ "PACKAGE"- ,local_ = def &= opt "" &= help "Index local packages"+ ,local_ = def &= opt "" &= help "Index local packages and link to local haddock docs" ,haddock = def &= help "Use local haddocks" ,debug = def &= help "Generate debug information" } &= help "Generate Hoogle databases" server = Server- {port = 80 &= typ "INT" &= help "Port number"+ {port = 8080 &= typ "INT" &= help "Port number" ,cdn = "" &= typ "URL" &= help "URL prefix to use" ,logs = "" &= opt "log.txt" &= typFile &= help "File to log requests to (defaults to stdout)" ,local = False &= help "Allow following file:// links, restricts to 127.0.0.1 Set --host explicitely (including to '*' for any host) to override the localhost-only behaviour"
src/Action/Generate.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ViewPatterns, TupleSections, RecordWildCards, ScopedTypeVariables, PatternGuards #-}+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} -- getGCStats became getRTSStats module Action.Generate(actionGenerate) where @@ -98,7 +99,6 @@ readHaskellOnline timing settings download = do stackage <- download "haskell-stackage.txt" "https://www.stackage.org/lts/cabal.config" platform <- download "haskell-platform.txt" "https://raw.githubusercontent.com/haskell/haskell-platform/master/hptool/src/Releases2015.hs"- ghcapi <- download "haskell-ghcapi.txt" $ "https://downloads.haskell.org/~ghc/" ++ ghcApiVersion ++ "/docs/html/libraries/ghc-" ++ ghcApiVersion ++ "/ghc.txt" cabals <- download "haskell-cabal.tar.gz" "https://hackage.haskell.org/packages/index.tar.gz" hoogles <- download "haskell-hoogle.tar.gz" "https://hackage.haskell.org/packages/hoogle.tar.gz" @@ -120,9 +120,6 @@ tar <- liftIO $ tarballReadFiles hoogles forM_ tar $ \(takeBaseName -> name, src) -> yield (name, hackagePackageURL name, src)- src <- liftIO $ strReadFile ghcapi- let url = "https://downloads.haskell.org/~ghc/" ++ ghcApiVersion ++ "/docs/html/libraries/ghc-" ++ ghcApiVersion ++ "/"- yield ("ghc", url, lstrFromChunks [src]) return (cbl, want, source)
src/Action/Search.hs view
@@ -23,7 +23,6 @@ import Action.CmdLine import General.Util - -- -- generate all -- @tagsoup -- generate tagsoup -- @tagsoup filter -- search the tagsoup package@@ -80,7 +79,7 @@ search :: StoreRead -> [Query] -> ([Query], [Target]) search store qs = runIdentity $ do- (qs, exact, filt, list) <- return $ applyTags store qs+ (qs, exact, filt, list) <- return $ applyTags store qs is <- case (filter isQueryName qs, filter isQueryType qs) of ([], [] ) -> return list ([], t:_) -> return $ searchTypes store $ hseToSig $ fromQueryType t@@ -94,6 +93,11 @@ action_search_test :: Bool -> FilePath -> IO () action_search_test sample database = testing "Action.Search.search" $ withSearch database $ \store -> do+ let noResults a = do+ res <- return $ snd $ search store (parseQuery a)+ case res of+ [] -> putChar '.'+ _ -> error $ "Searching for: " ++ show a ++ "\nGot: " ++ show (take 1 res) ++ "\n expected none" let a ==$ f = do res <- return $ snd $ search store (parseQuery a) case res of@@ -112,6 +116,8 @@ "Prelude" === hackage "base/docs/Prelude.html" "map" === hackage "base/docs/Prelude.html#v:map" "map package:base" === hackage "base/docs/Prelude.html#v:map"+ noResults "map package:package-not-in-db"+ noResults "map module:Module.Not.In.Db" "True" === hackage "base/docs/Prelude.html#v:True" "Bool" === hackage "base/docs/Prelude.html#t:Bool" "String" === hackage "base/docs/Prelude.html#t:String"@@ -136,14 +142,14 @@ -- FIXME: "author:Neil-M" === hackage "filepath" -- FIXME: "Data.Se.insert" === hackage "containers/docs/Data-Set.html#v:insert" "set:-haskell-platform author:Neil-Mitchell" === hackage "safe"- "author:Neil-Mitchell category:Development" === hackage "derive"+ "author:Neil-Mitchell category:Development" === hackage "hlint" "( )" ==$ flip seq True -- used to segfault "( -is:exact) package:base=" ==$ flip seq True "(a -> b) -> [a] -> [b]" === hackage "base/docs/Prelude.html#v:map" "Ord a => [a] -> [a]" === hackage "base/docs/Data-List.html#v:sort" "ShakeOptions -> Int" === hackage "shake/docs/Development-Shake.html#v:shakeThreads" "is:module" === hackage "base/docs/Prelude.html"- "visibleDataCons" === ("https://downloads.haskell.org/~ghc/" ++ ghcApiVersion ++ "/docs/html/libraries/ghc-" ++ ghcApiVersion ++ "/TyCon.html#v:visibleDataCons")+ "visibleDataCons" === hackage "ghc/docs/TyCon.html#v:visibleDataCons" let tags = completionTags store let asserts b x = if b then putChar '.' else error $ "Assertion failed, got False for " ++ x
src/Action/Server.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ViewPatterns, TupleSections, RecordWildCards, ScopedTypeVariables, PatternGuards #-}+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} -- getGCStats became getRTSStats module Action.Server(actionServer, actionReplay, action_server_test_, action_server_test) where @@ -85,7 +86,8 @@ let qSource = grab "hoogle" ++ filter (/= "set:stackage") qScope let q = concatMap parseQuery qSource let (q2, results) = search store q- let body = showResults local haddock inputArgs q2 $ dedupeTake 25 (\t -> t{targetURL="",targetPackage=Nothing, targetModule=Nothing}) results+ let body = showResults local haddock (filter ((/= "mode") . fst) inputArgs) q2 $+ dedupeTake 25 (\t -> t{targetURL="",targetPackage=Nothing, targetModule=Nothing}) results case lookup "mode" $ reverse inputArgs of Nothing | qSource /= [] -> fmap OutputHTML $ templateRender templateIndex $ map (second str) [("tags",tagOptions qScope)
src/General/Conduit.hs view
@@ -4,10 +4,10 @@ module General.Conduit( module Data.Conduit, MonadIO, liftIO, sourceList, sinkList, sourceLStr,- foldC, mapC, mapMaybeC, mapAccumC, filterC, concatC,+ mapC, mapAccumC, filterC, mapMC, mapAccumMC, (|$|), pipelineC, groupOnLastC,- zipFromC, linesC, linesCR+ zipFromC, linesCR ) where import Data.Conduit@@ -23,11 +23,8 @@ import Prelude -concatC = C.concat mapC = C.map mapMC = C.mapM-foldC = C.fold-mapMaybeC = C.mapMaybe mapAccumC f = C.mapAccum (\x a -> a `seq` f a x) mapAccumMC f = C.mapAccumM (\x a -> a `seq` f a x) filterC = C.filter
src/General/Store.hs view
@@ -2,7 +2,7 @@ module General.Store( Typeable, Stored,- intSize, intFromBS, intToBS, encodeBS, decodeBS,+ intSize, intFromBS, intToBS, encodeBS, StoreWrite, storeWriteFile, storeWrite, storeWritePart, StoreRead, storeReadFile, storeRead, Jagged, jaggedFromList, jaggedAsk,
src/General/Timing.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE RecordWildCards #-}+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} -- getGCStats became getRTSStats module General.Timing(Timing, withTiming, timed, timedOverwrite) where
src/General/Util.hs view
@@ -6,12 +6,12 @@ fromDeclHead, fromContext, fromIParen, fromInstHead, tarballReadFiles, isUpper1, isAlpha1,- splitPair, joinPair,- testing, testing_, testEq,+ joinPair,+ testing, testEq, showUTCTime, strict, withs,- escapeHTML, unescapeHTML, innerTextHTML, unHTML, tag, tag_,+ escapeHTML, unescapeHTML, unHTML, tag, tag_, takeSortOn, Average, toAverage, fromAverage, inRanges,@@ -19,9 +19,8 @@ parseTrailingVersion, exitFail, prettyTable,- ghcApiVersion, hackagePackageURL, hackageModuleURL, hackageDeclURL, ghcModuleURL,- minimum', maximum', minimumBy', maximumBy',+ minimum', maximum', general_util_test ) where @@ -56,9 +55,6 @@ -- | A URL, complete with a @https:@ prefix. type URL = String--ghcApiVersion :: String-ghcApiVersion = "8.0.1" exitFail :: String -> IO () exitFail msg = do
src/Output/Tags.hs view
@@ -103,19 +103,20 @@ --------------------------------------------------------------------- -- TAG SEMANTICS --- | Given a tag, find the ranges of identifiers it covers-resolveTag :: StoreRead -> Tag -> (Maybe Tag, [(TargetId,TargetId)])+-- | Given a tag, find the ranges of identifiers it covers (if it restricts the range)+-- An empty range means an empty result, while a Nothing means a search on the entire range+resolveTag :: StoreRead -> Tag -> (Tag, Maybe [(TargetId,TargetId)]) resolveTag store x = case x of- IsExact -> (Just IsExact, [])- IsPackage -> (Just IsPackage, map (dupe . fst) $ V.toList packageIds)- IsModule -> (Just IsModule, map (dupe . fst) $ V.toList moduleIds)- EqPackage (BS.pack . lower -> val)+ IsExact -> (IsExact, Nothing)+ IsPackage -> (IsPackage, Just $ map (dupe . fst) $ V.toList packageIds)+ IsModule -> (IsModule, Just $ map (dupe . fst) $ V.toList moduleIds)+ EqPackage orig@(BS.pack -> val) -- look for people who are an exact prefix, sort by remaining length, if there are ties, pick the first one | res@(_:_) <- [(BS.length x, (i,x)) | (i,x) <- zip [0..] $ split0 packageNames, val `BS.isPrefixOf` x]- -> let (i,x) = snd $ minimumBy (compare `on` fst) res in (Just $ EqPackage $ BS.unpack x, [packageIds V.! i])- | otherwise -> (Nothing, [])- EqModule x -> (Just $ EqModule x, map (moduleIds V.!) $ findIndices (eqModule $ lower x) $ split0 moduleNames)- EqCategory cat val -> (Just $ EqCategory cat val, concat+ -> let (i,x) = snd $ minimumBy (compare `on` fst) res in (EqPackage $ BS.unpack x, Just [packageIds V.! i])+ | otherwise -> (EqPackage orig , Just [])+ EqModule x -> (EqModule x, Just $ map (moduleIds V.!) $ findIndices (eqModule $ lower x) $ split0 moduleNames)+ EqCategory cat val -> (EqCategory cat val, Just $ concat [ V.toList $ jaggedAsk categoryIds i | i <- elemIndices (BS.pack (cat ++ ":" ++ val)) $ split0 categoryNames]) where@@ -143,21 +144,30 @@ where fs = map (filterTags2 ts . snd) $ groupSort $ map (scopeCategory &&& id) $ filter isQueryScope qs exact = Just IsExact `elem` [parseTag a b | QueryScope True a b <- qs] redo (QueryScope sense cat val)- | Just (k,v) <- fmap showTag $ fst . resolveTag ts =<< parseTag cat val = QueryScope sense k v+ | Just (k,v) <- fmap (showTag . fst . resolveTag ts) $ parseTag cat val = QueryScope sense k v | otherwise = QueryNone $ ['-' | not sense] ++ cat ++ ":" ++ val redo q = q -filterTags2 ts qs = \i -> not (negq i) && (null pos || posq i)+filterTags2 ts qs = \i -> not (negq i) && (noPosRestrict || posq i) where (posq,negq) = both inRanges (pos,neg)- (pos, neg) = both (map snd) $ partition fst $ concatMap f qs- f (QueryScope sense cat val) = map (sense,) $ maybe [] (snd . resolveTag ts) $ parseTag cat val+ (pos, neg) = both (concatMap snd) $ partition fst xs+ xs = catMaybes restrictions+ noPosRestrict = all pred restrictions+ restrictions = map getRestriction qs+ pred Nothing = True+ pred (Just (sense, _)) = not sense+ getRestriction :: Query -> Maybe (Bool,[(TargetId, TargetId)])+ getRestriction (QueryScope sense cat val) = do+ tag <- parseTag cat val+ ranges <- snd $ resolveTag ts tag+ return (sense, ranges) -- | Given a search which has no type or string in it, run the query on the tag bits. -- Using for things like IsModule, EqCategory etc. searchTags :: StoreRead -> [Query] -> [TargetId] searchTags ts qs- | x:xs <- [map fst $ maybe [] (snd . resolveTag ts) $ parseTag cat val | QueryScope True cat val <- qs]+ | x:xs <- [map fst $ maybe [] (fromMaybe [] . snd . resolveTag ts) $ parseTag cat val | QueryScope True cat val <- qs] = if null xs then x else filter (`Set.member` foldl1' Set.intersection (map Set.fromList xs)) x-searchTags ts _ = map fst $ snd $ resolveTag ts IsPackage+searchTags ts _ = map fst $ fromMaybe [] $ snd $ resolveTag ts IsPackage
src/Query.hs view
@@ -73,7 +73,10 @@ where bs = zipWith (++) openBrackets shutBrackets ++ openBrackets ++ shutBrackets lexer (x:xs) | isSpace x = " " : lexer (dropWhile isSpace xs)- | isAlpha x || x == '_' = let (a,b) = span (\x -> isAlphaNum x || x `elem` "_'#-") xs in (x:a) : lexer b+ | isAlpha x || x == '_' =+ let (a,b) = span (\x -> isAlphaNum x || x `elem` "_'#-") xs+ (a1,a2) = spanEnd (== '-') a+ in (x:a1) : lexer (a2 ++ b) | isSym x = let (a,b) = span isSym xs in (x:a) : lexer b | x == ',' = "," : lexer xs | otherwise = lexer xs -- drop invalid bits@@ -192,6 +195,7 @@ "Int#" === name "Int#" "concat map" === name "concat" . name "map" "a -> b" === typ "a -> b"+ "a->b" === typ "a -> b" "(a b)" === typ "(a b)" "map :: a -> b" === typ "a -> b" "+Data.Map map" === scope True "module" "Data.Map" . name "map"