1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript.Name
21import qualified Data.ByteString.Builder as B
22import qualified Data.ByteString.Short as S
23import Data.Monoid ((<>))
24import qualified Data.Map as Map
25import qualified Data.Set as Set
26import qualified Data.Text as Text
27import qualified Data.Text.Encoding as Text
28import Data.Word (Word8)
30import qualified AST.Module.Name as ModuleName
31import qualified Data.Index as Index
32import qualified Elm.Name as N
33import qualified Elm.Package as Pkg
41 Name { toBuilder :: B.Builder }
48fromIndex :: Index.ZeroBased -> Name
50 fromInt (Index.toMachine index)
55 Name (B.shortByteString (intToAscii n))
58fromLocal :: N.Name -> Name
60 if Set.member name reservedNames then
61 Name ("_" <> N.toBuilder name)
63 Name (N.toBuilder name)
66fromGlobal :: ModuleName.Canonical -> N.Name -> Name
67fromGlobal (ModuleName.Canonical (Pkg.Name user project) home) name =
69 Text.encodeUtf8Builder (Text.replace "-" "_" user)
70 <> "$" <> Text.encodeUtf8Builder (Text.replace "-" "_" project) -- TODO store this in a better way
71 <> "$" <> N.toDotlessBuilder home
72 <> "$" <> N.toBuilder name
75fromCycle :: ModuleName.Canonical -> N.Name -> Name
76fromCycle (ModuleName.Canonical (Pkg.Name user project) home) name =
78 Text.encodeUtf8Builder (Text.replace "-" "_" user)
79 <> "$" <> Text.encodeUtf8Builder (Text.replace "-" "_" project) -- TODO store this in a better way
80 <> "$" <> N.toDotlessBuilder home
81 <> "$cyclic$" <> N.toBuilder name
84fromKernel :: N.Name -> N.Name -> Name
86 Name ("_" <> N.toBuilder home <> "_" <> N.toBuilder name)
95 Name ("F" <> B.intDec n)
100 Name ("A" <> B.intDec n)
103makeLabel :: N.Name -> Int -> Name
104makeLabel name index =
105 Name (N.toBuilder name <> "$" <> B.intDec index)
108makeTemp :: N.Name -> Name
110 Name ("$temp$" <> N.toBuilder name)
115 Name (N.toBuilder N.dollar)
122{-# NOINLINE reservedNames #-}
123reservedNames :: Set.Set N.Name
125 Set.union jsReservedWords elmReservedWords
128jsReservedWords :: Set.Set N.Name
132 , "NaN", "int", "for", "new", "try", "var", "let"
133 , "null", "true", "eval", "byte", "char", "goto", "long", "case", "else", "this", "void", "with", "enum"
134 , "false", "final", "float", "short", "break", "catch", "throw", "while", "class", "const", "super", "yield"
135 , "double", "native", "throws", "delete", "return", "switch", "typeof", "export", "import", "public", "static"
136 , "boolean", "default", "finally", "extends", "package", "private"
137 , "Infinity", "abstract", "volatile", "function", "continue", "debugger", "function"
138 , "undefined", "arguments", "transient", "interface", "protected"
139 , "instanceof", "implements"
144elmReservedWords :: Set.Set N.Name
147 [ "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
148 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
156intToAscii :: Int -> S.ShortByteString
158 if n < 53 then -- skip $ as a standalone name
162 intToAsciiHelp 2 (numStartBytes * numInnerBytes) allBadFields (n - 53)
165intToAsciiHelp :: Int -> Int -> [BadFields] -> Int -> S.ShortByteString
166intToAsciiHelp width blockSize badFields n =
169 if n < blockSize then
170 unsafeIntToAscii width [] n
172 intToAsciiHelp (width + 1) (blockSize * numInnerBytes) [] (n - blockSize)
174 BadFields renamings : biggerBadFields ->
175 let availableSize = blockSize - Map.size renamings in
176 if n < availableSize then
177 let name = unsafeIntToAscii width [] n in
178 Map.findWithDefault name name renamings
180 intToAsciiHelp (width + 1) (blockSize * numInnerBytes) biggerBadFields (n - availableSize)
184-- UNSAFE INT TO ASCII
187unsafeIntToAscii :: Int -> [Word8] -> Int -> S.ShortByteString
188unsafeIntToAscii width bytes n =
190 S.pack (toByte n : bytes)
193 (quotient, remainder) =
194 quotRem n numInnerBytes
196 unsafeIntToAscii (width - 1) (toByte remainder : bytes) quotient
213toByte :: Int -> Word8
215 | n < 26 = fromIntegral (97 + n ) {- lower -}
216 | n < 52 = fromIntegral (65 + n - 26) {- upper -}
217 | n == 52 = 95 {- _ -}
218 | n == 53 = 36 {- $ -}
219 | n < 64 = fromIntegral (48 + n - 54) {- digit -}
220 | True = error $ "cannot convert int " ++ show n ++ " to ASCII"
228 BadFields { _renamings :: Renamings }
232 Map.Map S.ShortByteString S.ShortByteString
235allBadFields :: [BadFields]
239 Map.alter (Just . addRenaming keyword) (N.length keyword) dict
241 Map.elems $ Set.foldr add Map.empty jsReservedWords
244addRenaming :: N.Name -> Maybe BadFields -> BadFields
245addRenaming keyword maybeBadFields =
247 width = N.length keyword
248 maxName = numStartBytes * numInnerBytes ^ (width - 1) - 1
250 case maybeBadFields of
252 BadFields $ Map.singleton (N.toShort keyword) (unsafeIntToAscii width [] maxName)
254 Just (BadFields renamings) ->
255 BadFields $ Map.insert (N.toShort 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