3 | import Core.Context.Log
5 | import Core.Normalise
9 | import Libraries.Data.NatSet
10 | import Libraries.Data.PosMap
12 | import public Protocol.IDE.Decoration as Protocol.IDE
17 | nameDecoration : Name -> NameType -> Decoration
18 | nameDecoration nm nt
19 | = ifThenElse (isUnsafeBuiltin nm) Postulate (nameTypeDecoration nt)
23 | nameTypeDecoration : NameType -> Decoration
24 | nameTypeDecoration Bound = Bound
25 | nameTypeDecoration Func = Function
26 | nameTypeDecoration (DataCon {}) = Data
27 | nameTypeDecoration (TyCon {}) = Typ
31 | ASemanticDecoration : Type
32 | ASemanticDecoration = (NonEmptyFC, Decoration, Maybe Name)
35 | SemanticDecorations : Type
36 | SemanticDecorations = List ASemanticDecoration
38 | TTC Decoration where
40 | toBuf Function = tag 1
42 | toBuf Keyword = tag 3
44 | toBuf Namespace = tag 5
45 | toBuf Postulate = tag 6
46 | toBuf Module = tag 7
47 | toBuf Comment = tag 8
59 | _ => corrupt "Decoration"
62 | record Metadata where
63 | constructor MkMetadata
67 | lhsApps : List (NonEmptyFC, (Nat, ClosedTerm))
73 | names : List (NonEmptyFC, (Name, Nat, ClosedTerm))
76 | tydecls : List (NonEmptyFC, (Name, Nat, ClosedTerm))
82 | currentLHS : Maybe ClosedTerm
83 | holeLHS : List (Name, ClosedTerm)
84 | nameLocMap : PosMap (NonEmptyFC, Name)
85 | sourceIdent : OriginDesc
89 | semanticHighlighting : PosMap ASemanticDecoration
93 | semanticAliases : PosMap (NonEmptyFC, NonEmptyFC)
97 | semanticDefaults : PosMap ASemanticDecoration
103 | allSemanticHighlighting :
104 | {auto c : Ref Ctxt Defs} ->
105 | Metadata -> Core (PosMap ASemanticDecoration)
106 | allSemanticHighlighting meta = do
107 | let semHigh = meta.semanticHighlighting
108 | log "ide-mode.highlight" 19 $
109 | "Semantic metadata is: " ++ show semHigh
112 | : List ASemanticDecoration
113 | = flip foldMap meta.semanticAliases $
\ (from, to) =>
114 | let decors = uncurry exactRange (snd to) semHigh in
115 | map (\ ((fnm, loc), rest) => ((fnm, snd from), rest)) decors
116 | log "ide-mode.highlight.alias" 19 $
117 | "Semantic metadata from aliases is: " ++ show aliases
120 | : List ASemanticDecoration
121 | = flip foldMap meta.semanticDefaults $
\ decor@((_, range), _) =>
122 | case uncurry exactRange range semHigh of
126 | pure (fromList aliases `union` (fromList defaults `union` semHigh))
129 | Show Metadata where
130 | show (MkMetadata apps names tydecls currentLHS holeLHS nameLocMap
131 | fname semanticHighlighting semanticAliases semanticDefaults) = """
133 | lhsApps: \{ show apps }
134 | names: \{ show names }
135 | type declarations: \{ show tydecls }
136 | current LHS: \{ show currentLHS }
137 | holes: \{ show holeLHS }
138 | nameLocMap: \{ show nameLocMap }
139 | sourceIdent: \{ show fname }
140 | semanticHighlighting: \{ show semanticHighlighting }
141 | semanticAliases: \{ show semanticAliases }
142 | semanticDefaults: \{ show semanticDefaults }
146 | initMetadata : OriginDesc -> Metadata
147 | initMetadata finfo = MkMetadata
151 | , currentLHS = Nothing
153 | , nameLocMap = empty
154 | , sourceIdent = finfo
155 | , semanticHighlighting = empty
156 | , semanticAliases = empty
157 | , semanticDefaults = empty
162 | data MD : Type where
166 | = do toBuf (lhsApps m)
170 | toBuf (nameLocMap m)
171 | toBuf (sourceIdent m)
172 | toBuf (semanticHighlighting m)
173 | toBuf (semanticAliases m)
174 | toBuf (semanticDefaults m)
177 | = do apps <- fromBuf
186 | pure (MkMetadata apps ns tys Nothing hlhs dlocs fname semhl semal semdef)
189 | addLHS : {vars : _} ->
190 | {auto c : Ref Ctxt Defs} ->
191 | {auto m : Ref MD Metadata} ->
192 | FC -> Nat -> Env Term vars -> Term vars -> Core ()
193 | addLHS loc outerenvlen env tm
194 | = do meta <- get MD
195 | tm' <- toFullNames (bindEnv loc (toPat env) tm)
197 | whenJust (isNonEmptyFC loc) $
\ neloc =>
198 | put MD $
{ lhsApps $= ((neloc, outerenvlen, tm') ::) } meta
201 | toPat : Env Term vs -> Env Term vs
202 | toPat (Lam fc c p ty :: bs) = PVar fc c p ty :: toPat bs
203 | toPat (b :: bs) = b :: toPat bs
214 | substEnv : {vars : _} ->
215 | FC -> Env Term vars -> (tm : Term vars) -> ClosedTerm
216 | substEnv loc [] tm = tm
217 | substEnv {vars = x :: _} loc (b :: env) tm
218 | = substEnv loc env (subst (Ref loc Bound x) tm)
221 | addNameType : {vars : _} ->
222 | {auto c : Ref Ctxt Defs} ->
223 | {auto m : Ref MD Metadata} ->
224 | FC -> Name -> Env Term vars -> Term vars -> Core ()
225 | addNameType loc n env tm
226 | = do meta <- get MD
227 | n' <- getFullName n
230 | whenJust (isConcreteFC loc) $
\ neloc => do
231 | put MD $
{ names $= ((neloc, (n', 0, substEnv loc env tm)) ::) } meta
232 | log "metadata.names" 7 $
show n' ++ " at line " ++ show (1 + startLine neloc)
235 | addTyDecl : {vars : _} ->
236 | {auto c : Ref Ctxt Defs} ->
237 | {auto m : Ref MD Metadata} ->
238 | FC -> Name -> Env Term vars -> Term vars -> Core ()
239 | addTyDecl loc n env tm
240 | = do meta <- get MD
241 | n' <- getFullName n
244 | whenJust (isNonEmptyFC loc) $
\ neloc =>
245 | put MD $
{ tydecls $= ( (neloc, (n', length env, bindEnv loc env tm)) ::) } meta
248 | addNameLoc : {auto m : Ref MD Metadata} ->
249 | {auto c : Ref Ctxt Defs} ->
250 | FC -> Name -> Core ()
252 | = do meta <- get MD
253 | n' <- getFullName n
254 | whenJust (isConcreteFC loc) $
\neloc =>
255 | put MD $
{ nameLocMap $= insert (neloc, n') } meta
258 | setHoleLHS : {auto m : Ref MD Metadata} -> ClosedTerm -> Core ()
259 | setHoleLHS tm = update MD { currentLHS := Just tm }
262 | clearHoleLHS : {auto m : Ref MD Metadata} -> Core ()
263 | clearHoleLHS = update MD { currentLHS := Nothing }
266 | withCurrentLHS : {auto c : Ref Ctxt Defs} ->
267 | {auto m : Ref MD Metadata} ->
270 | = do meta <- get MD
271 | n' <- getFullName n
273 | (\lhs => put MD ({ holeLHS $= ((n', lhs) ::) } meta))
276 | findEntryWith : (NonEmptyFC -> a -> Bool) -> List (NonEmptyFC, a) -> Maybe (NonEmptyFC, a)
277 | findEntryWith = find . uncurry
280 | findLHSAt : {auto m : Ref MD Metadata} ->
281 | (NonEmptyFC -> ClosedTerm -> Bool) ->
282 | Core (Maybe (NonEmptyFC, Nat, ClosedTerm))
284 | = do meta <- get MD
285 | pure (findEntryWith (\ loc, tm => p loc (snd tm)) (lhsApps meta))
288 | findTypeAt : {auto m : Ref MD Metadata} ->
289 | (NonEmptyFC -> (Name, Nat, ClosedTerm) -> Bool) ->
290 | Core (Maybe (Name, Nat, ClosedTerm))
292 | = do meta <- get MD
293 | pure (map snd (findEntryWith p (names meta)))
296 | findTyDeclAt : {auto m : Ref MD Metadata} ->
297 | (NonEmptyFC -> (Name, Nat, ClosedTerm) -> Bool) ->
298 | Core (Maybe (NonEmptyFC, Name, Nat, ClosedTerm))
300 | = do meta <- get MD
301 | pure (findEntryWith p (tydecls meta))
304 | findHoleLHS : {auto m : Ref MD Metadata} ->
305 | Name -> Core (Maybe ClosedTerm)
307 | = do meta <- get MD
308 | pure (lookupBy (\x, y => dropNS x == dropNS y) hn (holeLHS meta))
311 | addSemanticDefault : {auto m : Ref MD Metadata} ->
312 | ASemanticDecoration -> Core ()
313 | addSemanticDefault asem = update MD { semanticDefaults $= insert asem }
316 | addSemanticAlias : {auto m : Ref MD Metadata} ->
317 | NonEmptyFC -> NonEmptyFC -> Core ()
318 | addSemanticAlias from to = update MD { semanticAliases $= insert (from, to) }
321 | addSemanticDecorations : {auto m : Ref MD Metadata} ->
322 | {auto c : Ref Ctxt Defs} ->
323 | SemanticDecorations -> Core ()
324 | addSemanticDecorations decors
325 | = do meta <- get MD
326 | let posmap = meta.semanticHighlighting
327 | let (newDecors,droppedDecors) =
329 | ( (meta.sourceIdent ==)
333 | unless (isNil droppedDecors)
334 | $
log "ide-mode.highlight" 19 $
"ignored adding decorations to "
335 | ++ show meta.sourceIdent ++ ": " ++ show droppedDecors
336 | put MD $
{semanticHighlighting
337 | := (fromList newDecors) `union` posmap} meta
342 | normaliseTypes : {auto m : Ref MD Metadata} ->
343 | {auto c : Ref Ctxt Defs} ->
346 | = do meta <- get MD
348 | ns' <- traverse (nfType defs) (names meta)
349 | put MD ({ names := ns' } meta)
351 | nfType : Defs -> (NonEmptyFC, (Name, Nat, ClosedTerm)) ->
352 | Core (NonEmptyFC, (Name, Nat, ClosedTerm))
353 | nfType defs (loc, (n, len, ty))
354 | = pure (loc, (n, len, !(normaliseArgHoles defs Env.empty ty)))
356 | record TTMFile where
357 | constructor MkTTMFile
359 | metadata : Metadata
364 | toBuf (version file)
365 | toBuf (metadata file)
368 | = do hdr <- fromBuf
369 | when (hdr /= "TTM") $
corrupt "TTM header"
371 | checkTTCVersion "" ver ttcVersion
373 | pure (MkTTMFile ver md)
375 | HasNames Metadata where
377 | = pure $
{ lhsApps := !(traverse fullLHS $
md.lhsApps)
378 | , names := !(traverse fullTy $
md.names)
379 | , tydecls := !(traverse fullTy $
md.tydecls)
380 | , currentLHS := Nothing
381 | , holeLHS := !(traverse fullHLHS $
md.holeLHS)
382 | , nameLocMap := fromList !(traverse fullDecls (toList $
md.nameLocMap))
385 | fullLHS : (NonEmptyFC, (Nat, ClosedTerm)) -> Core (NonEmptyFC, (Nat, ClosedTerm))
386 | fullLHS (fc, (i, tm)) = pure (fc, (i, !(full gam tm)))
388 | fullTy : (NonEmptyFC, (Name, Nat, ClosedTerm)) -> Core (NonEmptyFC, (Name, Nat, ClosedTerm))
389 | fullTy (fc, (n, i, tm)) = pure (fc, (!(full gam n), i, !(full gam tm)))
391 | fullHLHS : (Name, ClosedTerm) -> Core (Name, ClosedTerm)
392 | fullHLHS (n, tm) = pure (!(full gam n), !(full gam tm))
394 | fullDecls : (NonEmptyFC, Name) -> Core (NonEmptyFC, Name)
395 | fullDecls (fc, n) = pure (fc, !(full gam n))
397 | resolved gam (MkMetadata lhs ns tys clhs hlhs dlocs fname semhl semal semdef)
398 | = pure $
MkMetadata !(traverse resolvedLHS lhs)
399 | !(traverse resolvedTy ns)
400 | !(traverse resolvedTy tys)
402 | !(traverse resolvedHLHS hlhs)
403 | (fromList !(traverse resolvedDecls (toList dlocs)))
409 | resolvedLHS : (NonEmptyFC, (Nat, ClosedTerm)) -> Core (NonEmptyFC, (Nat, ClosedTerm))
410 | resolvedLHS (fc, (i, tm)) = pure (fc, (i, !(resolved gam tm)))
412 | resolvedTy : (NonEmptyFC, (Name, Nat, ClosedTerm)) -> Core (NonEmptyFC, (Name, Nat, ClosedTerm))
413 | resolvedTy (fc, (n, i, tm)) = pure (fc, (!(resolved gam n), i, !(resolved gam tm)))
415 | resolvedHLHS : (Name, ClosedTerm) -> Core (Name, ClosedTerm)
416 | resolvedHLHS (n, tm) = pure (!(resolved gam n), !(resolved gam tm))
418 | resolvedDecls : (NonEmptyFC, Name) -> Core (NonEmptyFC, Name)
419 | resolvedDecls (fc, n) = pure (fc, !(resolved gam n))
422 | writeToTTM : {auto c : Ref Ctxt Defs} ->
423 | {auto m : Ref MD Metadata} ->
424 | (fname : String) ->
427 | = do normaliseTypes
431 | toBuf (MkTTMFile ttcVersion !(full (gamma defs) meta))
432 | Right ok <- coreLift $
writeToFile fname !(get Bin)
433 | | Left err => throw (InternalError (fname ++ ": " ++ show err))
437 | readFromTTM : {auto m : Ref MD Metadata} ->
438 | (fname : String) ->
441 | = do Right buf <- coreLift $
readFromFile fname
442 | | Left err => throw (InternalError (fname ++ ": " ++ show err))
443 | bin <- newRef Bin buf
445 | put MD (metadata ttm)
449 | readMetadata : (fname : String) -> Core Metadata
451 | = do Right buf <- coreLift $
readFromFile fname
452 | | Left err => throw (InternalError (fname ++ ": " ++ show err))
453 | bin <- newRef Bin buf
454 | MkTTMFile _ md <- fromBuf
459 | dumpTTM : (filename : String) -> Core ()
461 | = do md <- readMetadata fname
462 | coreLift $
putStrLn $
show md