1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript.Name
24import qualified Data.ByteString.Builder as B
25import qualified Data.ByteString.Short as S
26import qualified Data.List as List
27import Data.Monoid ((<>))
29import qualified Data.Map as Map
30import qualified Data.Set as Set
31import qualified Data.Text as Text
32import qualified Data.Text.Encoding as Text
33import Data.Word (Word8)
35import qualified AST.Module.Name as ModuleName
36import qualified Data.Index as Index
37import qualified Elm.Name as N
38import qualified Elm.Package as Pkg
46 Name { toBuilder :: B.Builder }
55 | Prod Target ShortFieldNames
58data Target = Client | Server
65isServer :: Mode -> Bool
68 Debug target -> isServerHelp target
69 Prod target _ -> isServerHelp target
72isServerHelp :: Target -> Bool
74 case target of { Client -> False ; Server -> True }
81fromIndex :: Index.ZeroBased -> Name
83 fromInt (Index.toMachine index)
88 Name (B.shortByteString (intToAscii n))
91fromLocal :: N.Name -> Name
93 if Set.member name reservedNames then
94 Name ("_" <> N.toBuilder name)
96 Name (N.toBuilder name)
99fromGlobal :: ModuleName.Canonical -> N.Name -> Name
100fromGlobal (ModuleName.Canonical (Pkg.Name user project) home) name =
102 Text.encodeUtf8Builder (Text.replace "-" "_" user)
103 <> "$" <> Text.encodeUtf8Builder (Text.replace "-" "_" project) -- TODO store this in a better way
104 <> "$" <> N.toBuilder home
105 <> "$" <> N.toBuilder name
108fromCycle :: ModuleName.Canonical -> N.Name -> Name
109fromCycle (ModuleName.Canonical (Pkg.Name user project) home) name =
111 Text.encodeUtf8Builder (Text.replace "-" "_" user)
112 <> "$" <> Text.encodeUtf8Builder (Text.replace "-" "_" project) -- TODO store this in a better way
113 <> "$" <> N.toBuilder home
114 <> "$cyclic$" <> N.toBuilder name
117fromKernel :: N.Name -> N.Name -> Name
118fromKernel home name =
119 Name ("_" <> N.toBuilder home <> "_" <> N.toBuilder name)
122fromField :: Mode -> N.Name -> Name
126 Name (N.toBuilder name)
136makeLabel :: N.Name -> Int -> Name
137makeLabel name index =
138 Name (N.toBuilder name <> "$" <> B.intDec index)
141makeTemp :: N.Name -> Name
143 Name ("$temp$" <> N.toBuilder name)
148 Name (N.toBuilder N.dollar)
152-- SHORTEN FIELD NAMES
155shortenFieldNames :: Map.Map N.Name Int -> ShortFieldNames
156shortenFieldNames frequencies =
157 Map.foldr addToShortNames Map.empty $
158 Map.foldrWithKey addToBuckets Map.empty frequencies
161addToBuckets :: N.Name -> Int -> Map.Map Int [N.Name] -> Map.Map Int [N.Name]
162addToBuckets field frequency buckets =
163 -- TODO try using an IntMap for buckets
164 Map.insertWith (++) frequency [field] buckets
167addToShortNames :: [N.Name] -> ShortFieldNames -> ShortFieldNames
168addToShortNames fields shortNames =
169 List.foldl' addField shortNames fields
172addField :: ShortFieldNames -> N.Name -> ShortFieldNames
173addField shortNames field =
174 let rename = fromInt (Map.size shortNames) in
175 Map.insert field rename shortNames
182{-# NOINLINE reservedNames #-}
183reservedNames :: Set.Set N.Name
185 Set.union jsReservedWords elmReservedWords
188jsReservedWords :: Set.Set N.Name
192 , "NaN", "int", "for", "new", "try", "var", "let"
193 , "null", "true", "eval", "byte", "char", "goto", "long", "case", "else", "this", "void", "with", "enum"
194 , "false", "final", "float", "short", "break", "catch", "throw", "while", "class", "const", "super", "yield"
195 , "double", "native", "throws", "delete", "return", "switch", "typeof", "export", "import", "public", "static"
196 , "boolean", "default", "finally", "extends", "package", "private"
197 , "Infinity", "abstract", "volatile", "function", "continue", "debugger", "function"
198 , "undefined", "arguments", "transient", "interface", "protected"
199 , "instanceof", "implements"
204elmReservedWords :: Set.Set N.Name
207 [ "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
208 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
216intToAscii :: Int -> S.ShortByteString
218 if n < 53 then -- skip $ as a standalone name
222 intToAsciiHelp (numStartBytes * numInnerBytes) allBadFields (n - 53)
225intToAsciiHelp :: Int -> [BadFields] -> Int -> S.ShortByteString
226intToAsciiHelp blockSize badFields n =
229 if n < blockSize then
232 intToAsciiHelp (blockSize * numInnerBytes) [] (n - blockSize)
234 BadFields renamings : biggerBadFields ->
235 let availableSize = blockSize - Map.size renamings in
236 if n < availableSize then
237 let name = unsafeIntToAscii n in
238 Map.findWithDefault name name renamings
240 intToAsciiHelp (blockSize * numInnerBytes) biggerBadFields (n - availableSize)
244-- UNSAFE INT TO ASCII
247unsafeIntToAscii :: Int -> S.ShortByteString
250 (quotient, remainder) =
251 quotRem n numStartBytes
253 S.pack $ toByte remainder : unsafeIntToAsciiHelp quotient
256unsafeIntToAsciiHelp :: Int -> [Word8]
257unsafeIntToAsciiHelp n =
261 let (quotient, remainder) = quotRem n numInnerBytes in
262 toByte remainder : unsafeIntToAsciiHelp quotient
279toByte :: Int -> Word8
281 | n < 26 = fromIntegral (97 + n ) {- lower -}
282 | n < 52 = fromIntegral (65 + n - 26) {- upper -}
283 | n == 53 = 95 {- _ -}
284 | n == 54 = 36 {- $ -}
285 | n < 64 = fromIntegral (48 + n - 54) {- digit -}
286 | True = error $ "cannot convert int " ++ show n ++ " to ASCII"
294 BadFields { _renamings :: Renamings }
298 Map.Map S.ShortByteString S.ShortByteString
301allBadFields :: [BadFields]
305 Map.alter (Just . addRenaming keyword) (N.length keyword) dict
307 Map.elems $ Set.foldr add Map.empty jsReservedWords
310addRenaming :: N.Name -> Maybe BadFields -> BadFields
311addRenaming keyword maybeBadFields =
314 numStartBytes * numInnerBytes ^ (N.length keyword - 1) - 1
316 case maybeBadFields of
318 BadFields $ Map.singleton (N.toShort keyword) (unsafeIntToAscii maxName)
320 Just (BadFields renamings) ->
321 BadFields $ Map.insert (N.toShort keyword) (unsafeIntToAscii (maxName - Map.size renamings)) renamings
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list