This commit is contained in:
Mark Probst 2017-09-07 07:50:39 -07:00
Родитель 2818d0b2f9
Коммит 237d0cd66a
2 изменённых файлов: 22 добавлений и 0 удалений

Просмотреть файл

@ -285,12 +285,17 @@ replaceClass from to = do
replaceTypes $ (replaceClassesInType \i -> if i == from then Just to else Nothing)
deleteClass from
-- This maps from old class index to new class index and new class data
type ClassMapper = State (Map Int (Tuple Int (Maybe IRClassData)))
normalizeGraphOrder :: IRGraph -> IRGraph
normalizeGraphOrder graph@(IRGraph { toplevels }) =
evalState work M.empty
where
-- When we encounter a class we first check whether we've seen
-- it before (Right), or whether it's new (Left). In the Left
-- case, we get a new index for the class, and the index is added
-- to the map.
registerClass :: Int -> ClassMapper (Either Int Int)
registerClass oldIndex = do
m <- get
@ -301,6 +306,8 @@ normalizeGraphOrder graph@(IRGraph { toplevels }) =
put $ M.insert oldIndex (Tuple newIndex Nothing) m
pure $ Left newIndex
-- After we're done processing a new class, we update the
-- entry in the map with its IRClassData.
setClass :: Int -> IRClassData -> ClassMapper Unit
setClass oldIndex cd = do
m <- get

Просмотреть файл

@ -84,6 +84,21 @@ newtype JSONSchema = JSONSchema
, title :: Maybe String
}
-- For recursive JSON Schemas we must not reenter a class we've
-- already begun processing. The way we ensure this is to keep
-- a map of the reference paths of all the classes we've encountered
-- so far. It maps to each class's index in the graph.
--
-- Of course we can only set the entry in the graph properly once
-- we're done with processing the class, but we need to reserve
-- the index when starting processing the class. As a simple solution
-- we just set the entry to `NoType`` when we start, then replace it
-- with the finished `Class`` entry when we're done.
--
-- FIXME: We don't actually need the IR monad because the path map
-- itself can keep track of the index of each class as well as the
-- number of classes seen so far (which is also the index of the next
-- class to be added). Similar to `normalizeGraphOrder`.
type JsonIR = StateT.StateT (Map ReversePath Int) IR
decodeEnum :: forall a. StrMap a -> Json -> Either Error a