Skip to content

transitively track and reify annotations across a codebase

License

Notifications You must be signed in to change notification settings

isovector/transitive-anns

Repository files navigation

transitive-anns

Overview

This package is a small compiler plugin that transitively propagates, and reifies, annotations. To get started, try attaching some annotations to some values:

{-# OPTIONS_GHC -fplugin=TransitiveAnns.Plugin #-}

import TransitiveAnns.Types

{-# ANN test3 (Annotation Remote "hello from" "test3") #-}
test3 :: Int
test3 = 4

{-# ANN test2 (Annotation Remote "hello from" "test2") #-}
test2 :: Int
test2 = test3

and then we can reify them:

test :: ([Annotation], Int)
test = withAnnotations test2

with result:

( [ Annotation Remote "hello from" "test3"
  , Annotation Remote "hello from" "test2"
  ]
, 4
)

Better yet, it works across module boundaries!

Nitty Gritty Details

Internally, this plugin consists of two parts: a CoreToDo plugin, and a typechecker plugin. The CoreToDo runs after the module has been compiled, looks up every function with an Annotation, and then also attaches it to any function which calls an annotated function. These get stuck in the ModIface, so they are cached in the compiled artifacts.

The other half of the plugin is a solver for the following class:

class KnownAnnotations where
  annotationsVal :: [Annotation]

which returns every annotation attached to the function calling annotationsVal. Of course, this dispatch plays nicely with the usual constraint system, so you can delay its evaluation by adding a KnownAnnotations => given constraint to your type signature.

About

transitively track and reify annotations across a codebase

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published