|
| 1 | +module Language.PureScript.Ide.ToIde where |
| 2 | + |
| 3 | +import Protolude hiding (moduleName, unzip) |
| 4 | + |
| 5 | +import Control.Concurrent.STM (TVar, modifyTVar, readTVar, readTVarIO, writeTVar) |
| 6 | +import Control.Lens (Ixed(..), preview, view, (%~), (.~), (^.)) |
| 7 | +import Data.IORef (readIORef, writeIORef) |
| 8 | +import Data.Map.Lazy qualified as Map |
| 9 | +import Data.Time.Clock (UTCTime) |
| 10 | +import Data.Zip (unzip) |
| 11 | +import Language.PureScript.Docs.Convert.Single (convertComments) |
| 12 | +import Language.PureScript.Externs (ExternsDeclaration(..), ExternsFile(..)) |
| 13 | +import Language.PureScript.Ide.Externs (convertExterns) |
| 14 | +import Language.PureScript.Ide.SourceFile (extractAstInformation) |
| 15 | +import Language.PureScript.Ide.Types |
| 16 | +import Language.PureScript.Ide.Util (discardAnn, displayTimeSpec, logPerf, opNameT, properNameT, runLogger) |
| 17 | +import System.Directory (getModificationTime) |
| 18 | +import Database.SQLite.Simple qualified as SQLite |
| 19 | +import Debug.Trace qualified as Debug |
| 20 | +import Language.PureScript.AST.Declarations (Module (..)) |
| 21 | +import Language.PureScript.AST.SourcePos qualified as P |
| 22 | +import Language.PureScript.Names qualified as P |
| 23 | +import Data.Text (Text) |
| 24 | +import Language.PureScript.AST.Declarations qualified as P |
| 25 | +import Language.PureScript.Comments qualified as P |
| 26 | +import Data.Maybe (Maybe) |
| 27 | + |
| 28 | +toIdeDeclarationAnn :: Module -> ExternsFile -> [IdeDeclarationAnn] |
| 29 | +toIdeDeclarationAnn m e = results |
| 30 | + where |
| 31 | + asts = extractAstInformation m |
| 32 | + (moduleDeclarations, reexportRefs) = convertExterns e |
| 33 | + results = |
| 34 | + moduleDeclarations |
| 35 | + -- & resolveDataConstructorsForModule |
| 36 | + & resolveLocationsForModule asts |
| 37 | + & resolveDocumentationForModule m |
| 38 | + -- & resolveInstances externs |
| 39 | + -- & resolveOperators |
| 40 | + -- & resolveReexports reexportRefs |
| 41 | + |
| 42 | + |
| 43 | +resolveLocationsForModule |
| 44 | + :: (DefinitionSites P.SourceSpan, TypeAnnotations) |
| 45 | + -> [IdeDeclarationAnn] |
| 46 | + -> [IdeDeclarationAnn] |
| 47 | +resolveLocationsForModule (defs, types) = |
| 48 | + map convertDeclaration |
| 49 | + where |
| 50 | + convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn |
| 51 | + convertDeclaration (IdeDeclarationAnn ann d) = convertDeclaration' |
| 52 | + annotateFunction |
| 53 | + annotateValue |
| 54 | + annotateDataConstructor |
| 55 | + annotateType |
| 56 | + annotateType -- type classes live in the type namespace |
| 57 | + annotateModule |
| 58 | + d |
| 59 | + where |
| 60 | + annotateFunction x = IdeDeclarationAnn (ann { _annLocation = Map.lookup (IdeNamespaced IdeNSValue (P.runIdent x)) defs |
| 61 | + , _annTypeAnnotation = Map.lookup x types |
| 62 | + }) |
| 63 | + annotateValue x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSValue x) defs}) |
| 64 | + annotateDataConstructor x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSValue x) defs}) |
| 65 | + annotateType x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSType x) defs}) |
| 66 | + annotateModule x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSModule x) defs}) |
| 67 | + |
| 68 | +convertDeclaration' |
| 69 | + :: (P.Ident -> IdeDeclaration -> IdeDeclarationAnn) |
| 70 | + -> (Text -> IdeDeclaration -> IdeDeclarationAnn) |
| 71 | + -> (Text -> IdeDeclaration -> IdeDeclarationAnn) |
| 72 | + -> (Text -> IdeDeclaration -> IdeDeclarationAnn) |
| 73 | + -> (Text -> IdeDeclaration -> IdeDeclarationAnn) |
| 74 | + -> (Text -> IdeDeclaration -> IdeDeclarationAnn) |
| 75 | + -> IdeDeclaration |
| 76 | + -> IdeDeclarationAnn |
| 77 | +convertDeclaration' annotateFunction annotateValue annotateDataConstructor annotateType annotateClass annotateModule d = |
| 78 | + case d of |
| 79 | + IdeDeclValue v -> |
| 80 | + annotateFunction (v ^. ideValueIdent) d |
| 81 | + IdeDeclType t -> |
| 82 | + annotateType (t ^. ideTypeName . properNameT) d |
| 83 | + IdeDeclTypeSynonym s -> |
| 84 | + annotateType (s ^. ideSynonymName . properNameT) d |
| 85 | + IdeDeclDataConstructor dtor -> |
| 86 | + annotateDataConstructor (dtor ^. ideDtorName . properNameT) d |
| 87 | + IdeDeclTypeClass tc -> |
| 88 | + annotateClass (tc ^. ideTCName . properNameT) d |
| 89 | + IdeDeclValueOperator operator -> |
| 90 | + annotateValue (operator ^. ideValueOpName . opNameT) d |
| 91 | + IdeDeclTypeOperator operator -> |
| 92 | + annotateType (operator ^. ideTypeOpName . opNameT) d |
| 93 | + IdeDeclModule mn -> |
| 94 | + annotateModule (P.runModuleName mn) d |
| 95 | + |
| 96 | +resolveDocumentationForModule |
| 97 | + :: Module |
| 98 | + -> [IdeDeclarationAnn] |
| 99 | + -> [IdeDeclarationAnn] |
| 100 | +resolveDocumentationForModule (Module _ moduleComments moduleName sdecls _) = |
| 101 | + map convertDecl |
| 102 | + where |
| 103 | + extractDeclComments :: P.Declaration -> [(P.Name, [P.Comment])] |
| 104 | + extractDeclComments = \case |
| 105 | + P.DataDeclaration (_, cs) _ ctorName _ ctors -> |
| 106 | + (P.TyName ctorName, cs) : map dtorComments ctors |
| 107 | + P.TypeClassDeclaration (_, cs) tyClassName _ _ _ members -> |
| 108 | + (P.TyClassName tyClassName, cs) : concatMap extractDeclComments members |
| 109 | + decl -> |
| 110 | + maybe [] (\name' -> [(name', snd (P.declSourceAnn decl))]) (name decl) |
| 111 | + |
| 112 | + comments :: Map.Map P.Name [P.Comment] |
| 113 | + comments = Map.insert (P.ModName moduleName) moduleComments $ |
| 114 | + Map.fromListWith (flip (<>)) $ concatMap extractDeclComments sdecls |
| 115 | + |
| 116 | + dtorComments :: P.DataConstructorDeclaration -> (P.Name, [P.Comment]) |
| 117 | + dtorComments dcd = (P.DctorName (P.dataCtorName dcd), snd (P.dataCtorAnn dcd)) |
| 118 | + |
| 119 | + name :: P.Declaration -> Maybe P.Name |
| 120 | + name (P.TypeDeclaration d) = Just $ P.IdentName $ P.tydeclIdent d |
| 121 | + name decl = P.declName decl |
| 122 | + |
| 123 | + convertDecl :: IdeDeclarationAnn -> IdeDeclarationAnn |
| 124 | + convertDecl (IdeDeclarationAnn ann d) = |
| 125 | + convertDeclaration' |
| 126 | + (annotateValue . P.IdentName) |
| 127 | + (annotateValue . P.IdentName . P.Ident) |
| 128 | + (annotateValue . P.DctorName . P.ProperName) |
| 129 | + (annotateValue . P.TyName . P.ProperName) |
| 130 | + (annotateValue . P.TyClassName . P.ProperName) |
| 131 | + (annotateValue . P.ModName . P.moduleNameFromString) |
| 132 | + d |
| 133 | + where |
| 134 | + docs :: P.Name -> Text |
| 135 | + docs ident = fromMaybe "" $ convertComments =<< Map.lookup ident comments |
| 136 | + |
| 137 | + annotateValue ident = IdeDeclarationAnn (ann { _annDocumentation = Just $ docs ident }) |
| 138 | + |
| 139 | +-- resolveDataConstructorsForModule |
| 140 | +-- :: [IdeDeclarationAnn] |
| 141 | +-- -> [IdeDeclarationAnn] |
| 142 | +-- resolveDataConstructorsForModule decls = |
| 143 | +-- map (idaDeclaration %~ resolveDataConstructors) decls |
| 144 | +-- where |
| 145 | +-- resolveDataConstructors :: IdeDeclaration -> IdeDeclaration |
| 146 | +-- resolveDataConstructors decl = case decl of |
| 147 | +-- IdeDeclType ty -> |
| 148 | +-- IdeDeclType (ty & ideTypeDtors .~ fromMaybe [] (Map.lookup (ty ^. ideTypeName) dtors)) |
| 149 | +-- _ -> |
| 150 | +-- decl |
| 151 | +-- |
| 152 | +-- dtors = |
| 153 | +-- decls |
| 154 | +-- & Map.mapMaybe (preview (idaDeclaration . _IdeDeclDataConstructor)) |
| 155 | +-- & foldr (\(IdeDataConstructor name typeName type') -> |
| 156 | +-- Map.insertWith (<>) typeName [(name, type')]) Map.empty |
0 commit comments