1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript.Name
21import qualified Data.ByteString.Builder as B
22import Data.Monoid ((<>))
23import qualified Data.Map as Map
24import qualified Data.Name as Name
25import qualified Data.Set as Set
26import qualified Data.Utf8 as Utf8
27import Data.Word (Word8)
29import qualified Data.Index as Index
30import qualified Elm.ModuleName as ModuleName
31import qualified Elm.Package as Pkg
39 Name { toBuilder :: B.Builder }
46fromIndex :: Index.ZeroBased -> Name
48 fromInt (Index.toMachine index)
53 Name (Name.toBuilder (intToAscii n))
56fromLocal :: Name.Name -> Name
58 if Set.member name reservedNames then
59 Name ("_" <> Name.toBuilder name)
61 Name (Name.toBuilder name)
64fromGlobal :: ModuleName.Canonical -> Name.Name -> Name
65fromGlobal (ModuleName.Canonical (Pkg.Name author project) home) name =
66 Name $ Name.toEscapedBuilder 0x2D {- - -} 0x5F {- _ -} author
67 <> "$" <> Name.toEscapedBuilder 0x2D {- - -} 0x5F {- _ -} project
68 <> "$" <> Name.toEscapedBuilder 0x2E {- . -} 0x24 {- $ -} home
69 <> "$" <> Name.toBuilder name
72fromCycle :: ModuleName.Canonical -> Name.Name -> Name
73fromCycle (ModuleName.Canonical (Pkg.Name author project) home) name =
74 Name $ Name.toEscapedBuilder 0x2D {- - -} 0x5F {- _ -} author
75 <> "$" <> Name.toEscapedBuilder 0x2D {- - -} 0x5F {- _ -} project
76 <> "$" <> Name.toEscapedBuilder 0x2E {- . -} 0x24 {- $ -} home
77 <> "$cyclic$" <> Name.toBuilder name
80fromKernel :: Name.Name -> Name.Name -> Name
82 Name ("_" <> Name.toBuilder home <> "_" <> Name.toBuilder name)
91 Name ("F" <> B.intDec n)
96 Name ("A" <> B.intDec n)
99makeLabel :: Name.Name -> Int -> Name
100makeLabel name index =
101 Name (Name.toBuilder name <> "$" <> B.intDec index)
104makeTemp :: Name.Name -> Name
106 Name ("$temp$" <> Name.toBuilder name)
111 Name (Name.toBuilder Name.dollar)
118{-# NOINLINE reservedNames #-}
119reservedNames :: Set.Set Name.Name
121 Set.union jsReservedWords elmReservedWords
124jsReservedWords :: Set.Set Name.Name
128 , "NaN", "int", "for", "new", "try", "var", "let"
129 , "null", "true", "eval", "byte", "char", "goto", "long", "case", "else", "this", "void", "with", "enum"
130 , "false", "final", "float", "short", "break", "catch", "throw", "while", "class", "const", "super", "yield"
131 , "double", "native", "throws", "delete", "return", "switch", "typeof", "export", "import", "public", "static"
132 , "boolean", "default", "finally", "extends", "package", "private"
133 , "Infinity", "abstract", "volatile", "function", "continue", "debugger", "function"
134 , "undefined", "arguments", "transient", "interface", "protected"
135 , "instanceof", "implements"
140elmReservedWords :: Set.Set Name.Name
143 [ "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
144 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
152intToAscii :: Int -> Name.Name
154 if n < 53 then -- skip $ as a standalone name
155 Name.fromWords [toByte n]
158 intToAsciiHelp 2 (numStartBytes * numInnerBytes) allBadFields (n - 53)
161intToAsciiHelp :: Int -> Int -> [BadFields] -> Int -> Name.Name
162intToAsciiHelp width blockSize badFields n =
165 if n < blockSize then
166 unsafeIntToAscii width [] n
168 intToAsciiHelp (width + 1) (blockSize * numInnerBytes) [] (n - blockSize)
170 BadFields renamings : biggerBadFields ->
171 let availableSize = blockSize - Map.size renamings in
172 if n < availableSize then
173 let name = unsafeIntToAscii width [] n in
174 Map.findWithDefault name name renamings
176 intToAsciiHelp (width + 1) (blockSize * numInnerBytes) biggerBadFields (n - availableSize)
180-- UNSAFE INT TO ASCII
183unsafeIntToAscii :: Int -> [Word8] -> Int -> Name.Name
184unsafeIntToAscii width bytes n =
186 Name.fromWords (toByte n : bytes)
189 (quotient, remainder) =
190 quotRem n numInnerBytes
192 unsafeIntToAscii (width - 1) (toByte remainder : bytes) quotient
209toByte :: Int -> Word8
211 | n < 26 = fromIntegral (97 + n ) {- lower -}
212 | n < 52 = fromIntegral (65 + n - 26) {- upper -}
213 | n == 52 = 95 {- _ -}
214 | n == 53 = 36 {- $ -}
215 | n < 64 = fromIntegral (48 + n - 54) {- digit -}
216 | True = error $ "cannot convert int " ++ show n ++ " to ASCII"
224 BadFields { _renamings :: Renamings }
228 Map.Map Name.Name Name.Name
231allBadFields :: [BadFields]
235 Map.alter (Just . addRenaming keyword) (Utf8.size keyword) dict
237 Map.elems $ Set.foldr add Map.empty jsReservedWords
240addRenaming :: Name.Name -> Maybe BadFields -> BadFields
241addRenaming keyword maybeBadFields =
243 width = Utf8.size keyword
244 maxName = numStartBytes * numInnerBytes ^ (width - 1) - 1
246 case maybeBadFields of
248 BadFields $ Map.singleton keyword (unsafeIntToAscii width [] maxName)
250 Just (BadFields renamings) ->
251 BadFields $ Map.insert keyword (unsafeIntToAscii width [] (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