@@ -69,6 +69,7 @@ import qualified Data.Set as Set
6969import Data.Text (Text )
7070import Data.Traversable (for )
7171import Data.Typeable (cast )
72+ import Debug.Trace (trace )
7273import Development.IDE (IdeAction , IdeState ,
7374 Priority (.. ), ideLogger ,
7475 logPriority , use , uses )
@@ -83,80 +84,15 @@ import Development.IDE.Types.Exports (ExportsMap (..),
8384import Development.IDE.Types.HscEnvEq (hscEnv )
8485import GHC.Conc (readTVar )
8586
86- -- logWith :: (MonadIO m) => IdeState -> String -> m ()
87- -- logWith st = liftIO . logPriority (ideLogger st) Info . T.pack . show
88-
8987logWith :: (MonadIO m ) => IdeState -> String -> m ()
90- logWith st = liftIO . print
91-
92- bytestringString :: ByteString -> String
93- bytestringString = map (toEnum . fromEnum ) . unpack
94-
95- -- data TyThing
96- -- = AnId Id
97- -- | AConLike ConLike
98- -- | ATyCon TyCon -- TyCons and classes; see Note [ATyCon for classes]
99- -- | ACoAxiom (CoAxiom Branched)
100- -- a :: IdDetails
101- -- a = undefined
102-
103- -- | Identifier Details
104- --
105- -- The 'IdDetails' of an 'Id' give stable, and necessary,
106- -- information about the Id.
107- -- data IdDetails
108- -- = VanillaId
88+ logWith st = liftIO . logPriority (ideLogger st) Info . T. pack
10989
110- -- -- | The 'Id' for a record selector
111- -- | RecSelId
112- -- { sel_tycon :: RecSelParent
113- -- , sel_naughty :: Bool -- True <=> a "naughty" selector which can't actually exist, for example @x@ in:
114- -- -- data T = forall a. MkT { x :: a }
115- -- } -- See Note [Naughty record selectors] in GHC.Tc.TyCl
11690
117- -- | DataConWorkId DataCon -- ^ The 'Id' is for a data constructor /worker/
118- -- | DataConWrapId DataCon -- ^ The 'Id' is for a data constructor /wrapper/
119-
120- -- -- [the only reasons we need to know is so that
121- -- -- a) to support isImplicitId
122- -- -- b) when desugaring a RecordCon we can get
123- -- -- from the Id back to the data con]
124- -- | ClassOpId Class -- ^ The 'Id' is a superclass selector,
125- -- -- or class operation of a class
126-
127- -- | PrimOpId PrimOp Bool -- ^ The 'Id' is for a primitive operator
128- -- -- True <=> is representation-polymorphic,
129- -- -- and hence has no binding
130- -- -- This lev-poly flag is used only in GHC.Types.Id.hasNoBinding
131-
132- -- | FCallId ForeignCall -- ^ The 'Id' is for a foreign call.
133- -- -- Type will be simple: no type families, newtypes, etc
134-
135- -- | TickBoxOpId TickBoxOp -- ^ The 'Id' is for a HPC tick box (both traditional and binary)
136-
137- -- | DFunId Bool -- ^ A dictionary function.
138- -- -- Bool = True <=> the class has only one method, so may be
139- -- -- implemented with a newtype, so it might be bad
140- -- -- to be strict on this dictionary
91+ -- logWith :: (MonadIO m) => IdeState -> String -> m ()
92+ -- logWith st = liftIO . print
14193
142- -- | CoVarId -- ^ A coercion variable
143- -- -- This only covers /un-lifted/ coercions, of type
144- -- -- (t1 ~# t2) or (t1 ~R# t2), not their lifted variants
145- -- | JoinId JoinArity (Maybe [CbvMark])
146- -- -- ^ An 'Id' for a join point taking n arguments
147- -- -- Note [Join points] in "GHC.Core"
148- -- -- Can also work as a WorkerLikeId if given `CbvMark`s.
149- -- -- See Note [CBV Function Ids]
150- -- -- The [CbvMark] is always empty (and ignored) until after Tidy.
151- -- | WorkerLikeId [CbvMark]
152- -- -- ^ An 'Id' for a worker like function, which might expect some arguments to be
153- -- -- passed both evaluated and tagged.
154- -- -- Worker like functions are create by W/W and SpecConstr and we can expect that they
155- -- -- aren't used unapplied.
156- -- -- See Note [CBV Function Ids]
157- -- -- See Note [Tag Inference]
158- -- -- The [CbvMark] is always empty (and ignored) until after Tidy for ids from the current
159- -- -- module.
94+ bytestringString :: ByteString -> String
95+ bytestringString = map (toEnum . fromEnum ) . unpack
16096
16197tyThingSemantic :: TyThing -> SemanticTokenType
16298tyThingSemantic ty = case ty of
@@ -171,11 +107,11 @@ tyThingSemantic ty = case ty of
171107 RealDataCon _ -> TDataCon
172108 PatSynCon _ -> TPatternSyn
173109 ATyCon tyCon
174- | isDataTyCon tyCon -> TTypeCon
175- | isPrimTyCon tyCon -> TTypeCon
176- | isClassTyCon tyCon -> TClass
177110 | isTypeSynonymTyCon tyCon -> TTypeSyn
178111 | isTypeFamilyTyCon tyCon -> TTypeFamily
112+ | isClassTyCon tyCon -> TClass
113+ | isDataTyCon tyCon -> TTypeCon
114+ | isPrimTyCon tyCon -> TTypeCon
179115 | otherwise -> TNothing
180116 ACoAxiom _ -> TNothing
181117
@@ -185,48 +121,40 @@ tyThingSemantic ty = case ty of
185121
186122computeSemanticTokens :: IdeState -> NormalizedFilePath -> Action (Maybe SemanticTokens )
187123computeSemanticTokens state nfp =
188- let dbg = logWith state in
189- runMaybeT $ do
190- -- HAR{hieAst, refMap} <- MaybeT $ use GetHieAst nfp
191- [HAR {.. }] <- usesMT GetHieAst [nfp]
192- -- [TcModuleResult{..}]<- usesMT TypeCheck [nfp]
193- [hscEnv -> hsc] <- usesMT (GhcSessionDeps_ True ) [nfp]
194- -- HAR{..} <- MaybeT $ useWithStaleFastMT GetHieAst nfp
195- liftIO $ putStrLn $ " moduleName: " <> showSDocUnsafe (ppr hieModule)
196- let xs = Map. toList $ getAsts hieAst
197- liftIO $ putStrLn $ " hieAst size: " <> show (List. length xs)
198-
199- case xs of
200- ((_,ast): _) -> do
201- -- compute imported names from hieAst
202- let importedNames = importedNameFromModule hieModule ast
203- -- accumulate names from typechecked module
204- -- km <- liftIO $ foldrM (getType hsc) (tcg_type_env tmrTypechecked) importedNames
205- km <- liftIO $ foldrM (getType hsc) emptyNameEnv importedNames
206- let importedModuleNameSemanticMap = Map. fromList $ flip mapMaybe (Set. toList importedNames) $ \ name -> do
207- ty <- lookupNameEnv km name
208- return (name, tyThingSemantic ty)
209- liftIO $ forM (Set. toList importedNames) $ \ name -> do
210- let ty = lookupNameEnv km name
211- dbg $ " imported name: "
212- <> showSDocUnsafe (ppr name)
213- <> " :: " <> showSDocUnsafe (ppr ty)
214- -- return (name, tyThingSemantic ty)
215- ShakeExtras {.. } <- MaybeT $ fmap Just getShakeExtras
216- let originalModuleNameSemanticMap = toNameSemanticMap refMap
217- let combineMap = Map. unionWith (<>) originalModuleNameSemanticMap importedModuleNameSemanticMap
218- let names = identifierGetter ast
219-
124+ runMaybeT $ do
125+ -- let dbg = logWith state
126+ -- let getAst HAR{hieAst, refMap} = hieAst
127+ (HAR {hieAst, refMap, hieModule}, _) <- useWithStaleMT GetHieAst nfp
128+ (_, ast) <- MaybeT $ return $ listToMaybe $ Map. toList $ getAsts hieAst
129+ (TcModuleResult {.. }, _) <- useWithStaleMT TypeCheck nfp
130+ (hscEnv -> hsc, _) <- useWithStaleMT GhcSessionDeps nfp
131+ -- because the names get from ast might contain derived name
132+ let nameSet = nameGetter tmrRenamed
133+ -- let nameSet = hieAstNameSet ast
134+ let names = hieAstSpanNames ast
135+
136+ -- ask hscEnv for none local types
137+ km <- liftIO $ foldrM (getType hsc) (tcg_type_env tmrTypechecked) nameSet
138+ -- name from type typecheck
139+ let importedModuleNameSemanticMap = Map. fromList $ flip mapMaybe (Set. toList nameSet) $ \ name -> do
140+ ty <- lookupNameEnv km name
141+ return (name, tyThingSemantic ty)
142+ let localNameSemanticMap = toNameSemanticMap $ Map. filterWithKey (\ k _ ->
143+ either (const False ) (flip Set. member nameSet) k) refMap
144+ let combineMap = Map. unionWith (<>) localNameSemanticMap importedModuleNameSemanticMap
145+ -- print all names
146+ -- deriving method locate in the same position as the class name
147+ -- liftIO $ mapM_ (\ (name, tokenType) -> dbg ("debug semanticMap: " <> showClearName name <> ":" <> show tokenType )) $ Map.toList importedModuleNameSemanticMap
148+ -- liftIO $ mapM_ (\ (span, name) -> dbg ("debug names: " <> showClearName name <> ":" <> printCompactRealSrc span ) ) names
149+ let moduleAbsTks = extractSemanticTokensFromNames combineMap names
150+ case semanticTokenAbsoluteSemanticTokens moduleAbsTks of
151+ Right tokens -> do
220152 source :: ByteString <- lift $ getSourceFileSource nfp
221- let moduleAbsTks = extractSemanticTokensFromNames combineMap names
222- case semanticTokenAbsoluteSemanticTokens moduleAbsTks of
223- Right tokens -> do
224- liftIO $ mapM_ (\ x -> mapM_ (dbg . show ) x) $ recoverSemanticTokens (bytestringString source) tokens
225- pure tokens
226- Left err -> do
227- liftIO $ putStrLn $ " computeSemanticTokens: " <> show err
228- MaybeT . pure $ Nothing
229- _ -> MaybeT . pure $ Nothing
153+ -- liftIO $ mapM_ (\x -> mapM_ (dbg . show) x) $ recoverSemanticTokens (bytestringString source) tokens
154+ pure tokens
155+ Left err -> do
156+ liftIO $ putStrLn $ " computeSemanticTokens: " <> show err
157+ MaybeT . pure $ Nothing
230158 where
231159 getType env n nameMap
232160 | Nothing <- lookupNameEnv nameMap n
@@ -239,9 +167,9 @@ computeSemanticTokens state nfp =
239167
240168semanticTokensFull :: PluginMethodHandler IdeState 'Method_TextDocumentSemanticTokensFull
241169semanticTokensFull state _ param = do
242- let dbg = logWith state
170+ -- let dbg = logWith state
243171 nfp <- getNormalizedFilePathE (param ^. (L. textDocument . L. uri))
244- dbg $ " semanticTokensFull: " <> show nfp
172+ -- dbg $ "semanticTokensFull: " <> show nfp
245173 -- source :: ByteString <- lift $ getSourceFileSource nfp
246174 items <- liftIO
247175 $ runAction " SemanticTokens.semanticTokensFull" state
@@ -258,32 +186,25 @@ semanticTokensFull state _ param = do
258186---- recover tokens
259187-----------------------
260188
189+ -- | recoverSemanticTokens
190+ -- used for debug and test
191+ -- this function is used to recover the original tokens(with token in haskell token type zoon)
192+ -- from the lsp semantic tokens(with token in lsp token type zoon)
261193recoverSemanticTokens :: String -> SemanticTokens -> Either Text [SemanticTokenOriginal ]
262194recoverSemanticTokens sourceCode (SemanticTokens _ xs) = fmap (fmap $ tokenOrigin sourceCode) $ dataActualToken xs
263-
264-
265- tokenOrigin :: [Char ] -> ActualToken -> SemanticTokenOriginal
266- tokenOrigin sourceCode (line, startChar, len, tokenType, _) =
267- -- convert back to count from 1
268- SemanticTokenOriginal tokenType (Loc (line+ 1 ) (startChar+ 1 ) len) name
269- where tLine = lines sourceCode !? fromIntegral line
270- name = maybe " no source" (take (fromIntegral len) . drop (fromIntegral startChar)) tLine
271-
272-
273- dataActualToken :: [UInt ] -> Either Text [ActualToken ]
274- dataActualToken xs = maybe decodeError (Right . fmap semanticTokenAbsoluteActualToken . absolutizeTokens)
275- $ mapM fromTuple (chunksOf 5 $ map fromIntegral xs)
276195 where
277- decodeError = Left " recoverSemanticTokenRelative: wrong token data"
278- fromTuple [a, b, c, d, _] = Just $ SemanticTokenRelative a b c (fromInt $ fromIntegral d) []
279- fromTuple _ = Nothing
280-
281- -- span: /Users/ares/src/test/lib/SemanticTokens/Types.hs:(34,12)-(38,3)
282- -- type RefMap a = M.Map Identifier [(Span, IdentifierDetails a)]
283- computeImportedSemanticTokens :: IdeState -> [NormalizedFilePath ] -> Set. Set Name -> MaybeT Action NameSemanticMap
284- computeImportedSemanticTokens state nfps names =
285- let dbg = logWith state in do
286- dbg " heelo"
287- let nameList = Set. toList names
288- let moduleNamePairs = [(1 , nameOccName name) | name <- nameList]
289- return Map. empty
196+ tokenOrigin :: [Char ] -> ActualToken -> SemanticTokenOriginal
197+ tokenOrigin sourceCode (line, startChar, len, tokenType, _) =
198+ -- convert back to count from 1
199+ SemanticTokenOriginal tokenType (Loc (line+ 1 ) (startChar+ 1 ) len) name
200+ where tLine = lines sourceCode !? fromIntegral line
201+ name = maybe " no source" (take (fromIntegral len) . drop (fromIntegral startChar)) tLine
202+
203+
204+ dataActualToken :: [UInt ] -> Either Text [ActualToken ]
205+ dataActualToken xs = maybe decodeError (Right . fmap semanticTokenAbsoluteActualToken . absolutizeTokens)
206+ $ mapM fromTuple (chunksOf 5 $ map fromIntegral xs)
207+ where
208+ decodeError = Left " recoverSemanticTokenRelative: wrong token data"
209+ fromTuple [a, b, c, d, _] = Just $ SemanticTokenRelative a b c (fromInt $ fromIntegral d) []
210+ fromTuple _ = Nothing
0 commit comments