packages feed

ghcide 2.9.0.1 → 2.10.0.0

raw patch · 145 files changed

+2103/−2391 lines, 145 filesdep +lens-aesondep +os-stringdep ~basedep ~hls-graphdep ~hls-plugin-apiPVP ok

version bump matches the API change (PVP)

Dependencies added: lens-aeson, os-string

Dependency ranges changed: base, hls-graph, hls-plugin-api

API changes (from Hackage documentation)

- Development.IDE: GHC92 :: GhcVersion
- Development.IDE: hscEnvWithImportPaths :: HscEnvEq -> HscEnv
- Development.IDE: type FileDiagnostic = (NormalizedFilePath, ShowDiagnostic, Diagnostic)
- Development.IDE.Core.Compile: newtype TypecheckHelpers
- Development.IDE.Core.ProgressReporting: KickCompleted :: ProgressEvent
- Development.IDE.Core.ProgressReporting: KickStarted :: ProgressEvent
- Development.IDE.Core.ProgressReporting: ProgressReporting :: (ProgressEvent -> IO ()) -> (forall a. NormalizedFilePath -> Action a -> Action a) -> IO () -> ProgressReporting
- Development.IDE.Core.ProgressReporting: [progressStop] :: ProgressReporting -> IO ()
- Development.IDE.Core.ProgressReporting: [progressUpdate] :: ProgressReporting -> ProgressEvent -> IO ()
- Development.IDE.Core.ProgressReporting: noProgressReporting :: IO ProgressReporting
- Development.IDE.Core.Shake: KickCompleted :: ProgressEvent
- Development.IDE.Core.Shake: KickStarted :: ProgressEvent
- Development.IDE.Core.Shake: [$sel:indexProgressToken:HieDbWriter] :: HieDbWriter -> Var (Maybe ProgressToken)
- Development.IDE.GHC.Compat: GHC92 :: GhcVersion
- Development.IDE.GHC.Compat.Parser: hpm_annotations :: HsParsedModule -> ApiAnns
- Development.IDE.GHC.Compat.Parser: mkApiAnns :: PState -> ApiAnns
- Development.IDE.GHC.Compat.Parser: pm_annotations :: ParsedModule -> ApiAnns
- Development.IDE.GHC.Compat.Parser: type ApiAnns = ()
- Development.IDE.GHC.Compat.Plugins: initPlugins :: HscEnv -> ModSummary -> IO (ModSummary, HscEnv)
- Development.IDE.GHC.Compat.Plugins: initializePlugins :: HscEnv -> IO HscEnv
- Development.IDE.GHC.Compat.Units: oldInitUnits :: DynFlags -> IO DynFlags
- Development.IDE.Main: LogSetInitialDynFlagsException :: !SomeException -> Log
- Development.IDE.Session: setInitialDynFlags :: Recorder (WithPriority Log) -> FilePath -> SessionLoadingOptions -> IO (Maybe LibDir)
- Development.IDE.Types.Diagnostics: type FileDiagnostic = (NormalizedFilePath, ShowDiagnostic, Diagnostic)
- Development.IDE.Types.HscEnvEq: deps :: HscEnvEq -> [(UnitId, DynFlags)]
- Development.IDE.Types.HscEnvEq: envImportPaths :: HscEnvEq -> Maybe (Set FilePath)
- Development.IDE.Types.HscEnvEq: hscEnvWithImportPaths :: HscEnvEq -> HscEnv
- Development.IDE.Types.HscEnvEq: newHscEnvEqPreserveImportPaths :: HscEnv -> [(UnitId, DynFlags)] -> IO HscEnvEq
- Development.IDE.Types.HscEnvEq: newHscEnvEqWithImportPaths :: Maybe (Set FilePath) -> HscEnv -> [(UnitId, DynFlags)] -> IO HscEnvEq
- Development.IDE.Types.Shake: instance Control.DeepSeq.NFData (Development.IDE.Types.Shake.A v)
+ Development.IDE: FileDiagnostic :: NormalizedFilePath -> ShowDiagnostic -> Diagnostic -> StructuredMessage -> FileDiagnostic
+ Development.IDE: GHC912 :: GhcVersion
+ Development.IDE: GetFileHash :: GetFileHash
+ Development.IDE: NoStructuredMessage :: StructuredMessage
+ Development.IDE: SomeStructuredMessage :: MsgEnvelope GhcMessage -> StructuredMessage
+ Development.IDE: [fdFilePath] :: FileDiagnostic -> NormalizedFilePath
+ Development.IDE: [fdLspDiagnostic] :: FileDiagnostic -> Diagnostic
+ Development.IDE: [fdShouldShowDiagnostic] :: FileDiagnostic -> ShowDiagnostic
+ Development.IDE: [fdStructuredMessage] :: FileDiagnostic -> StructuredMessage
+ Development.IDE: [tmrWarnings] :: TcModuleResult -> WarningMessages
+ Development.IDE: _NoStructuredMessage :: Prism' StructuredMessage ()
+ Development.IDE: _SomeStructuredMessage :: Prism' StructuredMessage (MsgEnvelope GhcMessage)
+ Development.IDE: attachReason :: Maybe DiagnosticReason -> Diagnostic -> Diagnostic
+ Development.IDE: attachedReason :: Traversal' Diagnostic (Maybe Value)
+ Development.IDE: data FileDiagnostic
+ Development.IDE: data GetFileHash
+ Development.IDE: data StructuredMessage
+ Development.IDE: diagFromGhcErrorMessages :: Text -> DynFlags -> Bag (MsgEnvelope GhcMessage) -> [FileDiagnostic]
+ Development.IDE: diagFromSDocErrMsg :: Text -> DynFlags -> MsgEnvelope DecoratedSDoc -> [FileDiagnostic]
+ Development.IDE: diagFromSDocErrMsgs :: Text -> DynFlags -> Bag (MsgEnvelope DecoratedSDoc) -> [FileDiagnostic]
+ Development.IDE: fdFilePathL :: Lens' FileDiagnostic NormalizedFilePath
+ Development.IDE: fdLspDiagnosticL :: Lens' FileDiagnostic Diagnostic
+ Development.IDE: fdShouldShowDiagnosticL :: Lens' FileDiagnostic ShowDiagnostic
+ Development.IDE: fdStructuredMessageL :: Lens' FileDiagnostic StructuredMessage
+ Development.IDE: getFileModTimeContents :: NormalizedFilePath -> Action (UTCTime, Maybe Rope)
+ Development.IDE: getUriContents :: NormalizedUri -> Action (Maybe Rope)
+ Development.IDE: ideErrorFromLspDiag :: Diagnostic -> NormalizedFilePath -> Maybe (MsgEnvelope GhcMessage) -> FileDiagnostic
+ Development.IDE: showGhcCode :: DiagnosticCode -> Text
+ Development.IDE.Core.Actions: getImplementationDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
+ Development.IDE.Core.Compile: [getModuleGraph] :: TypecheckHelpers -> IO DependencyInformation
+ Development.IDE.Core.Compile: [get_module_graph] :: RecompilationInfo m -> m DependencyInformation
+ Development.IDE.Core.Compile: [tmrWarnings] :: TcModuleResult -> WarningMessages
+ Development.IDE.Core.Compile: data TypecheckHelpers
+ Development.IDE.Core.Compile: setNonHomeFCHook :: HscEnv -> HscEnv
+ Development.IDE.Core.FileStore: getFileModTimeContents :: NormalizedFilePath -> Action (UTCTime, Maybe Rope)
+ Development.IDE.Core.FileStore: getUriContents :: NormalizedUri -> Action (Maybe Rope)
+ Development.IDE.Core.FileStore: getVersionedTextDoc :: TextDocumentIdentifier -> Action VersionedTextDocumentIdentifier
+ Development.IDE.Core.PluginUtils: activeDiagnosticsInRange :: MonadIO m => ShakeExtras -> NormalizedFilePath -> Range -> m (Maybe [FileDiagnostic])
+ Development.IDE.Core.PluginUtils: activeDiagnosticsInRangeMT :: MonadIO m => ShakeExtras -> NormalizedFilePath -> Range -> MaybeT m [FileDiagnostic]
+ Development.IDE.Core.PluginUtils: mkFormattingHandlers :: FormattingHandler IdeState -> PluginHandlers IdeState
+ Development.IDE.Core.ProgressReporting: PerFileProgressReporting :: (forall a. NormalizedFilePath -> IO a -> IO a) -> ProgressReporting -> PerFileProgressReporting
+ Development.IDE.Core.ProgressReporting: ProgressCompleted :: ProgressEvent
+ Development.IDE.Core.ProgressReporting: ProgressNewStarted :: ProgressEvent
+ Development.IDE.Core.ProgressReporting: ProgressStarted :: ProgressEvent
+ Development.IDE.Core.ProgressReporting: [progressReportingInner] :: PerFileProgressReporting -> ProgressReporting
+ Development.IDE.Core.ProgressReporting: data PerFileProgressReporting
+ Development.IDE.Core.ProgressReporting: instance Development.IDE.Core.ProgressReporting.ProgressReporter Development.IDE.Core.ProgressReporting.PerFileProgressReporting
+ Development.IDE.Core.ProgressReporting: instance Development.IDE.Core.ProgressReporting.ProgressReporter Development.IDE.Core.ProgressReporting.ProgressReporting
+ Development.IDE.Core.ProgressReporting: noPerFileProgressReporting :: IO PerFileProgressReporting
+ Development.IDE.Core.ProgressReporting: progressReportingNoTrace :: STM Int -> STM Int -> Maybe (LanguageContextEnv c) -> Text -> ProgressReportingStyle -> IO ProgressReporting
+ Development.IDE.Core.ProgressReporting: progressStop :: ProgressReporter a => a -> IO ()
+ Development.IDE.Core.ProgressReporting: progressUpdate :: ProgressReporter a => a -> ProgressEvent -> IO ()
+ Development.IDE.Core.RuleTypes: GetFileHash :: GetFileHash
+ Development.IDE.Core.RuleTypes: [tmrWarnings] :: TcModuleResult -> WarningMessages
+ Development.IDE.Core.RuleTypes: data GetFileHash
+ Development.IDE.Core.RuleTypes: instance Control.DeepSeq.NFData Development.IDE.Core.RuleTypes.GetFileHash
+ Development.IDE.Core.RuleTypes: instance Data.Hashable.Class.Hashable Development.IDE.Core.RuleTypes.GetFileHash
+ Development.IDE.Core.RuleTypes: instance GHC.Classes.Eq Development.IDE.Core.RuleTypes.GetFileHash
+ Development.IDE.Core.RuleTypes: instance GHC.Generics.Generic Development.IDE.Core.RuleTypes.GetFileHash
+ Development.IDE.Core.RuleTypes: instance GHC.Show.Show Development.IDE.Core.RuleTypes.GetFileHash
+ Development.IDE.Core.Shake: ProgressCompleted :: ProgressEvent
+ Development.IDE.Core.Shake: ProgressNewStarted :: ProgressEvent
+ Development.IDE.Core.Shake: ProgressStarted :: ProgressEvent
+ Development.IDE.Core.Shake: [$sel:indexProgressReporting:HieDbWriter] :: HieDbWriter -> ProgressReporting
+ Development.IDE.Core.Shake: runWithSignal :: (KnownSymbol s0, KnownSymbol s1, IdeRule k v) => Proxy s0 -> Proxy s1 -> [NormalizedFilePath] -> k -> Action ()
+ Development.IDE.GHC.Compat: GHC912 :: GhcVersion
+ Development.IDE.GHC.Compat.Driver: hscTypecheckRenameWithDiagnostics :: HscEnv -> ModSummary -> HsParsedModule -> IO ((TcGblEnv, RenamedStuff), Messages GhcMessage)
+ Development.IDE.GHC.Compat.Error: -- | Type of configuration options for the diagnostic.
+ Development.IDE.GHC.Compat.Error: DsAggregatedViewExpressions :: [[LHsExpr GhcTc]] -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsAnotherRuleMightFireFirst :: !RuleName -> !RuleName -> !Var -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsCannotMixPolyAndUnliftedBindings :: !HsBindLR GhcTc GhcTc -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsEmptyEnumeration :: DsMessage
+ Development.IDE.GHC.Compat.Error: DsIdentitiesFound :: !Id -> !Type -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsInaccessibleRhs :: !HsMatchContext GhcRn -> !SDoc -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsLazyPatCantBindVarsOfUnliftedType :: [Var] -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsMaxPmCheckModelsReached :: !MaxPmCheckModels -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsMultiplicityCoercionsNotSupported :: DsMessage
+ Development.IDE.GHC.Compat.Error: DsNonExhaustivePatterns :: !HsMatchContext GhcRn -> !ExhaustivityCheckType -> !MaxUncoveredPatterns -> [Id] -> [Nabla] -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsNotYetHandledByTH :: !ThRejectionReason -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsOrphanRule :: !CoreRule -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsOverflowedLiterals :: !Integer -> !Name -> !Maybe (MinBound, MaxBound) -> !NegLiteralExtEnabled -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsOverlappingPatterns :: !HsMatchContext GhcRn -> !SDoc -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsRecBindsNotAllowedForUnliftedTys :: ![LHsBindLR GhcTc GhcTc] -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsRedundantBangPatterns :: !HsMatchContext GhcRn -> !SDoc -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsRuleBindersNotBound :: ![Var] -> ![Var] -> !CoreExpr -> !CoreExpr -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsRuleIgnoredDueToConstructor :: !DataCon -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsRuleLhsTooComplicated :: !CoreExpr -> !CoreExpr -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsRuleMightInlineFirst :: !RuleName -> !Var -> !Activation -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsTopLevelBindsNotAllowed :: !BindsType -> !HsBindLR GhcTc GhcTc -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsUnbangedStrictPatterns :: !HsBindLR GhcTc GhcTc -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsUnknownMessage :: UnknownDiagnostic -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsUnusedDoBind :: !LHsExpr GhcTc -> !Type -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsUselessSpecialiseForClassMethodSelector :: !Id -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsUselessSpecialiseForNoInlineFunction :: !Id -> DsMessage
+ Development.IDE.GHC.Compat.Error: DsWrongDoBind :: !LHsExpr GhcTc -> !Type -> DsMessage
+ Development.IDE.GHC.Compat.Error: MsgEnvelope :: SrcSpan -> NamePprCtx -> e -> Severity -> MsgEnvelope e
+ Development.IDE.GHC.Compat.Error: PsHeaderMessage :: !PsHeaderMessage -> PsMessage
+ Development.IDE.GHC.Compat.Error: TcRnMessageDetailed :: !ErrInfo -> !TcRnMessage -> TcRnMessageDetailed
+ Development.IDE.GHC.Compat.Error: [DriverBackpackModuleNotFound] :: !ModuleName -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverCannotImportFromUntrustedPackage] :: !UnitState -> !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverCannotImportUnsafeModule] :: !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverCannotLoadInterfaceFile] :: !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverDuplicatedModuleDeclaration] :: !Module -> [FilePath] -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverFileModuleNameMismatch] :: !ModuleName -> !ModuleName -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverFileNotFound] :: !FilePath -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverHomePackagesNotClosed] :: ![UnitId] -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverInferredSafeImport] :: !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverInferredSafeModule] :: !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverMarkedTrustworthyButInferredSafe] :: !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverMissingHomeModules] :: UnitId -> [ModuleName] -> !BuildingCabalPackage -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverMissingSafeHaskellMode] :: !Module -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverMixedSafetyImport] :: !ModuleName -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverModuleNotFound] :: !ModuleName -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverPackageNotTrusted] :: !UnitState -> !UnitId -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverPsHeaderMessage] :: !PsMessage -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverRedirectedNoMain] :: !ModuleName -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverStaticPointersNotSupported] :: DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUnexpectedSignature] :: !ModuleName -> !BuildingCabalPackage -> GenInstantiations UnitId -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUnknownHiddenModules] :: UnitId -> [ModuleName] -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUnknownMessage] :: UnknownDiagnostic -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUnknownReexportedModules] :: UnitId -> [ModuleName] -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUnnecessarySourceImports] :: !ModuleName -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUnusedPackages] :: [(UnitId, PackageName, Version, PackageArg)] -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [DriverUserDefinedRuleIgnored] :: !RuleDecl GhcTc -> DriverMessage
+ Development.IDE.GHC.Compat.Error: [GhcDriverMessage] :: DriverMessage -> GhcMessage
+ Development.IDE.GHC.Compat.Error: [GhcDsMessage] :: DsMessage -> GhcMessage
+ Development.IDE.GHC.Compat.Error: [GhcPsMessage] :: PsMessage -> GhcMessage
+ Development.IDE.GHC.Compat.Error: [GhcTcRnMessage] :: TcRnMessage -> GhcMessage
+ Development.IDE.GHC.Compat.Error: [GhcUnknownMessage] :: UnknownDiagnostic -> GhcMessage
+ Development.IDE.GHC.Compat.Error: [TcRnAbstractClassInst] :: !Class -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnAddDocToNonLocalDefn] :: !DocLoc -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnAddInvalidCorePlugin] :: !String -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnAmbiguousField] :: HsExpr GhcRn -> TyCon -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnAnnotationInSafeHaskell] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnArrowIfThenElsePredDependsOnResultTy] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnArrowProcGADTPattern] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadAssociatedType] :: !Name -> !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadBootFamInstDecl] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadDefaultType] :: Type -> [Class] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadFamInstDecl] :: TyCon -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadGenericMethod] :: !Name -> !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadMethodErr] :: !Name -> !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadOverloadedRecordUpdate] :: [LHsRecUpdField GhcRn] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBadQuantPredHead] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnBangOnUnliftedType] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotBindScopedTyVarInPatSig] :: !NonEmpty (Name, TcTyVar) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotBindTyVarsInPatBind] :: !NonEmpty (Name, TcTyVar) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotDefaultConcrete] :: !FixedRuntimeRepOrigin -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotDeriveInstance] :: !Class -> [Type] -> !Maybe (DerivStrategy GhcTc) -> !UsingGeneralizedNewtypeDeriving -> !DeriveInstanceErrReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotReifyInstance] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotReifyOutOfScopeThing] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotReifyThingNotInTypeEnv] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCannotRepresentType] :: !UnrepresentableTypeDescr -> !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnCharLiteralOutOfRange] :: !Char -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnClassKindNotConstraint] :: !Kind -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnConflictingExports] :: OccName -> GreName -> GlobalRdrElt -> IE GhcPs -> GreName -> GlobalRdrElt -> IE GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnConflictingFamInstDecls] :: NonEmpty FamInst -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnConstraintInKind] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDefaultMethodForPragmaLacksBinding] :: Id -> Sig GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDerivingDefaults] :: !Class -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDifferentNamesForTyVar] :: !Name -> !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDodgyExports] :: Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDodgyImports] :: RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDupInstanceDecls] :: !UnitState -> NonEmpty ClsInst -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDupeModuleExport] :: ModuleName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDuplicateExport] :: GreName -> IE GhcPs -> IE GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDuplicateFieldName] :: !RecordFieldPart -> NonEmpty RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnDuplicateWarningDecls] :: !LocatedN RdrName -> !RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnEmptyRecordUpdate] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnEmptyStmtsGroup] :: EmptyStatementGroupErrReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnExpectedValueId] :: !TcTyThing -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnExportHiddenComponents] :: IE GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnExportedModNotImported] :: ModuleName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnExportedParentChildMismatch] :: Name -> TyThing -> GreName -> [Name] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnFailedToLookupThInstName] :: !Type -> !LookupTHInstNameErrReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnFamInstNotInjective] :: InjectivityErrReason -> TyCon -> NonEmpty CoAxBranch -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnFieldUpdateInvalidType] :: [(FieldLabelString, TcType)] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnForAllEscapeError] :: !Type -> !Kind -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnForAllRankErr] :: !Rank -> !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnForallIdentifier] :: RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnForeignFunctionImportAsValue] :: ForeignImport GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnForeignImportPrimExtNotSet] :: ForeignImport GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnForeignImportPrimSafeAnn] :: ForeignImport GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnFunDepConflict] :: !UnitState -> NonEmpty ClsInst -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnFunPtrImportWithoutAmpersand] :: ForeignImport GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnGADTMonoLocalBinds] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIdNotExportedFromLocalSig] :: Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIdNotExportedFromModuleSig] :: Name -> Module -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIgnoreSpecialisePragmaOnDefMethod] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIgnoringAnnotations] :: [LAnnDecl GhcRn] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalBindingOfBuiltIn] :: !OccName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalBuiltinSyntax] :: SDoc -> RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalClassInst] :: !TyConFlavour -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalConstraintSynonymOfKind] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalDerivingItem] :: !LHsSigType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalFamilyInstance] :: TyCon -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalFieldPunning] :: !Located RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalForeignDeclBackend] :: Either (ForeignExport GhcRn) (ForeignImport GhcRn) -> Backend -> ExpectedBackends -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalForeignType] :: !Maybe ArgOrResult -> !IllegalForeignTypeReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalHsBootFileDecl] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalHsigDefaultMethods] :: !Name -> NonEmpty (LHsBind GhcRn) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalImplicitParam] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalImplicitParameterBindings] :: Either (HsLocalBindsLR GhcPs GhcPs) (HsLocalBindsLR GhcRn GhcPs) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalNewtype] :: DataCon -> Bool -> IllegalNewtypeReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalPatSynDecl] :: !LIdP GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalRecordSyntax] :: !HsType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalStaticExpression] :: HsExpr GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalStaticFormInSplice] :: HsExpr GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalTupleConstraint] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalTupleSection] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalTypeData] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalTypeOperatorDecl] :: !RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalTypeOperator] :: !SDoc -> !RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalViewPattern] :: !Pat GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalWildcardInType] :: Maybe Name -> !BadAnonWildcardContext -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalWildcardsInConstructor] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIllegalWildcardsInRecord] :: !RecordFieldPart -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnImplicitLift] :: Name -> !ErrInfo -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInaccessibleCode] :: Implication -> SolverReportWithCtxt -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnIncorrectNameSpace] :: Name -> Bool -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInterfaceLookupError] :: !Name -> !SDoc -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInvalidCIdentifier] :: !CLabelString -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInvalidReturnKind] :: !DataSort -> !AllowedDataResKind -> !Kind -> !Maybe SuggestUnliftedTypes -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInvalidTopDecl] :: !HsDecl GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInvalidTypeApplication] :: Type -> LHsWcType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnInvalidVisibleKindArgument] :: !LHsType GhcRn -> !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnLastStmtNotExpr] :: HsStmtContext GhcRn -> UnexpectedStatement -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnLazyBangOnUnliftedType] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnLazyGADTPattern] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnLinearFuncInKind] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnLinearPatSyn] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnListComprehensionDuplicateBinding] :: Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnLoopySuperclassSolve] :: CtLoc -> PredType -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMatchesHaveDiffNumArgs] :: !HsMatchContext GhcTc -> !MatchArgBadMatches -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMessageWithInfo] :: !UnitState -> !TcRnMessageDetailed -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMisplacedInstSig] :: Name -> LHsSigType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMissingClassAssoc] :: TyCon -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMissingExportList] :: ModuleName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMissingFields] :: ConLike -> [(FieldLabelString, TcType)] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMissingImportList] :: IE GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMissingSignature] :: MissingSignature -> Exported -> Bool -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMissingStrictFields] :: ConLike -> [(FieldLabelString, TcType)] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMixedSelectors] :: Name -> [Id] -> Name -> [Id] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnModMissingRealSrcSpan] :: Module -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMonomorphicBindings] :: [Name] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMultipleDefaultDeclarations] :: [LDefaultDecl GhcRn] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnMultipleInlinePragmas] :: !Id -> !LocatedA InlinePragma -> !NonEmpty (LocatedA InlinePragma) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNameByTemplateHaskellQuote] :: !RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoClassInstHead] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoConstructorHasAllFields] :: [FieldLabelString] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoExplicitAssocTypeOrDefaultDeclaration] :: Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoFieldPunsRecordDot] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoPossibleParentForFields] :: [LHsRecUpdField GhcRn] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoRebindableSyntaxRecordDot] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNoRolesAssociatedWithThing] :: !TcTyThing -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNonExactName] :: !RdrName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNonOverloadedSpecialisePragma] :: !LIdP GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNonTypeVarArgInConstraint] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNonUnaryTypeclassConstraint] :: !LHsSigType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNotARecordSelector] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNotInScope] :: NotInScopeError -> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNotOpenFamily] :: TyCon -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnNullExportedModule] :: ModuleName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnOrphanInstance] :: ClsInst -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnOverloadedSig] :: TcIdSigInfo -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnOversaturatedVisibleKindArg] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPartialTypeSigBadQuantifier] :: Name -> Name -> Maybe Type -> LHsSigWcType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPartialTypeSigTyVarMismatch] :: Name -> Name -> Name -> LHsSigWcType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPartialTypeSignatures] :: !SuggestPartialTypeSignatures -> !ThetaType -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPatSynBundledWithNonDataCon] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPatSynBundledWithWrongType] :: Type -> Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPatSynNotBidirectional] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPolymorphicBinderMissingSig] :: Name -> Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnPragmaWarning] :: OccName -> WarningTxt GhcRn -> ModuleName -> ModuleName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnRecSelectorEscapedTyVar] :: !OccName -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnRecursivePatternSynonym] :: LHsBinds GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnRedundantConstraints] :: [Id] -> (SkolemInfoAnon, Bool) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnReportCustomQuasiError] :: !Bool -> !String -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnRunSpliceFailure] :: !Maybe String -> !RunSpliceFailReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSectionWithoutParentheses] :: HsExpr GhcPs -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnShadowedName] :: OccName -> ShadowedNameProvenance -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSimplifierTooManyIterations] :: Cts -> !IntWithInf -> WantedConstraints -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSolverReport] :: SolverReportWithCtxt -> DiagnosticReason -> [GhcHint] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSpecialClassInst] :: !Class -> !Bool -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSpecialiseNotVisible] :: !Name -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSplicePolymorphicLocalVar] :: !Id -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnSpliceThrewException] :: !SplicePhase -> !SomeException -> !String -> !LHsExpr GhcTc -> !Bool -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnStaticFormNotClosed] :: Name -> NotClosedReason -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTagToEnumMissingValArg] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTagToEnumResTyNotAnEnum] :: Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTagToEnumResTyTypeData] :: Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTagToEnumUnspecifiedResTy] :: Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTooManyBinders] :: !Kind -> ![LHsTyVarBndr () GhcRn] -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTooManyTyArgsInConPattern] :: !ConLike -> !Int -> !Int -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTupleConstraintInst] :: !Class -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTypeDataForbids] :: !TypeDataForbids -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTypeDoesNotHaveFixedRuntimeRep] :: !Type -> !FixedRuntimeRepProvenance -> !ErrInfo -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTypeEqualityOutOfScope] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTypeEqualityRequiresOperators] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnTypedTHWithPolyType] :: !TcType -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnboxedTupleOrSumTypeFuncArg] :: UnboxedTupleOrSum -> !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnexpectedAnnotation] :: !HsType GhcRn -> !HsSrcBang -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnexpectedPragmas] :: !Id -> !NonEmpty (LSig GhcRn) -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnexpectedStatementInContext] :: HsStmtContext GhcRn -> UnexpectedStatement -> Maybe Extension -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnexpectedTypeSplice] :: !HsType GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnknownMessage] :: UnknownDiagnostic -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnpromotableThing] :: !Name -> !PromotionErr -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnsafeDueToPlugin] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnsatisfiedMinimalDef] :: ClassMinimalDef -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnsupportedCallConv] :: Either (ForeignExport GhcRn) (ForeignImport GhcRn) -> UnsupportedCallConvention -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUntickedPromotedThing] :: UntickedPromotedThing -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUnusedPatternBinds] :: HsBind GhcRn -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUselessTypeable] :: TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnUserTypeError] :: !Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnVDQInTermType] :: !Maybe Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnWarnDefaulting] :: [Ct] -> Maybe TyVar -> Type -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnWarningMinimalDefIncomplete] :: ClassMinimalDef -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [TcRnWithHsDocContext] :: !HsDocContext -> !TcRnMessage -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: [errMsgContext] :: MsgEnvelope e -> NamePprCtx
+ Development.IDE.GHC.Compat.Error: [errMsgDiagnostic] :: MsgEnvelope e -> e
+ Development.IDE.GHC.Compat.Error: [errMsgSeverity] :: MsgEnvelope e -> Severity
+ Development.IDE.GHC.Compat.Error: [errMsgSpan] :: MsgEnvelope e -> SrcSpan
+ Development.IDE.GHC.Compat.Error: _GhcDriverMessage :: Prism' GhcMessage DriverMessage
+ Development.IDE.GHC.Compat.Error: _GhcDsMessage :: Prism' GhcMessage DsMessage
+ Development.IDE.GHC.Compat.Error: _GhcPsMessage :: Prism' GhcMessage PsMessage
+ Development.IDE.GHC.Compat.Error: _TcRnMessage :: Prism' GhcMessage TcRnMessage
+ Development.IDE.GHC.Compat.Error: class () => Diagnostic a where {
+ Development.IDE.GHC.Compat.Error: data () => DriverMessage
+ Development.IDE.GHC.Compat.Error: data () => DsMessage
+ Development.IDE.GHC.Compat.Error: data () => GhcMessage
+ Development.IDE.GHC.Compat.Error: data () => MsgEnvelope e
+ Development.IDE.GHC.Compat.Error: data () => PsMessage
+ Development.IDE.GHC.Compat.Error: data () => TcRnMessage
+ Development.IDE.GHC.Compat.Error: data () => TcRnMessageDetailed
+ Development.IDE.GHC.Compat.Error: defaultDiagnosticOpts :: Diagnostic a => DiagnosticOpts a
+ Development.IDE.GHC.Compat.Error: diagnosticCode :: Diagnostic a => a -> Maybe DiagnosticCode
+ Development.IDE.GHC.Compat.Error: diagnosticHints :: Diagnostic a => a -> [GhcHint]
+ Development.IDE.GHC.Compat.Error: diagnosticMessage :: Diagnostic a => DiagnosticOpts a -> a -> DecoratedSDoc
+ Development.IDE.GHC.Compat.Error: diagnosticReason :: Diagnostic a => a -> DiagnosticReason
+ Development.IDE.GHC.Compat.Error: msgEnvelopeErrorL :: Lens' (MsgEnvelope e) e
+ Development.IDE.GHC.Compat.Error: stripTcRnMessageContext :: TcRnMessage -> TcRnMessage
+ Development.IDE.GHC.Compat.Error: type family DiagnosticOpts a;
+ Development.IDE.GHC.Compat.Error: }
+ Development.IDE.GHC.Error: diagFromGhcErrorMessages :: Text -> DynFlags -> Bag (MsgEnvelope GhcMessage) -> [FileDiagnostic]
+ Development.IDE.GHC.Error: diagFromSDocErrMsg :: Text -> DynFlags -> MsgEnvelope DecoratedSDoc -> [FileDiagnostic]
+ Development.IDE.GHC.Error: diagFromSDocErrMsgs :: Text -> DynFlags -> Bag (MsgEnvelope DecoratedSDoc) -> [FileDiagnostic]
+ Development.IDE.GHC.Orphans: instance Control.DeepSeq.NFData (Language.Haskell.Syntax.Expr.HsExpr (GHC.Hs.Extension.GhcPass 'GHC.Hs.Extension.Typechecked))
+ Development.IDE.GHC.Orphans: instance Control.DeepSeq.NFData (Language.Haskell.Syntax.Pat.Pat (GHC.Hs.Extension.GhcPass 'GHC.Hs.Extension.Typechecked))
+ Development.IDE.Import.DependencyInformation: idToModLocation :: PathIdMap -> FilePathId -> ArtifactsLocation
+ Development.IDE.LSP.HoverDefinition: foundHover :: (Maybe Range, [Text]) -> Hover |? Null
+ Development.IDE.LSP.HoverDefinition: gotoImplementation :: Recorder (WithPriority Log) -> IdeState -> TextDocumentPositionParams -> ExceptT PluginError (HandlerM c) (MessageResult Method_TextDocumentImplementation)
+ Development.IDE.Plugin.HLS: LogResolveDefaultHandler :: Some SMethod -> Log
+ Development.IDE.Session: getInitialGhcLibDirDefault :: Recorder (WithPriority Log) -> FilePath -> IO (Maybe LibDir)
+ Development.IDE.Spans.AtPoint: gotoImplementation :: MonadIO m => WithHieDb -> LookupModule m -> IdeOptions -> HieAstResult -> Position -> MaybeT m [Location]
+ Development.IDE.Spans.Common: srcSpanToMdLink :: Location -> Text
+ Development.IDE.Types.Diagnostics: FileDiagnostic :: NormalizedFilePath -> ShowDiagnostic -> Diagnostic -> StructuredMessage -> FileDiagnostic
+ Development.IDE.Types.Diagnostics: NoStructuredMessage :: StructuredMessage
+ Development.IDE.Types.Diagnostics: SomeStructuredMessage :: MsgEnvelope GhcMessage -> StructuredMessage
+ Development.IDE.Types.Diagnostics: [fdFilePath] :: FileDiagnostic -> NormalizedFilePath
+ Development.IDE.Types.Diagnostics: [fdLspDiagnostic] :: FileDiagnostic -> Diagnostic
+ Development.IDE.Types.Diagnostics: [fdShouldShowDiagnostic] :: FileDiagnostic -> ShowDiagnostic
+ Development.IDE.Types.Diagnostics: [fdStructuredMessage] :: FileDiagnostic -> StructuredMessage
+ Development.IDE.Types.Diagnostics: _NoStructuredMessage :: Prism' StructuredMessage ()
+ Development.IDE.Types.Diagnostics: _SomeStructuredMessage :: Prism' StructuredMessage (MsgEnvelope GhcMessage)
+ Development.IDE.Types.Diagnostics: attachReason :: Maybe DiagnosticReason -> Diagnostic -> Diagnostic
+ Development.IDE.Types.Diagnostics: attachedReason :: Traversal' Diagnostic (Maybe Value)
+ Development.IDE.Types.Diagnostics: data FileDiagnostic
+ Development.IDE.Types.Diagnostics: data StructuredMessage
+ Development.IDE.Types.Diagnostics: fdFilePathL :: Lens' FileDiagnostic NormalizedFilePath
+ Development.IDE.Types.Diagnostics: fdLspDiagnosticL :: Lens' FileDiagnostic Diagnostic
+ Development.IDE.Types.Diagnostics: fdShouldShowDiagnosticL :: Lens' FileDiagnostic ShowDiagnostic
+ Development.IDE.Types.Diagnostics: fdStructuredMessageL :: Lens' FileDiagnostic StructuredMessage
+ Development.IDE.Types.Diagnostics: ideErrorFromLspDiag :: Diagnostic -> NormalizedFilePath -> Maybe (MsgEnvelope GhcMessage) -> FileDiagnostic
+ Development.IDE.Types.Diagnostics: instance Control.DeepSeq.NFData Development.IDE.Types.Diagnostics.FileDiagnostic
+ Development.IDE.Types.Diagnostics: instance Control.DeepSeq.NFData Development.IDE.Types.Diagnostics.StructuredMessage
+ Development.IDE.Types.Diagnostics: instance GHC.Classes.Eq Development.IDE.Types.Diagnostics.FileDiagnostic
+ Development.IDE.Types.Diagnostics: instance GHC.Classes.Eq Development.IDE.Types.Diagnostics.StructuredMessage
+ Development.IDE.Types.Diagnostics: instance GHC.Classes.Ord Development.IDE.Types.Diagnostics.FileDiagnostic
+ Development.IDE.Types.Diagnostics: instance GHC.Classes.Ord Development.IDE.Types.Diagnostics.StructuredMessage
+ Development.IDE.Types.Diagnostics: instance GHC.Generics.Generic Development.IDE.Types.Diagnostics.FileDiagnostic
+ Development.IDE.Types.Diagnostics: instance GHC.Generics.Generic Development.IDE.Types.Diagnostics.StructuredMessage
+ Development.IDE.Types.Diagnostics: instance GHC.Show.Show Development.IDE.Types.Diagnostics.FileDiagnostic
+ Development.IDE.Types.Diagnostics: instance GHC.Show.Show Development.IDE.Types.Diagnostics.StructuredMessage
+ Development.IDE.Types.Diagnostics: showGhcCode :: DiagnosticCode -> Text
- Development.IDE: TcModuleResult :: ParsedModule -> RenamedSource -> TcGblEnv -> Splices -> !Bool -> !ModuleEnv ByteString -> TcModuleResult
+ Development.IDE: TcModuleResult :: ParsedModule -> RenamedSource -> TcGblEnv -> Splices -> !Bool -> !ModuleEnv ByteString -> WarningMessages -> TcModuleResult
- Development.IDE: diagFromErrMsg :: Text -> DynFlags -> MsgEnvelope DecoratedSDoc -> [FileDiagnostic]
+ Development.IDE: diagFromErrMsg :: Text -> DynFlags -> MsgEnvelope GhcMessage -> [FileDiagnostic]
- Development.IDE: diagFromErrMsgs :: Text -> DynFlags -> Bag (MsgEnvelope DecoratedSDoc) -> [FileDiagnostic]
+ Development.IDE: diagFromErrMsgs :: Text -> DynFlags -> Bag (MsgEnvelope GhcMessage) -> [FileDiagnostic]
- Development.IDE: diagFromString :: Text -> DiagnosticSeverity -> SrcSpan -> String -> [FileDiagnostic]
+ Development.IDE: diagFromString :: Text -> DiagnosticSeverity -> SrcSpan -> String -> Maybe (MsgEnvelope GhcMessage) -> [FileDiagnostic]
- Development.IDE: diagFromStrings :: Text -> DiagnosticSeverity -> [(SrcSpan, String)] -> [FileDiagnostic]
+ Development.IDE: diagFromStrings :: Text -> DiagnosticSeverity -> [(SrcSpan, String, Maybe (MsgEnvelope GhcMessage))] -> [FileDiagnostic]
- Development.IDE: getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
+ Development.IDE: getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [(Location, Identifier)])
- Development.IDE: getFileContents :: NormalizedFilePath -> Action (UTCTime, Maybe Text)
+ Development.IDE: getFileContents :: NormalizedFilePath -> Action (Maybe Rope)
- Development.IDE: getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
+ Development.IDE: getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [(Location, Identifier)])
- Development.IDE: ideErrorWithSource :: Maybe Text -> Maybe DiagnosticSeverity -> a -> Text -> (a, ShowDiagnostic, Diagnostic)
+ Development.IDE: ideErrorWithSource :: Maybe Text -> Maybe DiagnosticSeverity -> NormalizedFilePath -> Text -> Maybe (MsgEnvelope GhcMessage) -> FileDiagnostic
- Development.IDE.Core.Actions: getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
+ Development.IDE.Core.Actions: getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [(Location, Identifier)])
- Development.IDE.Core.Actions: getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
+ Development.IDE.Core.Actions: getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [(Location, Identifier)])
- Development.IDE.Core.Compile: RecompilationInfo :: FileVersion -> Maybe (HiFileResult, FileVersion) -> (NormalizedFilePath -> m (Maybe FileVersion)) -> ([NormalizedFilePath] -> m [ByteString]) -> (Maybe LinkableType -> m ([FileDiagnostic], Maybe HiFileResult)) -> RecompilationInfo m
+ Development.IDE.Core.Compile: RecompilationInfo :: FileVersion -> Maybe (HiFileResult, FileVersion) -> (NormalizedFilePath -> m (Maybe FileVersion)) -> ([NormalizedFilePath] -> m [ByteString]) -> m DependencyInformation -> (Maybe LinkableType -> m ([FileDiagnostic], Maybe HiFileResult)) -> RecompilationInfo m
- Development.IDE.Core.Compile: TcModuleResult :: ParsedModule -> RenamedSource -> TcGblEnv -> Splices -> !Bool -> !ModuleEnv ByteString -> TcModuleResult
+ Development.IDE.Core.Compile: TcModuleResult :: ParsedModule -> RenamedSource -> TcGblEnv -> Splices -> !Bool -> !ModuleEnv ByteString -> WarningMessages -> TcModuleResult
- Development.IDE.Core.Compile: TypecheckHelpers :: ([NormalizedFilePath] -> IO [LinkableResult]) -> TypecheckHelpers
+ Development.IDE.Core.Compile: TypecheckHelpers :: ([NormalizedFilePath] -> IO [LinkableResult]) -> IO DependencyInformation -> TypecheckHelpers
- Development.IDE.Core.Compile: mergeEnvs :: HscEnv -> ModuleGraph -> ModSummary -> [HomeModInfo] -> [HscEnv] -> IO HscEnv
+ Development.IDE.Core.Compile: mergeEnvs :: HscEnv -> ModuleGraph -> DependencyInformation -> ModSummary -> [HomeModInfo] -> [HscEnv] -> IO HscEnv
- Development.IDE.Core.FileStore: getFileContents :: NormalizedFilePath -> Action (UTCTime, Maybe Text)
+ Development.IDE.Core.FileStore: getFileContents :: NormalizedFilePath -> Action (Maybe Rope)
- Development.IDE.Core.FileStore: getFileContentsImpl :: NormalizedFilePath -> Action ([FileDiagnostic], Maybe (FileVersion, Maybe Text))
+ Development.IDE.Core.FileStore: getFileContentsImpl :: NormalizedFilePath -> Action ([FileDiagnostic], Maybe (FileVersion, Maybe Rope))
- Development.IDE.Core.ProgressReporting: [inProgress] :: ProgressReporting -> forall a. NormalizedFilePath -> Action a -> Action a
+ Development.IDE.Core.ProgressReporting: [inProgress] :: PerFileProgressReporting -> forall a. NormalizedFilePath -> IO a -> IO a
- Development.IDE.Core.ProgressReporting: progressReporting :: Maybe (LanguageContextEnv c) -> ProgressReportingStyle -> IO ProgressReporting
+ Development.IDE.Core.ProgressReporting: progressReporting :: Maybe (LanguageContextEnv c) -> Text -> ProgressReportingStyle -> IO PerFileProgressReporting
- Development.IDE.Core.RuleTypes: TcModuleResult :: ParsedModule -> RenamedSource -> TcGblEnv -> Splices -> !Bool -> !ModuleEnv ByteString -> TcModuleResult
+ Development.IDE.Core.RuleTypes: TcModuleResult :: ParsedModule -> RenamedSource -> TcGblEnv -> Splices -> !Bool -> !ModuleEnv ByteString -> WarningMessages -> TcModuleResult
- Development.IDE.Core.Shake: HieDbWriter :: IndexQueue -> TVar (HashMap NormalizedFilePath Fingerprint) -> TVar Int -> Var (Maybe ProgressToken) -> HieDbWriter
+ Development.IDE.Core.Shake: HieDbWriter :: IndexQueue -> TVar (HashMap NormalizedFilePath Fingerprint) -> TVar Int -> ProgressReporting -> HieDbWriter
- Development.IDE.Core.Shake: ShakeExtras :: Maybe (LanguageContextEnv Config) -> Debouncer NormalizedUri -> Recorder (WithPriority Log) -> IdePlugins IdeState -> TVar (HashMap TypeRep Dynamic) -> Values -> STMDiagnosticStore -> STMDiagnosticStore -> Map NormalizedUri [Diagnostic] -> Map NormalizedFilePath SemanticTokens -> TVar Int -> Map NormalizedUri (EnumMap Int32 (PositionDelta, PositionMapping)) -> ProgressReporting -> IdeTesting -> (VFSModified -> String -> [DelayedAction ()] -> IO [Key] -> IO ()) -> NameCache -> TVar (Hashed KnownTargets) -> TVar ExportsMap -> ActionQueue -> ClientCapabilities -> WithHieDb -> HieDbWriter -> TVar (KeyMap GetStalePersistent) -> TVar VFS -> Config -> TVar KeySet -> TQueue (IO ()) -> TQueue (IO ()) -> ShakeExtras
+ Development.IDE.Core.Shake: ShakeExtras :: Maybe (LanguageContextEnv Config) -> Debouncer NormalizedUri -> Recorder (WithPriority Log) -> IdePlugins IdeState -> TVar (HashMap TypeRep Dynamic) -> Values -> STMDiagnosticStore -> STMDiagnosticStore -> Map NormalizedUri [FileDiagnostic] -> Map NormalizedFilePath SemanticTokens -> TVar Int -> Map NormalizedUri (EnumMap Int32 (PositionDelta, PositionMapping)) -> PerFileProgressReporting -> IdeTesting -> (VFSModified -> String -> [DelayedAction ()] -> IO [Key] -> IO ()) -> NameCache -> TVar (Hashed KnownTargets) -> TVar ExportsMap -> ActionQueue -> ClientCapabilities -> WithHieDb -> HieDbWriter -> TVar (KeyMap GetStalePersistent) -> TVar VFS -> Config -> TVar KeySet -> TQueue (IO ()) -> TQueue (IO ()) -> ShakeExtras
- Development.IDE.Core.Shake: [$sel:progress:ShakeExtras] :: ShakeExtras -> ProgressReporting
+ Development.IDE.Core.Shake: [$sel:progress:ShakeExtras] :: ShakeExtras -> PerFileProgressReporting
- Development.IDE.Core.Shake: [$sel:publishedDiagnostics:ShakeExtras] :: ShakeExtras -> Map NormalizedUri [Diagnostic]
+ Development.IDE.Core.Shake: [$sel:publishedDiagnostics:ShakeExtras] :: ShakeExtras -> Map NormalizedUri [FileDiagnostic]
- Development.IDE.GHC.Compat: pattern PFailedWithErrorMessages :: forall a b. (b -> Bag (MsgEnvelope DecoratedSDoc)) -> ParseResult a
+ Development.IDE.GHC.Compat: pattern PFailedWithErrorMessages :: forall a b. (b -> Bag (MsgEnvelope GhcMessage)) -> ParseResult a
- Development.IDE.GHC.Compat.Core: collectHsBindsBinders :: CollectPass p => Bag (XRec p (HsBindLR p idR)) -> [IdP p]
+ Development.IDE.GHC.Compat.Core: collectHsBindsBinders :: CollectPass p => LHsBindsLR p idR -> [IdP p]
- Development.IDE.GHC.Compat.Outputable: type ErrMsg = MsgEnvelope DecoratedSDoc
+ Development.IDE.GHC.Compat.Outputable: type ErrMsg = MsgEnvelope GhcMessage
- Development.IDE.GHC.Compat.Outputable: type WarnMsg = MsgEnvelope DecoratedSDoc
+ Development.IDE.GHC.Compat.Outputable: type WarnMsg = MsgEnvelope GhcMessage
- Development.IDE.GHC.Compat.Parser: pattern HsParsedModule :: Located (HsModule GhcPs) -> [FilePath] -> ApiAnns -> HsParsedModule
+ Development.IDE.GHC.Compat.Parser: pattern HsParsedModule :: Located (HsModule GhcPs) -> [FilePath] -> HsParsedModule
- Development.IDE.GHC.Compat.Parser: pattern ParsedModule :: ModSummary -> ParsedSource -> [FilePath] -> ApiAnns -> ParsedModule
+ Development.IDE.GHC.Compat.Parser: pattern ParsedModule :: ModSummary -> ParsedSource -> [FilePath] -> ParsedModule
- Development.IDE.GHC.Compat.Plugins: applyPluginsParsedResultAction :: HscEnv -> ModSummary -> ApiAnns -> ParsedSource -> PsMessages -> IO (ParsedSource, PsMessages)
+ Development.IDE.GHC.Compat.Plugins: applyPluginsParsedResultAction :: HscEnv -> ModSummary -> ParsedSource -> PsMessages -> IO (ParsedSource, PsMessages)
- Development.IDE.GHC.CoreFile: writeBinCoreFile :: FilePath -> CoreFile -> IO Fingerprint
+ Development.IDE.GHC.CoreFile: writeBinCoreFile :: DynFlags -> FilePath -> CoreFile -> IO Fingerprint
- Development.IDE.GHC.Error: diagFromErrMsg :: Text -> DynFlags -> MsgEnvelope DecoratedSDoc -> [FileDiagnostic]
+ Development.IDE.GHC.Error: diagFromErrMsg :: Text -> DynFlags -> MsgEnvelope GhcMessage -> [FileDiagnostic]
- Development.IDE.GHC.Error: diagFromErrMsgs :: Text -> DynFlags -> Bag (MsgEnvelope DecoratedSDoc) -> [FileDiagnostic]
+ Development.IDE.GHC.Error: diagFromErrMsgs :: Text -> DynFlags -> Bag (MsgEnvelope GhcMessage) -> [FileDiagnostic]
- Development.IDE.GHC.Error: diagFromString :: Text -> DiagnosticSeverity -> SrcSpan -> String -> [FileDiagnostic]
+ Development.IDE.GHC.Error: diagFromString :: Text -> DiagnosticSeverity -> SrcSpan -> String -> Maybe (MsgEnvelope GhcMessage) -> [FileDiagnostic]
- Development.IDE.GHC.Error: diagFromStrings :: Text -> DiagnosticSeverity -> [(SrcSpan, String)] -> [FileDiagnostic]
+ Development.IDE.GHC.Error: diagFromStrings :: Text -> DiagnosticSeverity -> [(SrcSpan, String, Maybe (MsgEnvelope GhcMessage))] -> [FileDiagnostic]
- Development.IDE.Spans.AtPoint: gotoDefinition :: MonadIO m => WithHieDb -> LookupModule m -> IdeOptions -> Map ModuleName NormalizedFilePath -> HieASTs a -> Position -> MaybeT m [Location]
+ Development.IDE.Spans.AtPoint: gotoDefinition :: MonadIO m => WithHieDb -> LookupModule m -> IdeOptions -> Map ModuleName NormalizedFilePath -> HieAstResult -> Position -> MaybeT m [(Location, Identifier)]
- Development.IDE.Spans.AtPoint: gotoTypeDefinition :: MonadIO m => WithHieDb -> LookupModule m -> IdeOptions -> HieAstResult -> Position -> MaybeT m [Location]
+ Development.IDE.Spans.AtPoint: gotoTypeDefinition :: MonadIO m => WithHieDb -> LookupModule m -> IdeOptions -> HieAstResult -> Position -> MaybeT m [(Location, Identifier)]
- Development.IDE.Spans.Pragmas: getNextPragmaInfo :: DynFlags -> Maybe Text -> NextPragmaInfo
+ Development.IDE.Spans.Pragmas: getNextPragmaInfo :: DynFlags -> Maybe Rope -> NextPragmaInfo
- Development.IDE.Types.Diagnostics: ideErrorWithSource :: Maybe Text -> Maybe DiagnosticSeverity -> a -> Text -> (a, ShowDiagnostic, Diagnostic)
+ Development.IDE.Types.Diagnostics: ideErrorWithSource :: Maybe Text -> Maybe DiagnosticSeverity -> NormalizedFilePath -> Text -> Maybe (MsgEnvelope GhcMessage) -> FileDiagnostic
- Development.IDE.Types.HscEnvEq: newHscEnvEq :: FilePath -> FilePath -> HscEnv -> [(UnitId, DynFlags)] -> IO HscEnvEq
+ Development.IDE.Types.HscEnvEq: newHscEnvEq :: HscEnv -> IO HscEnvEq

Files

ghcide.cabal view
@@ -2,7 +2,7 @@ build-type:         Simple category:           Development name:               ghcide-version:            2.9.0.1+version:            2.10.0.0 license:            Apache-2.0 license-file:       LICENSE author:             Digital Asset and Ghcide contributors@@ -14,15 +14,10 @@   https://github.com/haskell/haskell-language-server/tree/master/ghcide#readme  bug-reports:        https://github.com/haskell/haskell-language-server/issues-tested-with:        GHC ==9.10.1 || ==9.8.2 || ==9.6.5 || ==9.4.8 || ==9.2.8+tested-with:        GHC ==9.10.1 || ==9.8.2 || ==9.6.5 || ==9.4.8 extra-source-files:   CHANGELOG.md   README.md-  test/data/**/*.cabal-  test/data/**/*.hs-  test/data/**/*.hs-boot-  test/data/**/*.project-  test/data/**/*.yaml  source-repository head   type:     git@@ -81,16 +76,18 @@     , hie-bios                     ^>=0.14.0     , hie-compat                   ^>=0.3.0.0     , hiedb                        ^>= 0.6.0.0-    , hls-graph                    == 2.9.0.1-    , hls-plugin-api               == 2.9.0.1+    , hls-graph                    == 2.10.0.0+    , hls-plugin-api               == 2.10.0.0     , implicit-hie                 >= 0.1.4.0 && < 0.1.5     , lens+    , lens-aeson     , list-t     , lsp                          ^>=2.7     , lsp-types                    ^>=2.3     , mtl     , opentelemetry                >=0.6.1     , optparse-applicative+    , os-string     , parallel     , prettyprinter                >=1.7     , prettyprinter-ansi-terminal@@ -150,7 +147,9 @@     Development.IDE.GHC.Compat     Development.IDE.GHC.Compat.Core     Development.IDE.GHC.Compat.CmdLine+    Development.IDE.GHC.Compat.Driver     Development.IDE.GHC.Compat.Env+    Development.IDE.GHC.Compat.Error     Development.IDE.GHC.Compat.Iface     Development.IDE.GHC.Compat.Logger     Development.IDE.GHC.Compat.Outputable@@ -208,20 +207,6 @@   if flag(pedantic)     ghc-options:       -Werror--flag test-exe-  description: Build the ghcide-test-preprocessor executable-  default:     True--executable ghcide-test-preprocessor-  import: warnings-  default-language:   GHC2021-  hs-source-dirs:   test/preprocessor-  main-is:          Main.hs-  build-depends:    base >=4 && <5--  if !flag(test-exe)-    buildable: False  flag executable   description: Build the ghcide executable
session-loader/Development/IDE/Session.hs view
@@ -8,7 +8,7 @@   (SessionLoadingOptions(..)   ,CacheDirs(..)   ,loadSessionWithOptions-  ,setInitialDynFlags+  ,getInitialGhcLibDirDefault   ,getHieDbLoc   ,retryOnSqliteBusy   ,retryOnException@@ -62,8 +62,7 @@ import qualified Development.IDE.Session.Implicit    as GhcIde import           Development.IDE.Types.Diagnostics import           Development.IDE.Types.Exports-import           Development.IDE.Types.HscEnvEq      (HscEnvEq, newHscEnvEq,-                                                      newHscEnvEqPreserveImportPaths)+import           Development.IDE.Types.HscEnvEq      (HscEnvEq, newHscEnvEq) import           Development.IDE.Types.Location import           Development.IDE.Types.Options import           GHC.ResponseFile@@ -101,36 +100,32 @@ import           Data.HashMap.Strict                 (HashMap) import           Data.HashSet                        (HashSet) import qualified Data.HashSet                        as Set+import qualified Data.Set                            as OS import           Database.SQLite.Simple import           Development.IDE.Core.Tracing        (withTrace) import           Development.IDE.Core.WorkerThread   (awaitRunInThread,                                                       withWorkerQueue)+import qualified Development.IDE.GHC.Compat.Util     as Compat import           Development.IDE.Session.Diagnostics (renderCradleError) import           Development.IDE.Types.Shake         (WithHieDb,                                                       WithHieDbShield (..),                                                       toNoFileKey)+import           GHC.Data.Graph.Directed import           HieDb.Create import           HieDb.Types-import           HieDb.Utils import           Ide.PluginUtils                     (toAbsolute) import qualified System.Random                       as Random import           System.Random                       (RandomGen) import           Text.ParserCombinators.ReadP        (readP_to_S) ---- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if MIN_VERSION_ghc(9,3,0)-import qualified Data.Set                            as OS-import qualified Development.IDE.GHC.Compat.Util     as Compat-import           GHC.Data.Graph.Directed--import           GHC.Data.Bag import           GHC.Driver.Env                      (hsc_all_home_unit_ids) import           GHC.Driver.Errors.Types import           GHC.Types.Error                     (errMsgDiagnostic,                                                       singleMessage) import           GHC.Unit.State++#if MIN_VERSION_ghc(9,13,0)+import           GHC.Driver.Make                     (checkHomeUnitsClosed) #endif  data Log@@ -245,13 +240,6 @@   , getCacheDirs           :: String -> [String] -> IO CacheDirs   -- | Return the GHC lib dir to use for the 'unsafeGlobalDynFlags'   , getInitialGhcLibDir    :: Recorder (WithPriority Log) -> FilePath -> IO (Maybe LibDir)-#if !MIN_VERSION_ghc(9,3,0)-  , fakeUid                :: UnitId-    -- ^ unit id used to tag the internal component built by ghcide-    --   To reuse external interface files the unit ids must match,-    --   thus make sure to build them with `--this-unit-id` set to the-    --   same value as the ghcide fake uid-#endif   }  instance Default SessionLoadingOptions where@@ -260,9 +248,6 @@         ,loadCradle = loadWithImplicitCradle         ,getCacheDirs = getCacheDirsDefault         ,getInitialGhcLibDir = getInitialGhcLibDirDefault-#if !MIN_VERSION_ghc(9,3,0)-        ,fakeUid = Compat.toUnitId (Compat.stringToUnit "main")-#endif         }  -- | Find the cradle for a given 'hie.yaml' configuration.@@ -303,15 +288,6 @@         logWith recorder Warning LogGetInitialGhcLibDirDefaultCradleNone         pure Nothing --- | Sets `unsafeGlobalDynFlags` on using the hie-bios cradle and returns the GHC libdir-setInitialDynFlags :: Recorder (WithPriority Log) -> FilePath -> SessionLoadingOptions -> IO (Maybe LibDir)-setInitialDynFlags recorder rootDir SessionLoadingOptions{..} = do-  libdir <- getInitialGhcLibDir recorder rootDir-  dynFlags <- mapM dynFlagsForPrinting libdir-  logWith recorder Debug LogSettingInitialDynFlags-  mapM_ setUnsafeGlobalDynFlags dynFlags-  pure libdir- -- | If the action throws exception that satisfies predicate then we sleep for -- a duration determined by the random exponential backoff formula, -- `uniformRandom(0, min (maxDelay, (baseDelay * 2) ^ retryAttempt))`, and try@@ -540,26 +516,17 @@                   _inplace = map rawComponentUnitId $ NE.toList all_deps                all_deps' <- forM all_deps $ \RawComponentInfo{..} -> do-                  -- Remove all inplace dependencies from package flags for-                  -- components in this HscEnv-#if MIN_VERSION_ghc(9,3,0)-                  let (df2, uids) = (rawComponentDynFlags, [])-#else-                  let (df2, uids) = _removeInplacePackages fakeUid _inplace rawComponentDynFlags-#endif                   let prefix = show rawComponentUnitId                   -- See Note [Avoiding bad interface files]-                  let hscComponents = sort $ map show uids-                      cacheDirOpts = hscComponents ++ componentOptions opts+                  let cacheDirOpts = componentOptions opts                   cacheDirs <- liftIO $ getCacheDirs prefix cacheDirOpts-                  processed_df <- setCacheDirs recorder cacheDirs df2+                  processed_df <- setCacheDirs recorder cacheDirs rawComponentDynFlags                   -- The final component information, mostly the same but the DynFlags don't                   -- contain any packages which are also loaded                   -- into the same component.                   pure $ ComponentInfo                            { componentUnitId = rawComponentUnitId                            , componentDynFlags = processed_df-                           , componentInternalUnits = uids                            , componentTargets = rawComponentTargets                            , componentFP = rawComponentFP                            , componentCOptions = rawComponentCOptions@@ -585,8 +552,8 @@           -- For GHC's supporting multi component sessions, we create a shared           -- HscEnv but set the active component accordingly           hscEnv <- emptyHscEnv ideNc _libDir-          let new_cache = newComponentCache recorder optExtensions hieYaml _cfp hscEnv-          all_target_details <- new_cache old_deps new_deps rootDir+          let new_cache = newComponentCache recorder optExtensions _cfp hscEnv+          all_target_details <- new_cache old_deps new_deps            this_dep_info <- getDependencyInfo $ maybeToList hieYaml           let (all_targets, this_flags_map, this_options)@@ -599,10 +566,11 @@                         this_flags = (this_error_env, this_dep_info)                         this_error_env = ([this_error], Nothing)                         this_error = ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) _cfp-                                       $ T.unlines-                                       [ "No cradle target found. Is this file listed in the targets of your cradle?"-                                       , "If you are using a .cabal file, please ensure that this module is listed in either the exposed-modules or other-modules section"-                                       ]+                                       (T.unlines+                                         [ "No cradle target found. Is this file listed in the targets of your cradle?"+                                         , "If you are using a .cabal file, please ensure that this module is listed in either the exposed-modules or other-modules section"+                                         ])+                                       Nothing            void $ modifyVar' fileToFlags $ Map.insert hieYaml this_flags_map           void $ modifyVar' filesMap $ flip HM.union (HM.fromList (map ((,hieYaml) . fst) $ concatMap toFlagsMap all_targets))@@ -771,24 +739,13 @@             PreferSingleComponentLoading -> LoadFile             PreferMultiComponentLoading  -> LoadWithContext old_fps -#if MIN_VERSION_ghc(9,3,0) emptyHscEnv :: NameCache -> FilePath -> IO HscEnv-#else-emptyHscEnv :: IORef NameCache -> FilePath -> IO HscEnv-#endif emptyHscEnv nc libDir = do     -- We call setSessionDynFlags so that the loader is initialised     -- We need to do this before we call initUnits.     env <- runGhc (Just libDir) $       getSessionDynFlags >>= setSessionDynFlags >> getSession-    -- On GHC 9.2 calling setSessionDynFlags caches the unit databases-    -- for an empty environment. This prevents us from reading the-    -- package database subsequently. So clear the unit db cache in-    -- hsc_unit_dbs     pure $ setNameCache nc (hscSetFlags ((hsc_dflags env){useUnicode = True }) env)-#if !MIN_VERSION_ghc(9,3,0)-              {hsc_unit_dbs = Nothing}-#endif  data TargetDetails = TargetDetails   {@@ -826,23 +783,23 @@     [ (l, (targetEnv, targetDepends)) | l <-  targetLocations]  -#if MIN_VERSION_ghc(9,3,0) setNameCache :: NameCache -> HscEnv -> HscEnv-#else-setNameCache :: IORef NameCache -> HscEnv -> HscEnv-#endif setNameCache nc hsc = hsc { hsc_NC = nc } -#if MIN_VERSION_ghc(9,3,0)+#if MIN_VERSION_ghc(9,13,0)+-- Moved back to implementation in GHC.+checkHomeUnitsClosed' ::  UnitEnv -> OS.Set UnitId -> [DriverMessages]+checkHomeUnitsClosed' ue _ = checkHomeUnitsClosed ue+#elif MIN_VERSION_ghc(9,3,0) -- This function checks the important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -- GHC had an implementation of this function, but it was horribly inefficient -- We should move back to the GHC implementation on compilers where -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/12162 is included-checkHomeUnitsClosed' ::  UnitEnv -> OS.Set UnitId -> [DriverMessages]+checkHomeUnitsClosed' ::  UnitEnv -> OS.Set UnitId -> Maybe (Compat.MsgEnvelope DriverMessage) checkHomeUnitsClosed' ue home_id_set-    | OS.null bad_unit_ids = []-    | otherwise = [singleMessage $ GHC.mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (OS.toList bad_unit_ids)]+    | OS.null bad_unit_ids = Nothing+    | otherwise = Just (GHC.mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (OS.toList bad_unit_ids))   where     bad_unit_ids = upwards_closure OS.\\ home_id_set     rootLoc = mkGeneralSrcSpan (Compat.fsLit "<command line>")@@ -865,7 +822,7 @@       where         go rest this this_uis =            plusUniqMap_C OS.union-             (addToUniqMap_C OS.union external_depends this (OS.fromList $ this_deps))+             (addToUniqMap_C OS.union external_depends this (OS.fromList this_deps))              rest            where              external_depends = mapUniqMap (OS.fromList . unitDepends)@@ -899,14 +856,12 @@ newComponentCache          :: Recorder (WithPriority Log)          -> [String]           -- ^ File extensions to consider-         -> Maybe FilePath     -- ^ Path to cradle          -> NormalizedFilePath -- ^ Path to file that caused the creation of this component          -> HscEnv             -- ^ An empty HscEnv          -> [ComponentInfo]    -- ^ New components to be loaded          -> [ComponentInfo]    -- ^ old, already existing components-         -> FilePath           -- ^ root dir, see Note [Root Directory]          -> IO [ [TargetDetails] ]-newComponentCache recorder exts cradlePath _cfp hsc_env old_cis new_cis dir = do+newComponentCache recorder exts _cfp hsc_env old_cis new_cis = do     let cis = Map.unionWith unionCIs (mkMap new_cis) (mkMap old_cis)         -- When we have multiple components with the same uid,         -- prefer the new one over the old.@@ -920,18 +875,22 @@     hscEnv' <- -- Set up a multi component session with the other units on GHC 9.4               Compat.initUnits dfs hsc_env -#if MIN_VERSION_ghc(9,3,0)-    let closure_errs = checkHomeUnitsClosed' (hsc_unit_env hscEnv') (hsc_all_home_unit_ids hscEnv')-        multi_errs = map (ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Warning) _cfp . T.pack . Compat.printWithoutUniques) closure_errs+    let closure_errs = maybeToList $ checkHomeUnitsClosed' (hsc_unit_env hscEnv') (hsc_all_home_unit_ids hscEnv')+        closure_err_to_multi_err err =+            ideErrorWithSource+                (Just "cradle") (Just DiagnosticSeverity_Warning) _cfp+                (T.pack (Compat.printWithoutUniques (singleMessage err)))+#if MIN_VERSION_ghc(9,5,0)+                (Just (fmap GhcDriverMessage err))+#else+                Nothing+#endif+        multi_errs = map closure_err_to_multi_err closure_errs         bad_units = OS.fromList $ concat $ do-            x <- bagToList $ mapBag errMsgDiagnostic $ unionManyBags $ map Compat.getMessages closure_errs+            x <- map errMsgDiagnostic closure_errs             DriverHomePackagesNotClosed us <- pure x             pure us         isBad ci = (homeUnitId_ (componentDynFlags ci)) `OS.member` bad_units-#else-    let isBad = const False-        multi_errs = []-#endif     -- Whenever we spin up a session on Linux, dynamically load libm.so.6     -- in. We need this in case the binary is statically linked, in which     -- case the interactive session will fail when trying to load@@ -951,26 +910,12 @@      forM (Map.elems cis) $ \ci -> do       let df = componentDynFlags ci-      let createHscEnvEq = maybe newHscEnvEqPreserveImportPaths (newHscEnvEq dir) cradlePath       thisEnv <- do-#if MIN_VERSION_ghc(9,3,0)             -- In GHC 9.4 we have multi component support, and we have initialised all the units             -- above.             -- We just need to set the current unit here             pure $ hscSetActiveUnitId (homeUnitId_ df) hscEnv'-#else-            -- This initializes the units for GHC 9.2-            -- Add the options for the current component to the HscEnv-            -- We want to call `setSessionDynFlags` instead of `hscSetFlags`-            -- because `setSessionDynFlags` also initializes the package database,-            -- which we need for any changes to the package flags in the dynflags-            -- to be visible.-            -- See #2693-            evalGhcEnv hscEnv' $ do-              _ <- setSessionDynFlags df-              getSession-#endif-      henv <- createHscEnvEq thisEnv (zip uids dfs)+      henv <- newHscEnvEq thisEnv       let targetEnv = (if isBad ci then multi_errs else [], Just henv)           targetDepends = componentDependencyInfo ci       logWith recorder Debug $ LogNewComponentCache (targetEnv, targetDepends)@@ -1076,10 +1021,6 @@   -- | Processed DynFlags. Does not contain inplace packages such as local   -- libraries. Can be used to actually load this Component.   , componentDynFlags       :: DynFlags-  -- | Internal units, such as local libraries, that this component-  -- is loaded with. These have been extracted from the original-  -- ComponentOptions.-  , componentInternalUnits  :: [UnitId]   -- | All targets of this components.   , componentTargets        :: [GHC.Target]   -- | Filepath which caused the creation of this component@@ -1201,7 +1142,6 @@       initOne this_opts = do         (dflags', targets') <- addCmdOpts this_opts dflags         let dflags'' =-#if MIN_VERSION_ghc(9,3,0)                 case unitIdString (homeUnitId_ dflags') of                      -- cabal uses main for the unit id of all executable packages                      -- This makes multi-component sessions confused about what@@ -1210,13 +1150,10 @@                      -- This works because there won't be any dependencies on the                      -- executable unit.                      "main" ->-                       let hash = B.unpack $ B16.encode $ H.finalize $ H.updates H.init (map B.pack $ this_opts)+                       let hash = B.unpack $ B16.encode $ H.finalize $ H.updates H.init (map B.pack this_opts)                            hashed_uid = Compat.toUnitId (Compat.stringToUnit ("main-"++hash))                        in setHomeUnitId_ hashed_uid dflags'                      _ -> dflags'-#else-                dflags'-#endif          let targets = makeTargetsAbsolute root targets'             root = case workingDirectory dflags'' of@@ -1236,14 +1173,7 @@               Compat.setUpTypedHoles $               makeDynFlagsAbsolute compRoot -- makeDynFlagsAbsolute already accounts for workingDirectory               dflags''-        -- initPackages parses the -package flags and-        -- sets up the visibility for each component.-        -- Throws if a -package flag cannot be satisfied.-        -- This only works for GHC <9.2-        -- For GHC >= 9.2, we need to modify the unit env in the hsc_dflags, which-        -- is done later in newComponentCache-        final_flags <- liftIO $ wrapPackageSetupException $ Compat.oldInitUnits dflags'''-        return (final_flags, targets)+        return (dflags''', targets)  setIgnoreInterfacePragmas :: DynFlags -> DynFlags setIgnoreInterfacePragmas df =@@ -1289,12 +1219,6 @@  instance Exception PackageSetupException --- | Wrap any exception as a 'PackageSetupException'-wrapPackageSetupException :: IO a -> IO a-wrapPackageSetupException = handleAny $ \case-  e | Just (pkgE :: PackageSetupException) <- fromException e -> throwIO pkgE-  e -> (throwIO . PackageSetupException . show) e- showPackageSetupException :: PackageSetupException -> String showPackageSetupException GhcVersionMismatch{..} = unwords     ["ghcide compiled against GHC"@@ -1308,6 +1232,6 @@     , "failed to load packages:", message <> "."     , "\nPlease ensure that ghcide is compiled with the same GHC installation as the project."] -renderPackageSetupException :: FilePath -> PackageSetupException -> (NormalizedFilePath, ShowDiagnostic, Diagnostic)+renderPackageSetupException :: FilePath -> PackageSetupException -> FileDiagnostic renderPackageSetupException fp e =-    ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) (toNormalizedFilePath' fp) (T.pack $ showPackageSetupException e)+  ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) (toNormalizedFilePath' fp) (T.pack $ showPackageSetupException e) Nothing
session-loader/Development/IDE/Session/Diagnostics.hs view
@@ -2,6 +2,7 @@  module Development.IDE.Session.Diagnostics where import           Control.Applicative+import           Control.Lens import           Control.Monad import qualified Data.Aeson                        as Aeson import           Data.List@@ -27,11 +28,13 @@   Depicts the cradle error in a user-friendly way. -} renderCradleError :: CradleError -> Cradle a -> NormalizedFilePath -> FileDiagnostic-renderCradleError (CradleError deps _ec ms) cradle nfp-  | HieBios.isCabalCradle cradle =-      let (fp, showDiag, diag) = ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp $ T.unlines $ map T.pack userFriendlyMessage in-        (fp, showDiag, diag{_data_ = Just $ Aeson.toJSON CradleErrorDetails{cabalProjectFiles=absDeps}})-  | otherwise = ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp $ T.unlines $ map T.pack userFriendlyMessage+renderCradleError (CradleError deps _ec ms) cradle nfp =+  let noDetails =+        ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp (T.unlines $ map T.pack userFriendlyMessage) Nothing+  in+  if HieBios.isCabalCradle cradle+     then noDetails & fdLspDiagnosticL %~ \diag -> diag{_data_ = Just $ Aeson.toJSON CradleErrorDetails{cabalProjectFiles=absDeps}}+     else noDetails   where     absDeps = fmap (cradleRootDir cradle </>) deps     userFriendlyMessage :: [String]
src/Development/IDE.hs view
@@ -10,7 +10,9 @@                                                              getDefinition,                                                              getTypeDefinition) import           Development.IDE.Core.FileExists       as X (getFileExists)-import           Development.IDE.Core.FileStore        as X (getFileContents)+import           Development.IDE.Core.FileStore        as X (getFileContents,+                                                             getFileModTimeContents,+                                                             getUriContents) import           Development.IDE.Core.IdeConfiguration as X (IdeConfiguration (..),                                                              isWorkspaceFile) import           Development.IDE.Core.OfInterest       as X (getFilesOfInterestUntracked)@@ -50,7 +52,6 @@ import           Development.IDE.Plugin                as X import           Development.IDE.Types.Diagnostics     as X import           Development.IDE.Types.HscEnvEq        as X (HscEnvEq (..),-                                                             hscEnv,-                                                             hscEnvWithImportPaths)+                                                             hscEnv) import           Development.IDE.Types.Location        as X import           Ide.Logger                            as X
src/Development/IDE/Core/Actions.hs view
@@ -3,6 +3,7 @@ ( getAtPoint , getDefinition , getTypeDefinition+, getImplementationDefinition , highlightAtPoint , refsAtPoint , workspaceSymbols@@ -66,56 +67,68 @@   !pos' <- MaybeT (return $ fromCurrentPosition mapping pos)   MaybeT $ liftIO $ fmap (first (toCurrentRange mapping =<<)) <$> AtPoint.atPoint opts hf dkMap env pos' --- | For each Location, determine if we have the PositionMapping--- for the correct file. If not, get the correct position mapping--- and then apply the position mapping to the location.-toCurrentLocations+-- | Converts locations in the source code to their current positions,+-- taking into account changes that may have occurred due to edits.+toCurrentLocation   :: PositionMapping   -> NormalizedFilePath-  -> [Location]-  -> IdeAction [Location]-toCurrentLocations mapping file = mapMaybeM go+  -> Location+  -> IdeAction (Maybe Location)+toCurrentLocation mapping file (Location uri range) =+  -- The Location we are going to might be in a different+  -- file than the one we are calling gotoDefinition from.+  -- So we check that the location file matches the file+  -- we are in.+  if nUri == normalizedFilePathToUri file+  -- The Location matches the file, so use the PositionMapping+  -- we have.+  then pure $ Location uri <$> toCurrentRange mapping range+  -- The Location does not match the file, so get the correct+  -- PositionMapping and use that instead.+  else do+    otherLocationMapping <- fmap (fmap snd) $ runMaybeT $ do+      otherLocationFile <- MaybeT $ pure $ uriToNormalizedFilePath nUri+      useWithStaleFastMT GetHieAst otherLocationFile+    pure $ Location uri <$> (flip toCurrentRange range =<< otherLocationMapping)   where-    go :: Location -> IdeAction (Maybe Location)-    go (Location uri range) =-      -- The Location we are going to might be in a different-      -- file than the one we are calling gotoDefinition from.-      -- So we check that the location file matches the file-      -- we are in.-      if nUri == normalizedFilePathToUri file-      -- The Location matches the file, so use the PositionMapping-      -- we have.-      then pure $ Location uri <$> toCurrentRange mapping range-      -- The Location does not match the file, so get the correct-      -- PositionMapping and use that instead.-      else do-        otherLocationMapping <- fmap (fmap snd) $ runMaybeT $ do-          otherLocationFile <- MaybeT $ pure $ uriToNormalizedFilePath nUri-          useWithStaleFastMT GetHieAst otherLocationFile-        pure $ Location uri <$> (flip toCurrentRange range =<< otherLocationMapping)-      where-        nUri :: NormalizedUri-        nUri = toNormalizedUri uri+    nUri :: NormalizedUri+    nUri = toNormalizedUri uri  -- | Goto Definition.-getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])+getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [(Location, Identifier)]) getDefinition file pos = runMaybeT $ do     ide@ShakeExtras{ withHieDb, hiedbWriter } <- ask     opts <- liftIO $ getIdeOptionsIO ide-    (HAR _ hf _ _ _, mapping) <- useWithStaleFastMT GetHieAst file+    (hf, mapping) <- useWithStaleFastMT GetHieAst file     (ImportMap imports, _) <- useWithStaleFastMT GetImportMap file     !pos' <- MaybeT (pure $ fromCurrentPosition mapping pos)-    locations <- AtPoint.gotoDefinition withHieDb (lookupMod hiedbWriter) opts imports hf pos'-    MaybeT $ Just <$> toCurrentLocations mapping file locations+    locationsWithIdentifier <- AtPoint.gotoDefinition withHieDb (lookupMod hiedbWriter) opts imports hf pos'+    mapMaybeM (\(location, identifier) -> do+      fixedLocation <- MaybeT $ toCurrentLocation mapping file location+      pure $ Just (fixedLocation, identifier)+      ) locationsWithIdentifier -getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])++getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [(Location, Identifier)]) getTypeDefinition file pos = runMaybeT $ do     ide@ShakeExtras{ withHieDb, hiedbWriter } <- ask     opts <- liftIO $ getIdeOptionsIO ide     (hf, mapping) <- useWithStaleFastMT GetHieAst file     !pos' <- MaybeT (return $ fromCurrentPosition mapping pos)-    locations <- AtPoint.gotoTypeDefinition withHieDb (lookupMod hiedbWriter) opts hf pos'-    MaybeT $ Just <$> toCurrentLocations mapping file locations+    locationsWithIdentifier <- AtPoint.gotoTypeDefinition withHieDb (lookupMod hiedbWriter) opts hf pos'+    mapMaybeM (\(location, identifier) -> do+      fixedLocation <- MaybeT $ toCurrentLocation mapping file location+      pure $ Just (fixedLocation, identifier)+      ) locationsWithIdentifier++getImplementationDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])+getImplementationDefinition file pos = runMaybeT $ do+    ide@ShakeExtras{ withHieDb, hiedbWriter } <- ask+    opts <- liftIO $ getIdeOptionsIO ide+    (hf, mapping) <- useWithStaleFastMT GetHieAst file+    !pos' <- MaybeT (pure $ fromCurrentPosition mapping pos)+    locs <- AtPoint.gotoImplementation withHieDb (lookupMod hiedbWriter) opts hf pos'+    traverse (MaybeT . toCurrentLocation mapping file) locs  highlightAtPoint :: NormalizedFilePath -> Position -> IdeAction (Maybe [DocumentHighlight]) highlightAtPoint file pos = runMaybeT $ do
src/Development/IDE/Core/Compile.hs view
@@ -36,103 +36,109 @@   , sourceTypecheck   , sourceParser   , shareUsages+  , setNonHomeFCHook   ) where -import           Control.Concurrent.Extra-import           Control.Concurrent.STM.Stats      hiding (orElse)-import           Control.DeepSeq                   (NFData (..), force, rnf)-import           Control.Exception                 (evaluate)+import           Control.Concurrent.STM.Stats           hiding (orElse)+import           Control.DeepSeq                        (NFData (..), force,+                                                         rnf)+import           Control.Exception                      (evaluate) import           Control.Exception.Safe-import           Control.Lens                      hiding (List, pre, (<.>))+import           Control.Lens                           hiding (List, pre,+                                                         (<.>)) import           Control.Monad.Extra import           Control.Monad.IO.Class import           Control.Monad.Trans.Except-import qualified Control.Monad.Trans.State.Strict  as S-import           Data.Aeson                        (toJSON)-import           Data.Bifunctor                    (first, second)+import qualified Control.Monad.Trans.State.Strict       as S+import           Data.Aeson                             (toJSON)+import           Data.Bifunctor                         (first, second) import           Data.Binary-import qualified Data.ByteString                   as BS+import qualified Data.ByteString                        as BS import           Data.Coerce-import qualified Data.DList                        as DL+import qualified Data.DList                             as DL import           Data.Functor import           Data.Generics.Aliases import           Data.Generics.Schemes-import qualified Data.HashMap.Strict               as HashMap-import           Data.IntMap                       (IntMap)+import qualified Data.HashMap.Strict                    as HashMap+import           Data.IntMap                            (IntMap) import           Data.IORef import           Data.List.Extra-import qualified Data.Map.Strict                   as Map+import qualified Data.List.NonEmpty                     as NE+import qualified Data.Map.Strict                        as Map import           Data.Maybe-import           Data.Proxy                        (Proxy (Proxy))-import qualified Data.Text                         as T-import           Data.Time                         (UTCTime (..))-import           Data.Tuple.Extra                  (dupe)-import           Data.Unique                       as Unique+import           Data.Proxy                             (Proxy (Proxy))+import qualified Data.Text                              as T+import           Data.Time                              (UTCTime (..), getCurrentTime)+import           Data.Tuple.Extra                       (dupe) import           Debug.Trace-import           Development.IDE.Core.FileStore    (resetInterfaceStore)+import           Development.IDE.Core.FileStore         (resetInterfaceStore) import           Development.IDE.Core.Preprocessor+import           Development.IDE.Core.ProgressReporting (progressUpdate) import           Development.IDE.Core.RuleTypes import           Development.IDE.Core.Shake-import           Development.IDE.Core.Tracing      (withTrace)-import           Development.IDE.GHC.Compat        hiding (loadInterface,-                                                    parseHeader, parseModule,-                                                    tcRnModule, writeHieFile, assert)-import qualified Development.IDE.GHC.Compat        as Compat-import qualified Development.IDE.GHC.Compat        as GHC-import qualified Development.IDE.GHC.Compat.Util   as Util+import           Development.IDE.Core.Tracing           (withTrace)+import           Development.IDE.GHC.Compat             hiding (assert,+                                                         loadInterface,+                                                         parseHeader,+                                                         parseModule,+                                                         tcRnModule,+                                                         writeHieFile)+import qualified Development.IDE.GHC.Compat             as Compat+import qualified Development.IDE.GHC.Compat             as GHC+import qualified Development.IDE.GHC.Compat.Util        as Util import           Development.IDE.GHC.CoreFile import           Development.IDE.GHC.Error-import           Development.IDE.GHC.Orphans       ()+import           Development.IDE.GHC.Orphans            () import           Development.IDE.GHC.Util import           Development.IDE.GHC.Warnings import           Development.IDE.Types.Diagnostics import           Development.IDE.Types.Location import           Development.IDE.Types.Options-import           GHC                               (ForeignHValue,-                                                    GetDocsFailure (..),-                                                    parsedSource)-import qualified GHC.LanguageExtensions            as LangExt+import           GHC                                    (ForeignHValue,+                                                         GetDocsFailure (..),+                                                         parsedSource, ModLocation (..))+import qualified GHC.LanguageExtensions                 as LangExt import           GHC.Serialized-import           HieDb                             hiding (withHieDb)-import qualified Language.LSP.Protocol.Message     as LSP-import           Language.LSP.Protocol.Types       (DiagnosticTag (..))-import qualified Language.LSP.Protocol.Types       as LSP-import qualified Language.LSP.Server               as LSP-import           Prelude                           hiding (mod)+import           HieDb                                  hiding (withHieDb)+import qualified Language.LSP.Protocol.Message          as LSP+import           Language.LSP.Protocol.Types            (DiagnosticTag (..))+import qualified Language.LSP.Server                    as LSP+import           Prelude                                hiding (mod) import           System.Directory import           System.FilePath-import           System.IO.Extra                   (fixIO, newTempFileWithin)+import           System.IO.Extra                        (fixIO,+                                                         newTempFileWithin) -import qualified GHC                               as G+import qualified Data.Set                               as Set+import qualified GHC                                    as G+import qualified GHC.Runtime.Loader                as Loader import           GHC.Tc.Gen.Splice+import           GHC.Types.Error import           GHC.Types.ForeignStubs import           GHC.Types.HpcInfo import           GHC.Types.TypeEnv  -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           Data.Map                          (Map)-import           GHC.Unit.Module.Graph             (ModuleGraph)-import           Unsafe.Coerce-#endif -#if MIN_VERSION_ghc(9,3,0)-import qualified Data.Set                          as Set-#endif- #if MIN_VERSION_ghc(9,5,0) import           GHC.Core.Lint.Interactive import           GHC.Driver.Config.CoreToStg.Prep #endif  #if MIN_VERSION_ghc(9,7,0)-import           Data.Foldable                     (toList)+import           Data.Foldable                          (toList) import           GHC.Unit.Module.Warnings #else-import           Development.IDE.Core.FileStore    (shareFilePath)+import           Development.IDE.Core.FileStore         (shareFilePath) #endif +import           Development.IDE.GHC.Compat.Driver (hscTypecheckRenameWithDiagnostics)++import Development.IDE.Import.DependencyInformation+import GHC.Driver.Env ( hsc_all_home_unit_ids )+import Development.IDE.Import.FindImports+ --Simple constants to make sure the source is consistently named sourceTypecheck :: T.Text sourceTypecheck = "typecheck"@@ -160,13 +166,18 @@     -> IO (Either [FileDiagnostic] [UnitId]) computePackageDeps env pkg = do     case lookupUnit env pkg of-        Nothing -> return $ Left [ideErrorText (toNormalizedFilePath' noFilePath) $-            T.pack $ "unknown package: " ++ show pkg]+        Nothing ->+          return $ Left+            [ ideErrorText+                (toNormalizedFilePath' noFilePath)+                (T.pack $ "unknown package: " ++ show pkg)+            ]         Just pkgInfo -> return $ Right $ unitDepends pkgInfo -newtype TypecheckHelpers+data TypecheckHelpers   = TypecheckHelpers   { getLinkables       :: [NormalizedFilePath] -> IO [LinkableResult] -- ^ hls-graph action to get linkables for files+  , getModuleGraph :: IO DependencyInformation   }  typecheckModule :: IdeDefer@@ -178,24 +189,28 @@         let modSummary = pm_mod_summary pm             dflags = ms_hspp_opts modSummary         initialized <- catchSrcErrors (hsc_dflags hsc) "typecheck (initialize plugins)"-                                      (initPlugins hsc modSummary)+                                      (Loader.initializePlugins (hscSetFlags (ms_hspp_opts modSummary) hsc))         case initialized of           Left errs -> return (errs, Nothing)-          Right (modSummary', hscEnv) -> do-            (warnings, etcm) <- withWarnings sourceTypecheck $ \tweak ->+          Right hscEnv -> do+            etcm <-                 let-                  session = tweak (hscSetFlags dflags hscEnv)-                   -- TODO: maybe settings ms_hspp_opts is unnecessary?-                  mod_summary'' = modSummary' { ms_hspp_opts = hsc_dflags session}+                   -- TODO: maybe setting ms_hspp_opts is unnecessary?+                  mod_summary' = modSummary { ms_hspp_opts = hsc_dflags hscEnv}                 in                   catchSrcErrors (hsc_dflags hscEnv) sourceTypecheck $ do-                    tcRnModule session tc_helpers $ demoteIfDefer pm{pm_mod_summary = mod_summary''}-            let errorPipeline = unDefer . hideDiag dflags . tagDiag-                diags = map errorPipeline warnings-                deferredError = any fst diags+                    tcRnModule hscEnv tc_helpers $ demoteIfDefer pm{pm_mod_summary = mod_summary'}             case etcm of-              Left errs -> return (map snd diags ++ errs, Nothing)-              Right tcm -> return (map snd diags, Just $ tcm{tmrDeferredError = deferredError})+              Left errs -> return (errs, Nothing)+              Right tcm ->+                let addReason diag =+                      map (Just (diagnosticReason (errMsgDiagnostic diag)),) $+                        diagFromErrMsg sourceTypecheck (hsc_dflags hscEnv) diag+                    errorPipeline = map (unDefer . hideDiag dflags . tagDiag) . addReason+                    diags = concatMap errorPipeline $ Compat.getMessages $ tmrWarnings tcm+                    deferredError = any fst diags+                in+                return (map snd diags, Just $ tcm{tmrDeferredError = deferredError})     where         demoteIfDefer = if defer then demoteTypeErrorsToWarnings else id @@ -223,11 +238,7 @@     -- come from in the IORef,, as these are the modules on whose implementation     -- we depend.     compile_bco_hook :: IORef (ModuleEnv BS.ByteString) -> HscEnv -> SrcSpan -> CoreExpr-#if MIN_VERSION_ghc(9,3,0)                      -> IO (ForeignHValue, [Linkable], PkgsLoaded)-#else-                     -> IO ForeignHValue-#endif     compile_bco_hook var hsc_env srcspan ds_expr       = do { let dflags = hsc_dflags hsc_env @@ -247,10 +258,8 @@            ; let iNTERACTIVELoc = G.ModLocation{ ml_hs_file   = Nothing,                                         ml_hi_file   = panic "hscCompileCoreExpr':ml_hi_file",                                         ml_obj_file  = panic "hscCompileCoreExpr':ml_obj_file",-#if MIN_VERSION_ghc(9,3,0)                                         ml_dyn_obj_file = panic "hscCompileCoreExpr':ml_dyn_obj_file",                                         ml_dyn_hi_file  = panic "hscCompileCoreExpr':ml_dyn_hi_file",-#endif                                         ml_hie_file  = panic "hscCompileCoreExpr':ml_hie_file"                                         }            ; let ictxt = hsc_IC hsc_env@@ -259,9 +268,7 @@                myCoreToStgExpr (hsc_logger hsc_env)                                (hsc_dflags hsc_env)                                ictxt-#if MIN_VERSION_ghc(9,3,0)                                True -- for bytecode-#endif                                (icInteractiveModule ictxt)                                iNTERACTIVELoc                                prepd_expr@@ -271,6 +278,9 @@                        (icInteractiveModule ictxt)                        stg_expr                        [] Nothing+#if MIN_VERSION_ghc(9,11,0)+                       [] -- spt_entries+#endif              -- Exclude wired-in names because we may not have read             -- their interface files, so getLinkDeps will fail@@ -279,11 +289,7 @@              -- Find the linkables for the modules we need            ; let needed_mods = mkUniqSet [-#if MIN_VERSION_ghc(9,3,0)                                            mod -- We need the whole module for 9.4 because of multiple home units modules may have different unit ids-#else-                                           moduleName mod -- On <= 9.2, just the name is enough because all unit ids will be the same-#endif                                           | n <- concatMap (uniqDSetToList . bcoFreeNames) $ bc_bcos bcos                                          , not (isWiredInName n) -- Exclude wired-in names@@ -291,51 +297,33 @@                                          , moduleUnitId mod `elem` home_unit_ids -- Only care about stuff from the home package set                                          ]                  home_unit_ids =-#if MIN_VERSION_ghc(9,3,0)                     map fst (hugElts $ hsc_HUG hsc_env)-#else-                    [homeUnitId_ dflags]-#endif                  mods_transitive = getTransitiveMods hsc_env needed_mods                   -- If we don't support multiple home units, ModuleNames are sufficient because all the units will be the same                  mods_transitive_list =-#if MIN_VERSION_ghc(9,3,0)                                          mapMaybe nodeKeyToInstalledModule $ Set.toList mods_transitive-#else-                                        -- Non det OK as we will put it into maps later anyway-                                         map (Compat.installedModule (homeUnitId_ dflags)) $ nonDetEltsUniqSet mods_transitive-#endif -#if MIN_VERSION_ghc(9,3,0)-           ; moduleLocs <- readIORef (fcModuleCache $ hsc_FC hsc_env)-#else-           ; moduleLocs <- readIORef (hsc_FC hsc_env)-#endif-           ; lbs <- getLinkables [toNormalizedFilePath' file+           ; moduleLocs <- getModuleGraph+           ; lbs <- getLinkables [file                                  | installedMod <- mods_transitive_list-                                 , let ifr = fromJust $ lookupInstalledModuleEnv moduleLocs installedMod-                                       file = case ifr of-                                         InstalledFound loc _ ->-                                           fromJust $ ml_hs_file loc-                                         _ -> panic "hscCompileCoreExprHook: module not found"+                                 , let file = fromJust $ lookupModuleFile (installedMod { moduleUnit = RealUnit (Definite $ moduleUnit installedMod) }) moduleLocs                                  ]            ; let hsc_env' = loadModulesHome (map linkableHomeMod lbs) hsc_env -#if MIN_VERSION_ghc(9,3,0)              {- load it -}-           ; (fv_hvs, lbss, pkgs) <- loadDecls (hscInterp hsc_env') hsc_env' srcspan bcos-           ; let hval = ((expectJust "hscCompileCoreExpr'" $ lookup (idName binding_id) fv_hvs), lbss, pkgs)+#if MIN_VERSION_ghc(9,11,0)+           ; bco_time <- getCurrentTime+           ; (fv_hvs, lbss, pkgs) <- loadDecls (hscInterp hsc_env') hsc_env' srcspan $+                Linkable bco_time (icInteractiveModule ictxt) $ NE.singleton $ BCOs bcos #else-             {- load it -}-           ; fv_hvs <- loadDecls (hscInterp hsc_env') hsc_env' srcspan bcos-           ; let hval = expectJust "hscCompileCoreExpr'" $ lookup (idName binding_id) fv_hvs+           ; (fv_hvs, lbss, pkgs) <- loadDecls (hscInterp hsc_env') hsc_env' srcspan bcos #endif+           ; let hval = (expectJust "hscCompileCoreExpr'" $ lookup (idName binding_id) fv_hvs, lbss, pkgs)             ; modifyIORef' var (flip extendModuleEnvList [(mi_module $ hm_iface hm, linkableHash lb) | lb <- lbs, let hm = linkableHomeMod lb])            ; return hval } -#if MIN_VERSION_ghc(9,3,0)     -- TODO: support backpack     nodeKeyToInstalledModule :: NodeKey -> Maybe InstalledModule     -- We shouldn't get boot files here, but to be safe, never map them to an installed module@@ -346,28 +334,13 @@     nodeKeyToInstalledModule _ = Nothing     moduleToNodeKey :: Module -> NodeKey     moduleToNodeKey mod = NodeKey_Module $ ModNodeKeyWithUid (GWIB (moduleName mod) NotBoot) (moduleUnitId mod)-#endif      -- Compute the transitive set of linkables required     getTransitiveMods hsc_env needed_mods-#if MIN_VERSION_ghc(9,3,0)       = Set.unions (Set.fromList (map moduleToNodeKey mods) : [ dep | m <- mods                                                               , Just dep <- [Map.lookup (moduleToNodeKey m) (mgTransDeps (hsc_mod_graph hsc_env))]                                                               ])       where mods = nonDetEltsUniqSet needed_mods -- OK because we put them into a set immediately after-#else-      = go emptyUniqSet needed_mods-      where-        hpt = hsc_HPT hsc_env-        go seen new-          | isEmptyUniqSet new = seen-          | otherwise = go seen' new'-            where-              seen' = seen `unionUniqSets` new-              new'  = new_deps `minusUniqSet` seen'-              new_deps = unionManyUniqSets [ mkUniqSet $ getDependentMods $ hm_iface mod_info-                                           | mod_info <- eltsUDFM $ udfmIntersectUFM hpt (getUniqSet new)]-#endif      -- | Add a Hook to the DynFlags which captures and returns the     -- typechecked splices before they are run. This information@@ -408,12 +381,12 @@   let ms = pm_mod_summary pmod       hsc_env_tmp = hscSetFlags (ms_hspp_opts ms) hsc_env -  ((tc_gbl_env', mrn_info), splices, mod_env)+  (((tc_gbl_env', mrn_info), warning_messages), splices, mod_env)       <- captureSplicesAndDeps tc_helpers hsc_env_tmp $ \hscEnvTmp ->-             do  hscTypecheckRename hscEnvTmp ms $-                          HsParsedModule { hpm_module = parsedSource pmod,-                                           hpm_src_files = pm_extra_src_files pmod,-                                           hpm_annotations = pm_annotations pmod }+             do  hscTypecheckRenameWithDiagnostics hscEnvTmp ms $+                          HsParsedModule { hpm_module = parsedSource pmod+                                         , hpm_src_files = pm_extra_src_files pmod+                                         }   let rn_info = case mrn_info of         Just x  -> x         Nothing -> error "no renamed info tcRnModule"@@ -422,7 +395,7 @@       mod_env_anns = map (\(mod, hash) -> Annotation (ModuleTarget mod) $ toSerialized BS.unpack hash)                          (moduleEnvToList mod_env)       tc_gbl_env = tc_gbl_env' { tcg_ann_env = extendAnnEnvList (tcg_ann_env tc_gbl_env') mod_env_anns }-  pure (TcModuleResult pmod rn_info tc_gbl_env splices False mod_env)+  pure (TcModuleResult pmod rn_info tc_gbl_env splices False mod_env warning_messages)   -- Note [Clearing mi_globals after generating an iface]@@ -442,12 +415,8 @@ -- HLS. To avoid GHC from pessimising HLS, we filter out certain dependency information -- that we track ourselves. See also Note [Recompilation avoidance in the presence of TH] filterUsages :: [Usage] -> [Usage]-#if MIN_VERSION_ghc(9,3,0) filterUsages = filter $ \case UsageHomeModuleInterface{} -> False                               _ -> True-#else-filterUsages = id-#endif  -- | Mitigation for https://gitlab.haskell.org/ghc/ghc/-/issues/22744 -- Important to do this immediately after reading the unit before@@ -473,7 +442,14 @@   details <- makeSimpleDetails hsc_env_tmp tcGblEnv   sf <- finalSafeMode (ms_hspp_opts ms) tcGblEnv   iface' <- mkIfaceTc hsc_env_tmp sf details ms Nothing tcGblEnv-  let iface = iface' { mi_globals = Nothing, mi_usages = filterUsages (mi_usages iface') } -- See Note [Clearing mi_globals after generating an iface]+  -- See Note [Clearing mi_globals after generating an iface]+  let iface = iface'+#if MIN_VERSION_ghc(9,11,0)+                & set_mi_top_env Nothing+                & set_mi_usages (filterUsages (mi_usages iface'))+#else+                { mi_globals = Nothing, mi_usages = filterUsages (mi_usages iface') }+#endif   pure $! mkHiFileResult ms iface details (tmrRuntimeModules tcm) Nothing  mkHiFileResultCompile@@ -498,8 +474,9 @@                                               (cg_binds guts) #endif                                               details-#if MIN_VERSION_ghc(9,3,0)                                               ms+#if MIN_VERSION_ghc(9,11,0)+                                              (tcg_import_decls (tmrTypechecked tcm)) #endif                                               simplified_guts @@ -507,7 +484,17 @@ #if MIN_VERSION_ghc(9,4,2)                     Nothing #endif-  let final_iface = final_iface' {mi_globals = Nothing, mi_usages = filterUsages (mi_usages final_iface')} -- See Note [Clearing mi_globals after generating an iface]+#if MIN_VERSION_ghc(9,11,0)+                    NoStubs []+#endif+  -- See Note [Clearing mi_globals after generating an iface]+  let final_iface = final_iface'+#if MIN_VERSION_ghc(9,11,0)+                      & set_mi_top_env Nothing+                      & set_mi_usages (filterUsages (mi_usages final_iface'))+#else+                      {mi_globals = Nothing, mi_usages = filterUsages (mi_usages final_iface')}+#endif    -- Write the core file now   core_file <- do@@ -515,7 +502,7 @@             core_file = codeGutsToCoreFile iface_hash guts             iface_hash = getModuleHash final_iface         core_hash1 <- atomicFileWrite se core_fp $ \fp ->-          writeBinCoreFile fp core_file+          writeBinCoreFile (hsc_dflags session) fp core_file         -- We want to drop references to guts and read in a serialized, compact version         -- of the core file from disk (as it is deserialised lazily)         -- This is because we don't want to keep the guts in memory for every file in@@ -552,17 +539,9 @@        -- Run corePrep first as we want to test the final version of the program that will       -- get translated to STG/Bytecode-#if MIN_VERSION_ghc(9,3,0)       prepd_binds-#else-      (prepd_binds , _)-#endif         <- corePrep unprep_binds data_tycons-#if MIN_VERSION_ghc(9,3,0)       prepd_binds'-#else-      (prepd_binds', _)-#endif         <- corePrep unprep_binds' data_tycons       let binds  = noUnfoldings $ (map flattenBinds . (:[])) prepd_binds           binds' = noUnfoldings $ (map flattenBinds . (:[])) prepd_binds'@@ -599,8 +578,14 @@     source = "compile"     catchErrs x = x `catches`       [ Handler $ return . (,Nothing) . diagFromGhcException source dflags-      , Handler $ return . (,Nothing) . diagFromString source DiagnosticSeverity_Error (noSpan "<internal>")-      . (("Error during " ++ T.unpack source) ++) . show @SomeException+      , Handler $ \diag ->+          return+            ( diagFromString+                source DiagnosticSeverity_Error (noSpan "<internal>")+                ("Error during " ++ T.unpack source ++ show @SomeException diag)+                Nothing+            , Nothing+            )       ]  -- | Whether we should run the -O0 simplifier when generating core.@@ -659,11 +644,7 @@                       let env' = tweak (hscSetFlags (ms_hspp_opts summary) session)                           target = platformDefaultBackend (hsc_dflags env')                           newFlags = setBackend target $ updOptLevel 0 $ setOutputFile-#if MIN_VERSION_ghc(9,3,0)                               (Just dot_o)-#else-                              dot_o-#endif                             $ hsc_dflags env'                           session' = hscSetFlags newFlags session #if MIN_VERSION_ghc(9,4,2)@@ -674,18 +655,16 @@                                 (ms_location summary)                                 fp                       obj <- compileFile session' driverNoStop (outputFilename, Just (As False))-#if MIN_VERSION_ghc(9,3,0)                       case obj of                         Nothing -> throwGhcExceptionIO $ Panic "compileFile didn't generate object code"                         Just x -> pure x-#else-                      return obj-#endif-              let unlinked = DotO dot_o_fp               -- Need time to be the modification time for recompilation checking               t <- liftIO $ getModificationTime dot_o_fp-              let linkable = LM t mod [unlinked]-+#if MIN_VERSION_ghc(9,11,0)+              let linkable = Linkable t mod (pure $ DotO dot_o_fp ModuleObject)+#else+              let linkable = LM t mod [DotO dot_o_fp]+#endif               pure (map snd warnings, linkable)  newtype CoreFileTime = CoreFileTime UTCTime@@ -694,15 +673,22 @@ generateByteCode (CoreFileTime time) hscEnv summary guts = do     fmap (either (, Nothing) (second Just)) $           catchSrcErrors (hsc_dflags hscEnv) "bytecode" $ do+#if MIN_VERSION_ghc(9,11,0)+              (warnings, (_, bytecode)) <-+#else               (warnings, (_, bytecode, sptEntries)) <-+#endif                 withWarnings "bytecode" $ \_tweak -> do                       let session = _tweak (hscSetFlags (ms_hspp_opts summary) hscEnv)                           -- TODO: maybe settings ms_hspp_opts is unnecessary?                           summary' = summary { ms_hspp_opts = hsc_dflags session }                       hscInteractive session (mkCgInteractiveGuts guts)                                 (ms_location summary')-              let unlinked = BCOs bytecode sptEntries-              let linkable = LM time (ms_mod summary) [unlinked]+#if MIN_VERSION_ghc(9,11,0)+              let linkable = Linkable time (ms_mod summary) (pure $ BCOs bytecode)+#else+              let linkable = LM time (ms_mod summary) [BCOs bytecode sptEntries]+#endif               pure (map snd warnings, linkable)  demoteTypeErrorsToWarnings :: ParsedModule -> ParsedModule@@ -725,34 +711,23 @@ update_pm_mod_summary up pm =   pm{pm_mod_summary = up $ pm_mod_summary pm} -#if MIN_VERSION_ghc(9,3,0) unDefer :: (Maybe DiagnosticReason, FileDiagnostic) -> (Bool, FileDiagnostic) unDefer (Just (WarningWithFlag Opt_WarnDeferredTypeErrors)         , fd) = (True, upgradeWarningToError fd) unDefer (Just (WarningWithFlag Opt_WarnTypedHoles)                 , fd) = (True, upgradeWarningToError fd) unDefer (Just (WarningWithFlag Opt_WarnDeferredOutOfScopeVariables), fd) = (True, upgradeWarningToError fd)-#else-unDefer :: (WarnReason, FileDiagnostic) -> (Bool, FileDiagnostic)-unDefer (Reason Opt_WarnDeferredTypeErrors         , fd) = (True, upgradeWarningToError fd)-unDefer (Reason Opt_WarnTypedHoles                 , fd) = (True, upgradeWarningToError fd)-unDefer (Reason Opt_WarnDeferredOutOfScopeVariables, fd) = (True, upgradeWarningToError fd)-#endif unDefer ( _                                        , fd) = (False, fd)  upgradeWarningToError :: FileDiagnostic -> FileDiagnostic-upgradeWarningToError (nfp, sh, fd) =-  (nfp, sh, fd{_severity = Just DiagnosticSeverity_Error, _message = warn2err $ _message fd}) where+upgradeWarningToError =+  fdLspDiagnosticL %~ \diag -> diag {_severity = Just DiagnosticSeverity_Error, _message = warn2err $ _message diag}+  where   warn2err :: T.Text -> T.Text   warn2err = T.intercalate ": error:" . T.splitOn ": warning:" -#if MIN_VERSION_ghc(9,3,0) hideDiag :: DynFlags -> (Maybe DiagnosticReason, FileDiagnostic) -> (Maybe DiagnosticReason, FileDiagnostic)-hideDiag originalFlags (w@(Just (WarningWithFlag warning)), (nfp, _sh, fd))-#else-hideDiag :: DynFlags -> (WarnReason, FileDiagnostic) -> (WarnReason, FileDiagnostic)-hideDiag originalFlags (w@(Reason warning), (nfp, _sh, fd))-#endif+hideDiag originalFlags (w@(Just (WarningWithFlag warning)), fd)   | not (wopt warning originalFlags)-  = (w, (nfp, HideDiag, fd))+  = (w, fd { fdShouldShowDiagnostic = HideDiag }) hideDiag _originalFlags t = t  -- | Warnings which lead to a diagnostic tag@@ -773,29 +748,21 @@     ]  -- | Add a unnecessary/deprecated tag to the required diagnostics.-#if MIN_VERSION_ghc(9,3,0) tagDiag :: (Maybe DiagnosticReason, FileDiagnostic) -> (Maybe DiagnosticReason, FileDiagnostic)-#else-tagDiag :: (WarnReason, FileDiagnostic) -> (WarnReason, FileDiagnostic)-#endif  #if MIN_VERSION_ghc(9,7,0)-tagDiag (w@(Just (WarningWithCategory cat)), (nfp, sh, fd))+tagDiag (w@(Just (WarningWithCategory cat)), fd)   | cat == defaultWarningCategory -- default warning category is for deprecations-  = (w, (nfp, sh, fd { _tags = Just $ DiagnosticTag_Deprecated : concat (_tags fd) }))-tagDiag (w@(Just (WarningWithFlags warnings)), (nfp, sh, fd))+  = (w, fd & fdLspDiagnosticL %~ \diag -> diag { _tags = Just $ DiagnosticTag_Deprecated : concat (_tags diag) })+tagDiag (w@(Just (WarningWithFlags warnings)), fd)   | tags <- mapMaybe requiresTag (toList warnings)-  = (w, (nfp, sh, fd { _tags = Just $ tags ++ concat (_tags fd) }))-#elif MIN_VERSION_ghc(9,3,0)-tagDiag (w@(Just (WarningWithFlag warning)), (nfp, sh, fd))-  | Just tag <- requiresTag warning-  = (w, (nfp, sh, fd { _tags = Just $ tag : concat (_tags fd) }))+  = (w, fd & fdLspDiagnosticL %~ \diag -> diag { _tags = Just $ tags ++ concat (_tags diag) }) #else-tagDiag (w@(Reason warning), (nfp, sh, fd))+tagDiag (w@(Just (WarningWithFlag warning)), fd)   | Just tag <- requiresTag warning-  = (w, (nfp, sh, fd { _tags = Just $ tag : concat (_tags fd) }))+  = (w, fd & fdLspDiagnosticL %~ \diag -> diag { _tags = Just $ tag : concat (_tags diag) }) #endif-  where+    where     requiresTag :: WarningFlag -> Maybe DiagnosticTag #if !MIN_VERSION_ghc(9,7,0)     -- doesn't exist on 9.8, we use WarningWithCategory instead@@ -822,33 +789,43 @@   (write tempFilePath >>= \x -> renameFile tempFilePath targetPath >> atomically (resetInterfaceStore se (toNormalizedFilePath' targetPath)) >> pure x)     `onException` cleanUp -generateHieAsts :: HscEnv -> TcModuleResult -> IO ([FileDiagnostic], Maybe (HieASTs Type))+generateHieAsts :: HscEnv -> TcModuleResult+#if MIN_VERSION_ghc(9,11,0)+                -> IO ([FileDiagnostic], Maybe (HieASTs Type, NameEntityInfo))+#else+                -> IO ([FileDiagnostic], Maybe (HieASTs Type))+#endif generateHieAsts hscEnv tcm =   handleGenerationErrors' dflags "extended interface generation" $ runHsc hscEnv $ do     -- These varBinds use unitDataConId but it could be anything as the id name is not used     -- during the hie file generation process. It's a workaround for the fact that the hie modules     -- don't export an interface which allows for additional information to be added to hie files.-    let fake_splice_binds = Util.listToBag (map (mkVarBind unitDataConId) (spliceExpressions $ tmrTopLevelSplices tcm))+    let fake_splice_binds =+#if !MIN_VERSION_ghc(9,11,0)+                            Util.listToBag $+#endif+                            map (mkVarBind unitDataConId) (spliceExpressions $ tmrTopLevelSplices tcm)         real_binds = tcg_binds $ tmrTypechecked tcm+        all_binds =+#if MIN_VERSION_ghc(9,11,0)+          fake_splice_binds ++ real_binds+#else+          fake_splice_binds `Util.unionBags` real_binds+#endif         ts = tmrTypechecked tcm :: TcGblEnv         top_ev_binds = tcg_ev_binds ts :: Util.Bag EvBind         insts = tcg_insts ts :: [ClsInst]         tcs = tcg_tcs ts :: [TyCon]-    run ts $-#if MIN_VERSION_ghc(9,3,0)-      pure $ Just $-#else-      Just <$>+        hie_asts = GHC.enrichHie all_binds (tmrRenamed tcm) top_ev_binds insts tcs++    pure $ Just $+#if MIN_VERSION_ghc(9,11,0)+      hie_asts (tcg_type_env ts)+#elif MIN_VERSION_ghc(9,3,0)+      hie_asts #endif-          GHC.enrichHie (fake_splice_binds `Util.unionBags` real_binds) (tmrRenamed tcm) top_ev_binds insts tcs   where     dflags = hsc_dflags hscEnv-    run _ts = -- ts is only used in GHC 9.2-#if !MIN_VERSION_ghc(9,3,0)-        fmap (join . snd) . liftIO . initDs hscEnv _ts-#else-        id-#endif  spliceExpressions :: Splices -> [LHsExpr GhcTc] spliceExpressions Splices{..} =@@ -890,7 +867,6 @@ -- indexHieFile :: ShakeExtras -> ModSummary -> NormalizedFilePath -> Util.Fingerprint -> Compat.HieFile -> IO () indexHieFile se mod_summary srcPath !hash hf = do- IdeOptions{optProgressStyle} <- getIdeOptionsIO se  atomically $ do   pending <- readTVar indexPending   case HashMap.lookup srcPath pending of@@ -911,69 +887,14 @@         unless newerScheduled $ do           -- Using bracket, so even if an exception happen during withHieDb call,           -- the `post` (which clean the progress indicator) will still be called.-          bracket_ (pre optProgressStyle) post $+          bracket_ pre post $             withHieDb (\db -> HieDb.addRefsFromLoaded db targetPath (HieDb.RealFile $ fromNormalizedFilePath srcPath) hash hf')   where     mod_location    = ms_location mod_summary     targetPath      = Compat.ml_hie_file mod_location     HieDbWriter{..} = hiedbWriter se -    -- Get a progress token to report progress and update it for the current file-    pre style = do-      tok <- modifyVar indexProgressToken $ fmap dupe . \case-        x@(Just _) -> pure x-        -- Create a token if we don't already have one-        Nothing -> do-          case lspEnv se of-            Nothing -> pure Nothing-            Just env -> LSP.runLspT env $ do-              u <- LSP.ProgressToken . LSP.InR . T.pack . show . hashUnique <$> liftIO Unique.newUnique-              -- TODO: Wait for the progress create response to use the token-              _ <- LSP.sendRequest LSP.SMethod_WindowWorkDoneProgressCreate (LSP.WorkDoneProgressCreateParams u) (const $ pure ())-              LSP.sendNotification LSP.SMethod_Progress $ LSP.ProgressParams u $-                toJSON $ LSP.WorkDoneProgressBegin-                  { _kind = LSP.AString @"begin"-                  ,  _title = "Indexing"-                  , _cancellable = Nothing-                  , _message = Nothing-                  , _percentage = Nothing-                  }-              pure (Just u)--      (!done, !remaining) <- atomically $ do-        done <- readTVar indexCompleted-        remaining <- HashMap.size <$> readTVar indexPending-        pure (done, remaining)-      let-        progressFrac :: Double-        progressFrac = fromIntegral done / fromIntegral (done + remaining)-        progressPct :: LSP.UInt-        progressPct = floor $ 100 * progressFrac--      whenJust (lspEnv se) $ \env -> whenJust tok $ \token -> LSP.runLspT env $-        LSP.sendNotification LSP.SMethod_Progress $ LSP.ProgressParams token $-          toJSON $-            case style of-                Percentage -> LSP.WorkDoneProgressReport-                    { _kind = LSP.AString @"report"-                    , _cancellable = Nothing-                    , _message = Nothing-                    , _percentage = Just progressPct-                    }-                Explicit -> LSP.WorkDoneProgressReport-                    { _kind = LSP.AString @"report"-                    , _cancellable = Nothing-                    , _message = Just $-                        T.pack " (" <> T.pack (show done) <> "/" <> T.pack (show $ done + remaining) <> ")..."-                    , _percentage = Nothing-                    }-                NoProgress -> LSP.WorkDoneProgressReport-                  { _kind = LSP.AString @"report"-                  , _cancellable = Nothing-                  , _message = Nothing-                  , _percentage = Nothing-                  }-+    pre = progressUpdate indexProgressReporting ProgressStarted     -- Report the progress once we are done indexing this file     post = do       mdone <- atomically $ do@@ -988,20 +909,16 @@         when (coerce $ ideTesting se) $           LSP.sendNotification (LSP.SMethod_CustomMethod (Proxy @"ghcide/reference/ready")) $             toJSON $ fromNormalizedFilePath srcPath-      whenJust mdone $ \done ->-        modifyVar_ indexProgressToken $ \tok -> do-          whenJust (lspEnv se) $ \env -> LSP.runLspT env $-            whenJust tok $ \token ->-              LSP.sendNotification LSP.SMethod_Progress  $ LSP.ProgressParams token $-                toJSON $-                LSP.WorkDoneProgressEnd-                  { _kind = LSP.AString @"end"-                  , _message = Just $ "Finished indexing " <> T.pack (show done) <> " files"-                  }-          -- We are done with the current indexing cycle, so destroy the token-          pure Nothing+      whenJust mdone $ \_ -> progressUpdate indexProgressReporting ProgressCompleted -writeAndIndexHieFile :: HscEnv -> ShakeExtras -> ModSummary -> NormalizedFilePath -> [GHC.AvailInfo] -> HieASTs Type -> BS.ByteString -> IO [FileDiagnostic]+writeAndIndexHieFile+  :: HscEnv -> ShakeExtras -> ModSummary -> NormalizedFilePath -> [GHC.AvailInfo]+#if MIN_VERSION_ghc(9,11,0)+  -> (HieASTs Type, NameEntityInfo)+#else+  -> HieASTs Type+#endif+  -> BS.ByteString -> IO [FileDiagnostic] writeAndIndexHieFile hscEnv se mod_summary srcPath exports ast source =   handleGenerationErrors dflags "extended interface write/compression" $ do     hf <- runHsc hscEnv $@@ -1028,16 +945,25 @@ handleGenerationErrors dflags source action =   action >> return [] `catches`     [ Handler $ return . diagFromGhcException source dflags-    , Handler $ return . diagFromString source DiagnosticSeverity_Error (noSpan "<internal>")-    . (("Error during " ++ T.unpack source) ++) . show @SomeException+    , Handler $ \(exception :: SomeException) -> return $+        diagFromString+          source DiagnosticSeverity_Error (noSpan "<internal>")+          ("Error during " ++ T.unpack source ++ show exception)+          Nothing     ]  handleGenerationErrors' :: DynFlags -> T.Text -> IO (Maybe a) -> IO ([FileDiagnostic], Maybe a) handleGenerationErrors' dflags source action =   fmap ([],) action `catches`     [ Handler $ return . (,Nothing) . diagFromGhcException source dflags-    , Handler $ return . (,Nothing) . diagFromString source DiagnosticSeverity_Error (noSpan "<internal>")-    . (("Error during " ++ T.unpack source) ++) . show @SomeException+    , Handler $ \(exception :: SomeException) ->+        return+          ( diagFromString+              source DiagnosticSeverity_Error (noSpan "<internal>")+              ("Error during " ++ T.unpack source ++ show exception)+              Nothing+          , Nothing+          )     ]  @@ -1046,9 +972,46 @@ -- Add the current ModSummary to the graph, along with the -- HomeModInfo's of all direct dependencies (by induction hypothesis all -- transitive dependencies will be contained in envs)-mergeEnvs :: HscEnv -> ModuleGraph -> ModSummary -> [HomeModInfo] -> [HscEnv] -> IO HscEnv-mergeEnvs env mg ms extraMods envs = do-#if MIN_VERSION_ghc(9,3,0)+mergeEnvs :: HscEnv+          -> ModuleGraph+          -> DependencyInformation+          -> ModSummary+          -> [HomeModInfo]+          -> [HscEnv]+          -> IO HscEnv+mergeEnvs env mg dep_info ms extraMods envs = do+#if MIN_VERSION_ghc(9,11,0)+    return $! loadModulesHome extraMods $+      let newHug = foldl' mergeHUG (hsc_HUG env) (map hsc_HUG envs) in+      (hscUpdateHUG (const newHug) env){+          hsc_mod_graph = mg,+          hsc_FC = (hsc_FC env)+            { addToFinderCache = \gwib@(GWIB im _) val ->+                  if moduleUnit im `elem` hsc_all_home_unit_ids env+                  then pure ()+                  else addToFinderCache (hsc_FC env) gwib val+            , lookupFinderCache = \gwib@(GWIB im _) ->+                  if moduleUnit im `elem` hsc_all_home_unit_ids env+                  then case lookupModuleFile (im { moduleUnit = RealUnit (Definite $ moduleUnit im) }) dep_info of+                         Nothing -> pure Nothing+                         Just fs -> let ml = fromJust $ do+                                              id <- lookupPathToId (depPathIdMap dep_info) fs+                                              artifactModLocation (idToModLocation (depPathIdMap dep_info) id)+                                    in pure $ Just $ InstalledFound ml im+                  else lookupFinderCache (hsc_FC env) gwib+            }+      }++    where+        mergeHUG (UnitEnvGraph a) (UnitEnvGraph b) = UnitEnvGraph $ Map.unionWith mergeHUE a b+        mergeHUE a b = a { homeUnitEnv_hpt = mergeUDFM (homeUnitEnv_hpt a) (homeUnitEnv_hpt b) }+        mergeUDFM = plusUDFM_C combineModules++        combineModules a b+          | HsSrcFile <- mi_hsc_src (hm_iface a) = a+          | otherwise = b++#elif MIN_VERSION_ghc(9,3,0)     let im  = Compat.installedModule (toUnitId $ moduleUnit $ ms_mod ms) (moduleName (ms_mod ms))         ifr = InstalledFound (ms_location ms) im         curFinderCache = Compat.extendInstalledModuleEnv Compat.emptyInstalledModuleEnv im ifr@@ -1082,33 +1045,9 @@           fcModules' <- newIORef $! foldl' (plusInstalledModuleEnv combineModuleLocations) cur fcModules           fcFiles' <- newIORef $! Map.unions fcFiles           pure $ FinderCache fcModules' fcFiles'--#else-    prevFinderCache <- concatFC <$> mapM (readIORef . hsc_FC) envs-    let im  = Compat.installedModule (toUnitId $ moduleUnit $ ms_mod ms) (moduleName (ms_mod ms))-        ifr = InstalledFound (ms_location ms) im-    newFinderCache <- newIORef $! Compat.extendInstalledModuleEnv prevFinderCache im ifr-    return $! loadModulesHome extraMods $-      env{-          hsc_HPT = foldMapBy mergeUDFM emptyUDFM hsc_HPT envs,-          hsc_FC = newFinderCache,-          hsc_mod_graph = mg-      }--    where-        mergeUDFM = plusUDFM_C combineModules-        combineModules a b-          | HsSrcFile <- mi_hsc_src (hm_iface a) = a-          | otherwise = b-    -- required because 'FinderCache':-    --  1) doesn't have a 'Monoid' instance,-    --  2) is abstract and doesn't export constructors-    -- To work around this, we coerce to the underlying type-    -- To remove this, I plan to upstream the missing Monoid instance-        concatFC :: [FinderCache] -> FinderCache-        concatFC = unsafeCoerce (mconcat @(Map InstalledModule InstalledFindResult)) #endif + withBootSuffix :: HscSource -> ModLocation -> ModLocation withBootSuffix HsBootFile = addBootSuffixLocnOut withBootSuffix _          = id@@ -1152,24 +1091,16 @@           convImport (L _ i) = (-#if !MIN_VERSION_ghc(9,3,0)-                               fmap sl_fs-#endif                                (ideclPkgQual i)                              , reLoc $ ideclName i)          msrImports = implicit_imports ++ imps -#if MIN_VERSION_ghc(9,3,0)         rn_pkg_qual = renameRawPkgQual (hsc_unit_env ppEnv)         rn_imps = fmap (\(pk, lmn@(L _ mn)) -> (rn_pkg_qual mn pk, lmn))         srcImports = rn_imps $ map convImport src_idecls         textualImports = rn_imps $ map convImport (implicit_imports ++ ordinary_imps)         ghc_prim_import = not (null _ghc_prim_imports)-#else-        srcImports = map convImport src_idecls-        textualImports = map convImport (implicit_imports ++ ordinary_imps)-#endif       -- Force bits that might keep the string buffer and DynFlags alive unnecessarily@@ -1185,18 +1116,14 @@      let modl = mkHomeModule (hscHomeUnit ppEnv) mod         sourceType = if "-boot" `isSuffixOf` takeExtension fp then HsBootFile else HsSrcFile-        msrModSummary2 =+        msrModSummary =             ModSummary                 { ms_mod          = modl                 , ms_hie_date     = Nothing-#if MIN_VERSION_ghc(9,3,0)                 , ms_dyn_obj_date    = Nothing                 , ms_ghc_prim_import = ghc_prim_import                 , ms_hs_hash      = _src_hash -#else-                , ms_hs_date      = _modTime-#endif                 , ms_hsc_src      = sourceType                 -- The contents are used by the GetModSummary rule                 , ms_hspp_buf     = Just contents@@ -1210,8 +1137,8 @@                 , ms_textual_imps = textualImports                 } -    msrFingerprint <- liftIO $ computeFingerprint opts msrModSummary2-    (msrModSummary, msrHscEnv) <- liftIO $ initPlugins ppEnv msrModSummary2+    msrFingerprint <- liftIO $ computeFingerprint opts msrModSummary+    msrHscEnv <- liftIO $ Loader.initializePlugins (hscSetFlags (ms_hspp_opts msrModSummary) ppEnv)     return ModSummaryResult{..}     where         -- Compute a fingerprint from the contents of `ModSummary`,@@ -1221,19 +1148,24 @@                   put $ Util.uniq $ moduleNameFS $ moduleName ms_mod                   forM_ (ms_srcimps ++ ms_textual_imps) $ \(mb_p, m) -> do                     put $ Util.uniq $ moduleNameFS $ unLoc m-#if MIN_VERSION_ghc(9,3,0)                     case mb_p of-                      G.NoPkgQual -> pure ()+                      G.NoPkgQual    -> pure ()                       G.ThisPkg uid  -> put $ getKey $ getUnique uid                       G.OtherPkg uid -> put $ getKey $ getUnique uid-#else-                    whenJust mb_p $ put . Util.uniq-#endif             return $! Util.fingerprintFingerprints $                     [ Util.fingerprintString fp                     , fingerPrintImports+                    , modLocationFingerprint ms_location                     ] ++ map Util.fingerprintString opts +        modLocationFingerprint :: ModLocation -> Util.Fingerprint+        modLocationFingerprint ModLocation{..} = Util.fingerprintFingerprints $+            Util.fingerprintString <$> [ fromMaybe "" ml_hs_file+                                         , ml_hi_file+                                         , ml_dyn_hi_file+                                         , ml_obj_file+                                         , ml_dyn_obj_file+                                         , ml_hie_file]  -- | Parse only the module header parseHeader@@ -1250,7 +1182,7 @@    let loc  = mkRealSrcLoc (Util.mkFastString filename) 1 1    case unP Compat.parseHeader (initParserState (initParserOpts dflags) contents loc) of      PFailedWithErrorMessages msgs ->-        throwE $ diagFromErrMsgs sourceParser dflags $ msgs dflags+        throwE $ diagFromGhcErrorMessages sourceParser dflags $ msgs dflags      POk pst rdr_module -> do         let (warns, errs) = renderMessages $ getPsMessages pst @@ -1264,9 +1196,9 @@         -- errors are those from which a parse tree just can't         -- be produced.         unless (null errs) $-            throwE $ diagFromErrMsgs sourceParser dflags errs+            throwE $ diagFromGhcErrorMessages sourceParser dflags errs -        let warnings = diagFromErrMsgs sourceParser dflags warns+        let warnings = diagFromGhcErrorMessages sourceParser dflags warns         return (warnings, rdr_module)  -- | Given a buffer, flags, and file path, produce a@@ -1283,20 +1215,29 @@        dflags = ms_hspp_opts ms        contents = fromJust $ ms_hspp_buf ms    case unP Compat.parseModule (initParserState (initParserOpts dflags) contents loc) of-     PFailedWithErrorMessages msgs -> throwE $ diagFromErrMsgs sourceParser dflags $ msgs dflags+     PFailedWithErrorMessages msgs ->+       throwE $ diagFromGhcErrorMessages sourceParser dflags $ msgs dflags      POk pst rdr_module ->          let-             hpm_annotations = mkApiAnns pst              psMessages = getPsMessages pst          in            do-               let IdePreprocessedSource preproc_warns errs parsed = customPreprocessor rdr_module+               let IdePreprocessedSource preproc_warns preproc_errs parsed = customPreprocessor rdr_module+               let attachNoStructuredError (span, msg) = (span, msg, Nothing) -               unless (null errs) $-                  throwE $ diagFromStrings sourceParser DiagnosticSeverity_Error errs+               unless (null preproc_errs) $+                  throwE $+                    diagFromStrings+                      sourceParser+                      DiagnosticSeverity_Error+                      (fmap attachNoStructuredError preproc_errs) -               let preproc_warnings = diagFromStrings sourceParser DiagnosticSeverity_Warning preproc_warns-               (parsed', msgs) <- liftIO $ applyPluginsParsedResultAction env ms hpm_annotations parsed psMessages+               let preproc_warning_file_diagnostics =+                     diagFromStrings+                      sourceParser+                      DiagnosticSeverity_Warning+                      (fmap attachNoStructuredError preproc_warns)+               (parsed', msgs) <- liftIO $ applyPluginsParsedResultAction env ms parsed psMessages                let (warns, errors) = renderMessages msgs                 -- Just because we got a `POk`, it doesn't mean there@@ -1309,8 +1250,7 @@                -- errors are those from which a parse tree just can't                -- be produced.                unless (null errors) $-                 throwE $ diagFromErrMsgs sourceParser dflags errors-+                 throwE $ diagFromGhcErrorMessages sourceParser dflags errors                 -- To get the list of extra source files, we take the list                -- that the parser gave us,@@ -1323,11 +1263,7 @@                --   - filter out the .hs/.lhs source filename if we have one                --                let n_hspp  = normalise filename-#if MIN_VERSION_ghc(9,3,0)                    TempDir tmp_dir = tmpDir dflags-#else-                   tmp_dir = tmpDir dflags-#endif                    srcs0 = nubOrd $ filter (not . (tmp_dir `isPrefixOf`))                                   $ filter (/= n_hspp)                                   $ map normalise@@ -1343,9 +1279,9 @@                -- filter them out:                srcs2 <- liftIO $ filterM doesFileExist srcs1 -               let pm = ParsedModule ms parsed' srcs2 hpm_annotations-                   warnings = diagFromErrMsgs sourceParser dflags warns-               pure (warnings ++ preproc_warnings, pm)+               let pm = ParsedModule ms parsed' srcs2+                   warnings = diagFromGhcErrorMessages sourceParser dflags warns+               pure (warnings ++ preproc_warning_file_diagnostics, pm)  loadHieFile :: Compat.NameCacheUpdater -> FilePath -> IO GHC.HieFile loadHieFile ncu f = do@@ -1420,6 +1356,7 @@   , old_value   :: Maybe (HiFileResult, FileVersion)   , get_file_version :: NormalizedFilePath -> m (Maybe FileVersion)   , get_linkable_hashes :: [NormalizedFilePath] -> m [BS.ByteString]+  , get_module_graph :: m DependencyInformation   , regenerate  :: Maybe LinkableType -> m ([FileDiagnostic], Maybe HiFileResult) -- ^ Action to regenerate an interface   } @@ -1474,14 +1411,9 @@         -- ncu and read_dflags are only used in GHC >= 9.4         let _ncu = hsc_NC sessionWithMsDynFlags             _read_dflags = hsc_dflags sessionWithMsDynFlags-#if MIN_VERSION_ghc(9,3,0)         read_result <- liftIO $ readIface _read_dflags _ncu mod iface_file-#else-        read_result <- liftIO $ initIfaceCheck (text "readIface") sessionWithMsDynFlags-                              $ readIface mod iface_file-#endif         case read_result of-          Util.Failed{} -> return Nothing+          Util.Failed{}        -> return Nothing           -- important to call `shareUsages` here before checkOldIface           -- consults `mi_usages`           Util.Succeeded iface -> return $ Just (shareUsages iface)@@ -1489,13 +1421,9 @@     -- If mb_old_iface is nothing then checkOldIface will load it for us     -- given that the source is unmodified     (recomp_iface_reqd, mb_checked_iface)-#if MIN_VERSION_ghc(9,3,0)       <- liftIO $ checkOldIface sessionWithMsDynFlags ms _old_iface >>= \case         UpToDateItem x -> pure (UpToDate, Just x)         OutOfDateItem reason x -> pure (NeedsRecompile reason, x)-#else-      <- liftIO $ checkOldIface sessionWithMsDynFlags ms _sourceMod mb_old_iface-#endif      let do_regenerate _reason = withTrace "regenerate interface" $ \setTag -> do           setTag "Module" $ moduleNameString $ moduleName mod@@ -1511,7 +1439,7 @@                    | not (mi_used_th iface) = emptyModuleEnv                    | otherwise = parseRuntimeDeps (md_anns details)              -- Peform the fine grained recompilation check for TH-             maybe_recomp <- checkLinkableDependencies session get_linkable_hashes runtime_deps+             maybe_recomp <- checkLinkableDependencies session get_linkable_hashes get_module_graph runtime_deps              case maybe_recomp of                Just msg -> do_regenerate msg                Nothing@@ -1548,20 +1476,10 @@ -- the runtime dependencies of the module, to check if any of them are out of date -- Hopefully 'runtime_deps' will be empty if the module didn't actually use TH -- See Note [Recompilation avoidance in the presence of TH]-checkLinkableDependencies :: MonadIO m => HscEnv -> ([NormalizedFilePath] -> m [BS.ByteString]) -> ModuleEnv BS.ByteString -> m (Maybe RecompileRequired)-checkLinkableDependencies hsc_env get_linkable_hashes runtime_deps = do-#if MIN_VERSION_ghc(9,3,0)-  moduleLocs <- liftIO $ readIORef (fcModuleCache $ hsc_FC hsc_env)-#else-  moduleLocs <- liftIO $ readIORef (hsc_FC hsc_env)-#endif-  let go (mod, hash) = do-        ifr <- lookupInstalledModuleEnv moduleLocs $ Compat.installedModule (toUnitId $ moduleUnit mod) (moduleName mod)-        case ifr of-          InstalledFound loc _ -> do-            hs <- ml_hs_file loc-            pure (toNormalizedFilePath' hs,hash)-          _ -> Nothing+checkLinkableDependencies :: MonadIO m => HscEnv -> ([NormalizedFilePath] -> m [BS.ByteString]) -> m DependencyInformation -> ModuleEnv BS.ByteString -> m (Maybe RecompileRequired)+checkLinkableDependencies hsc_env get_linkable_hashes get_module_graph runtime_deps = do+  graph <- get_module_graph+  let go (mod, hash) = (,hash) <$> lookupModuleFile mod graph       hs_files = mapM go (moduleEnvToList runtime_deps)   case hs_files of     Nothing -> error "invalid module graph"@@ -1575,27 +1493,16 @@  recompBecause :: String -> RecompileRequired recompBecause =-#if MIN_VERSION_ghc(9,3,0)                 NeedsRecompile .-#endif                 RecompBecause-#if MIN_VERSION_ghc(9,3,0)               . CustomReason-#endif -#if MIN_VERSION_ghc(9,3,0) data SourceModified = SourceModified | SourceUnmodified deriving (Eq, Ord, Show)-#endif  showReason :: RecompileRequired -> String-showReason UpToDate          = "UpToDate"-#if MIN_VERSION_ghc(9,3,0)-showReason (NeedsRecompile MustCompile)    = "MustCompile"-showReason (NeedsRecompile s) = printWithoutUniques s-#else-showReason MustCompile       = "MustCompile"-showReason (RecompBecause s) = s-#endif+showReason UpToDate                     = "UpToDate"+showReason (NeedsRecompile MustCompile) = "MustCompile"+showReason (NeedsRecompile s)           = printWithoutUniques s  mkDetailsFromIface :: HscEnv -> ModIface -> IO ModDetails mkDetailsFromIface session iface = do@@ -1610,11 +1517,7 @@       this_mod = mi_module iface   types_var <- newIORef (md_types details)   let hsc_env' = hscUpdateHPT act (session {-#if MIN_VERSION_ghc(9,3,0)         hsc_type_env_vars = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)])-#else-        hsc_type_env_var = Just (this_mod, types_var)-#endif         })   core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckCoreFile this_mod types_var core_file       -- Implicit binds aren't saved, so we need to regenerate them ourselves.@@ -1622,11 +1525,13 @@       tyCons = typeEnvTyCons (md_types details) #if MIN_VERSION_ghc(9,5,0)   -- In GHC 9.6, the implicit binds are tidied and part of core_binds-  pure $ CgGuts this_mod tyCons core_binds [] NoStubs [] mempty (emptyHpcInfo False) Nothing []-#elif MIN_VERSION_ghc(9,3,0)-  pure $ CgGuts this_mod tyCons (_implicit_binds ++ core_binds) [] NoStubs [] mempty (emptyHpcInfo False) Nothing []+  pure $ CgGuts this_mod tyCons core_binds [] NoStubs [] mempty+#if !MIN_VERSION_ghc(9,11,0)+                (emptyHpcInfo False)+#endif+                Nothing [] #else-  pure $ CgGuts this_mod tyCons (_implicit_binds ++ core_binds) NoStubs [] [] (emptyHpcInfo False) Nothing []+  pure $ CgGuts this_mod tyCons (_implicit_binds ++ core_binds) [] NoStubs [] mempty (emptyHpcInfo False) Nothing [] #endif  coreFileToLinkable :: LinkableType -> HscEnv -> ModSummary -> ModIface -> ModDetails -> CoreFile -> UTCTime -> IO ([FileDiagnostic], Maybe HomeModInfo)@@ -1643,45 +1548,23 @@ getDocsBatch   :: HscEnv   -> [Name]-#if MIN_VERSION_ghc(9,3,0)   -> IO [Either String (Maybe [HsDoc GhcRn], IntMap (HsDoc GhcRn))]-#else-  -> IO [Either String (Maybe HsDocString, IntMap HsDocString)]-#endif getDocsBatch hsc_env _names = do     res <- initIfaceLoad hsc_env $ forM _names $ \name ->         case nameModule_maybe name of             Nothing -> return (Left $ NameHasNoModule name)             Just mod -> do              ModIface {-#if MIN_VERSION_ghc(9,3,0)                         mi_docs = Just Docs{ docs_mod_hdr = mb_doc_hdr                                       , docs_decls = dmap                                       , docs_args = amap                                       }-#else-                        mi_doc_hdr = mb_doc_hdr-                      , mi_decl_docs = DeclDocMap dmap-                      , mi_arg_docs = ArgDocMap amap-#endif                       } <- loadSysInterface (text "getModuleInterface") mod-#if MIN_VERSION_ghc(9,3,0)              if isNothing mb_doc_hdr && isNullUniqMap dmap && isNullUniqMap amap-#else-             if isNothing mb_doc_hdr && Map.null dmap && null amap-#endif                then pure (Left (NoDocsInIface mod $ compiled name))                else pure (Right (-#if MIN_VERSION_ghc(9,3,0)                                   lookupUniqMap dmap name,-#else-                                  Map.lookup name dmap ,-#endif-#if MIN_VERSION_ghc(9,3,0)                                   lookupWithDefaultUniqMap amap mempty name))-#else-                                  Map.findWithDefault mempty name amap))-#endif     return $ map (first $ T.unpack . printOutputable) res   where     compiled n =@@ -1711,7 +1594,7 @@         res <- initIfaceLoad hsc_env $ importDecl name         case res of           Util.Succeeded x -> return (Just x)-          _ -> return Nothing+          _                -> return Nothing   where     exceptionHandle x = x `catch` \(_ :: IOEnvFailure) -> pure Nothing @@ -1721,6 +1604,22 @@       rep c | isPathSeparator c = '_'       rep ':' = '_'       rep c = c++-- | Initialising plugins looks in the finder cache, but we know that the plugin doesn't come from a home module, so don't+-- error out when we don't find it+setNonHomeFCHook :: HscEnv -> HscEnv+setNonHomeFCHook hsc_env =+#if MIN_VERSION_ghc(9,11,0)+  hsc_env { hsc_FC = (hsc_FC hsc_env)+                        { lookupFinderCache = \m@(GWIB im _) ->+                            if moduleUnit im `elem` hsc_all_home_unit_ids hsc_env+                            then pure (Just $ InstalledNotFound [] Nothing)+                            else lookupFinderCache (hsc_FC hsc_env) m+                        }+          }+#else+  hsc_env+#endif  {- Note [Guidelines For Using CPP In GHCIDE Import Statements]    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/Development/IDE/Core/FileStore.hs view
@@ -3,7 +3,10 @@ {-# LANGUAGE TypeFamilies #-}  module Development.IDE.Core.FileStore(+    getFileModTimeContents,     getFileContents,+    getUriContents,+    getVersionedTextDoc,     setFileModified,     setSomethingModified,     fileStoreRules,@@ -18,12 +21,13 @@     isWatchSupported,     registerFileWatches,     shareFilePath,-    Log(..)+    Log(..),     ) where  import           Control.Concurrent.STM.Stats                 (STM, atomically) import           Control.Concurrent.STM.TQueue                (writeTQueue) import           Control.Exception+import           Control.Lens                                 ((^.)) import           Control.Monad.Extra import           Control.Monad.IO.Class import qualified Data.Binary                                  as B@@ -33,6 +37,7 @@ import           Data.IORef import qualified Data.Text                                    as T import qualified Data.Text                                    as Text+import           Data.Text.Utf16.Rope.Mixed                   (Rope) import           Data.Time import           Data.Time.Clock.POSIX import           Development.IDE.Core.FileUtils@@ -56,13 +61,16 @@                                                                logWith, viaShow,                                                                (<+>)) import qualified Ide.Logger                                   as L-import           Ide.Plugin.Config                            (CheckParents (..),-                                                               Config)+import           Ide.Types+import qualified Language.LSP.Protocol.Lens                   as L import           Language.LSP.Protocol.Message                (toUntypedRegistration) import qualified Language.LSP.Protocol.Message                as LSP import           Language.LSP.Protocol.Types                  (DidChangeWatchedFilesRegistrationOptions (DidChangeWatchedFilesRegistrationOptions),                                                                FileSystemWatcher (..),-                                                               _watchers)+                                                               TextDocumentIdentifier (..),+                                                               VersionedTextDocumentIdentifier (..),+                                                               _watchers,+                                                               uriToNormalizedFilePath) import qualified Language.LSP.Protocol.Types                  as LSP import qualified Language.LSP.Server                          as LSP import           Language.LSP.VFS@@ -175,20 +183,20 @@  getFileContentsImpl     :: NormalizedFilePath-    -> Action ([FileDiagnostic], Maybe (FileVersion, Maybe T.Text))+    -> Action ([FileDiagnostic], Maybe (FileVersion, Maybe Rope)) getFileContentsImpl file = do     -- need to depend on modification time to introduce a dependency with Cutoff     time <- use_ GetModificationTime file     res <- do         mbVirtual <- getVirtualFile file-        pure $ virtualFileText <$> mbVirtual+        pure $ _file_text <$> mbVirtual     pure ([], Just (time, res))  -- | Returns the modification time and the contents. --   For VFS paths, the modification time is the current time.-getFileContents :: NormalizedFilePath -> Action (UTCTime, Maybe T.Text)-getFileContents f = do-    (fv, txt) <- use_ GetFileContents f+getFileModTimeContents :: NormalizedFilePath -> Action (UTCTime, Maybe Rope)+getFileModTimeContents f = do+    (fv, contents) <- use_ GetFileContents f     modTime <- case modificationTime fv of       Just t -> pure t       Nothing -> do@@ -198,8 +206,30 @@           _ -> do             posix <- getModTime $ fromNormalizedFilePath f             pure $ posixSecondsToUTCTime posix-    return (modTime, txt)+    return (modTime, contents) +getFileContents :: NormalizedFilePath -> Action (Maybe Rope)+getFileContents f = snd <$> use_ GetFileContents f++getUriContents :: NormalizedUri -> Action (Maybe Rope)+getUriContents uri =+    join <$> traverse getFileContents (uriToNormalizedFilePath uri)++-- | Given a text document identifier, annotate it with the latest version.+--+-- Like Language.LSP.Server.Core.getVersionedTextDoc, but gets the virtual file+-- from the Shake VFS rather than the LSP VFS.+getVersionedTextDoc :: TextDocumentIdentifier -> Action VersionedTextDocumentIdentifier+getVersionedTextDoc doc = do+  let uri = doc ^. L.uri+  mvf <-+    maybe (pure Nothing) getVirtualFile $+        uriToNormalizedFilePath $ toNormalizedUri uri+  let ver = case mvf of+        Just (VirtualFile lspver _ _) -> lspver+        Nothing                       -> 0+  return (VersionedTextDocumentIdentifier uri ver)+ fileStoreRules :: Recorder (WithPriority Log) -> (NormalizedFilePath -> Action Bool) -> Rules () fileStoreRules recorder isWatched = do     getModificationTimeRule recorder@@ -303,4 +333,3 @@           Just v  -> (km, v)           Nothing -> (HashMap.insert k k km, k) {-# NOINLINE shareFilePath  #-}-
src/Development/IDE/Core/OfInterest.hs view
@@ -29,6 +29,7 @@ import           Control.Concurrent.STM.Stats             (atomically,                                                            modifyTVar') import           Data.Aeson                               (toJSON)+import qualified Data.Aeson                               as Aeson import qualified Data.ByteString                          as BS import           Data.Maybe                               (catMaybes) import           Development.IDE.Core.ProgressReporting@@ -141,7 +142,7 @@                 toJSON $ map fromNormalizedFilePath files      signal (Proxy @"kick/start")-    liftIO $ progressUpdate progress KickStarted+    liftIO $ progressUpdate progress ProgressNewStarted      -- Update the exports map     results <- uses GenerateCore files@@ -152,7 +153,7 @@     let mguts = catMaybes results     void $ liftIO $ atomically $ modifyTVar' exportsMap (updateExportsMapMg mguts) -    liftIO $ progressUpdate progress KickCompleted+    liftIO $ progressUpdate progress ProgressCompleted      GarbageCollectVar var <- getIdeGlobalAction     garbageCollectionScheduled <- liftIO $ readVar var
src/Development/IDE/Core/PluginUtils.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE GADTs #-} module Development.IDE.Core.PluginUtils-(-- Wrapped Action functions+(-- * Wrapped Action functions   runActionE , runActionMT , useE@@ -9,13 +9,13 @@ , usesMT , useWithStaleE , useWithStaleMT--- Wrapped IdeAction functions+-- * Wrapped IdeAction functions , runIdeActionE , runIdeActionMT , useWithStaleFastE , useWithStaleFastMT , uriToFilePathE--- Wrapped PositionMapping functions+-- * Wrapped PositionMapping functions , toCurrentPositionE , toCurrentPositionMT , fromCurrentPositionE@@ -23,8 +23,16 @@ , toCurrentRangeE , toCurrentRangeMT , fromCurrentRangeE-, fromCurrentRangeMT) where+, fromCurrentRangeMT+-- * Diagnostics+, activeDiagnosticsInRange+, activeDiagnosticsInRangeMT+-- * Formatting handlers+, mkFormattingHandlers) where +import           Control.Concurrent.STM+import           Control.Lens                         ((^.))+import           Control.Monad.Error.Class            (MonadError (throwError)) import           Control.Monad.Extra import           Control.Monad.IO.Class import           Control.Monad.Reader                 (runReaderT)@@ -32,7 +40,10 @@ import           Control.Monad.Trans.Maybe import           Data.Functor.Identity import qualified Data.Text                            as T+import qualified Data.Text.Utf16.Rope.Mixed           as Rope+import           Development.IDE.Core.FileStore import           Development.IDE.Core.PositionMapping+import           Development.IDE.Core.Service         (runAction) import           Development.IDE.Core.Shake           (IdeAction, IdeRule,                                                        IdeState (shakeExtras),                                                        mkDelayedAction,@@ -40,11 +51,17 @@ import qualified Development.IDE.Core.Shake           as Shake import           Development.IDE.GHC.Orphans          () import           Development.IDE.Graph                hiding (ShakeValue)+import           Development.IDE.Types.Diagnostics import           Development.IDE.Types.Location       (NormalizedFilePath) import qualified Development.IDE.Types.Location       as Location import qualified Ide.Logger                           as Logger import           Ide.Plugin.Error+import           Ide.PluginUtils                      (rangesOverlap)+import           Ide.Types+import qualified Language.LSP.Protocol.Lens           as LSP+import           Language.LSP.Protocol.Message        (SMethod (..)) import qualified Language.LSP.Protocol.Types          as LSP+import qualified StmContainers.Map                    as STM  -- ---------------------------------------------------------------------------- -- Action wrappers@@ -162,3 +179,77 @@ -- |MaybeT version of `fromCurrentRange` fromCurrentRangeMT :: Monad m => PositionMapping -> LSP.Range -> MaybeT m LSP.Range fromCurrentRangeMT mapping = MaybeT . pure . fromCurrentRange mapping++-- ----------------------------------------------------------------------------+-- Diagnostics+-- ----------------------------------------------------------------------------++-- | @'activeDiagnosticsInRangeMT' shakeExtras nfp range@ computes the+-- 'FileDiagnostic' 's that HLS produced and overlap with the given @range@.+--+-- This function is to be used whenever we need an authoritative source of truth+-- for which diagnostics are shown to the user.+-- These diagnostics can be used to provide various IDE features, for example+-- CodeActions, CodeLenses, or refactorings.+--+-- However, why do we need this when computing 'CodeAction's? A 'CodeActionParam'+-- has the 'CodeActionContext' which already contains the diagnostics!+-- But according to the LSP docs, the server shouldn't rely that these Diagnostic+-- are actually up-to-date and accurately reflect the state of the document.+--+-- From the LSP docs:+-- > An array of diagnostics known on the client side overlapping the range+-- > provided to the `textDocument/codeAction` request. They are provided so+-- > that the server knows which errors are currently presented to the user+-- > for the given range. There is no guarantee that these accurately reflect+-- > the error state of the resource. The primary parameter+-- > to compute code actions is the provided range.+--+-- Thus, even when the client sends us the context, we should compute the+-- diagnostics on the server side.+activeDiagnosticsInRangeMT :: MonadIO m => Shake.ShakeExtras -> NormalizedFilePath -> LSP.Range -> MaybeT m [FileDiagnostic]+activeDiagnosticsInRangeMT ide nfp range = do+    MaybeT $ liftIO $ atomically $ do+        mDiags <- STM.lookup (LSP.normalizedFilePathToUri nfp) (Shake.publishedDiagnostics ide)+        case mDiags of+            Nothing -> pure Nothing+            Just fileDiags -> do+                pure $ Just $ filter diagRangeOverlaps fileDiags+    where+        diagRangeOverlaps = \fileDiag ->+            rangesOverlap range (fileDiag ^. fdLspDiagnosticL . LSP.range)++-- | Just like 'activeDiagnosticsInRangeMT'. See the docs of 'activeDiagnosticsInRangeMT' for details.+activeDiagnosticsInRange :: MonadIO m => Shake.ShakeExtras -> NormalizedFilePath -> LSP.Range -> m (Maybe [FileDiagnostic])+activeDiagnosticsInRange ide nfp range = runMaybeT (activeDiagnosticsInRangeMT ide nfp range)++-- ----------------------------------------------------------------------------+-- Formatting handlers+-- ----------------------------------------------------------------------------++-- `mkFormattingHandlers` was moved here from hls-plugin-api package so that+-- `mkFormattingHandlers` can refer to `IdeState`. `IdeState` is defined in the+-- ghcide package, but hls-plugin-api does not depend on ghcide, so `IdeState`+-- is not in scope there.++mkFormattingHandlers :: FormattingHandler IdeState -> PluginHandlers IdeState+mkFormattingHandlers f = mkPluginHandler SMethod_TextDocumentFormatting ( provider SMethod_TextDocumentFormatting)+                      <> mkPluginHandler SMethod_TextDocumentRangeFormatting (provider SMethod_TextDocumentRangeFormatting)+  where+    provider :: forall m. FormattingMethod m => SMethod m -> PluginMethodHandler IdeState m+    provider m ide _pid params+      | Just nfp <- LSP.uriToNormalizedFilePath $ LSP.toNormalizedUri uri = do+        contentsMaybe <- liftIO $ runAction "mkFormattingHandlers" ide $ getFileContents nfp+        case contentsMaybe of+          Just contents -> do+            let (typ, mtoken) = case m of+                  SMethod_TextDocumentFormatting -> (FormatText, params ^. LSP.workDoneToken)+                  SMethod_TextDocumentRangeFormatting -> (FormatRange (params ^. LSP.range), params ^. LSP.workDoneToken)+                  _ -> Prelude.error "mkFormattingHandlers: impossible"+            f ide mtoken typ (Rope.toText contents) nfp opts+          Nothing -> throwError $ PluginInvalidParams $ T.pack $ "Formatter plugin: could not get file contents for " ++ show uri++      | otherwise = throwError $ PluginInvalidParams $ T.pack $ "Formatter plugin: uriToFilePath failed for: " ++ show uri+      where+        uri = params ^. LSP.textDocument . LSP.uri+        opts = params ^. LSP.options
src/Development/IDE/Core/Preprocessor.hs view
@@ -28,15 +28,11 @@ import           Development.IDE.Types.Diagnostics import           Development.IDE.Types.Location import qualified GHC.LanguageExtensions            as LangExt+import qualified GHC.Runtime.Loader                as Loader+import           GHC.Utils.Logger                  (LogFlags (..)) import           System.FilePath import           System.IO.Extra --- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Utils.Logger                  (LogFlags (..))-#endif- -- | Given a file and some contents, apply any necessary preprocessors, --   e.g. unlit/cpp. Return the resulting buffer and the DynFlags it implies. preprocessor :: HscEnv -> FilePath -> Maybe Util.StringBuffer -> ExceptT [FileDiagnostic] IO (Util.StringBuffer, [String], HscEnv, Util.Fingerprint)@@ -88,11 +84,7 @@   where     logAction :: IORef [CPPLog] -> LogActionCompat     logAction cppLogs dflags _reason severity srcSpan _style msg = do-#if MIN_VERSION_ghc(9,3,0)       let cppLog = CPPLog (fromMaybe SevWarning severity) srcSpan $ T.pack $ renderWithContext (log_default_user_context dflags) msg-#else-      let cppLog = CPPLog severity srcSpan $ T.pack $ showSDoc dflags msg-#endif       modifyIORef cppLogs (cppLog :)  @@ -112,7 +104,7 @@  diagsFromCPPLogs :: FilePath -> [CPPLog] -> [FileDiagnostic] diagsFromCPPLogs filename logs =-  map (\d -> (toNormalizedFilePath' filename, ShowDiag, cppDiagToDiagnostic d)) $+  map (\d -> ideErrorFromLspDiag (cppDiagToDiagnostic d) (toNormalizedFilePath' filename) Nothing) $     go [] logs   where     -- On errors, CPP calls logAction with a real span for the initial log and@@ -152,17 +144,13 @@     -> Util.StringBuffer     -> IO (Either [FileDiagnostic] ([String], HscEnv)) parsePragmasIntoHscEnv env fp contents = catchSrcErrors dflags0 "pragmas" $ do-#if MIN_VERSION_ghc(9,3,0)     let (_warns,opts) = getOptions (initParserOpts dflags0) contents fp-#else-    let opts = getOptions dflags0 contents fp-#endif      -- Force bits that might keep the dflags and stringBuffer alive unnecessarily     evaluate $ rnf opts      (dflags, _, _) <- parseDynamicFilePragma dflags0 opts-    hsc_env' <- initializePlugins (hscSetFlags dflags env)+    hsc_env' <- Loader.initializePlugins (hscSetFlags dflags env)     return (map unLoc opts, hscSetFlags (disableWarningsAsErrors $ hsc_dflags hsc_env') hsc_env')   where dflags0 = hsc_dflags env 
src/Development/IDE/Core/ProgressReporting.hs view
@@ -1,17 +1,25 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies        #-}+ module Development.IDE.Core.ProgressReporting-  ( ProgressEvent(..)-  , ProgressReporting(..)-  , noProgressReporting-  , progressReporting-  -- utilities, reexported for use in Core.Shake-  , mRunLspT-  , mRunLspTCallback-  -- for tests-  , recordProgress-  , InProgressState(..)+  ( ProgressEvent (..),+    PerFileProgressReporting (..),+    ProgressReporting,+    noPerFileProgressReporting,+    progressReporting,+    progressReportingNoTrace,+    -- utilities, reexported for use in Core.Shake+    mRunLspT,+    mRunLspTCallback,+    -- for tests+    recordProgress,+    InProgressState (..),+    progressStop,+    progressUpdate   )-   where+where +import           Control.Concurrent.STM         (STM) import           Control.Concurrent.STM.Stats   (TVar, atomically,                                                  atomicallyNamed, modifyTVar',                                                  newTVarIO, readTVar, retry)@@ -23,7 +31,6 @@ import           Data.Functor                   (($>)) import qualified Data.Text                      as T import           Development.IDE.GHC.Orphans    ()-import           Development.IDE.Graph          hiding (ShakeValue) import           Development.IDE.Types.Location import           Development.IDE.Types.Options import qualified Focus@@ -33,119 +40,197 @@                                                  withProgress) import qualified Language.LSP.Server            as LSP import qualified StmContainers.Map              as STM-import           UnliftIO                       (Async, async, cancel)+import           UnliftIO                       (Async, async, bracket, cancel)  data ProgressEvent-    = KickStarted-    | KickCompleted+  = ProgressNewStarted+  | ProgressCompleted+  | ProgressStarted -data ProgressReporting  = ProgressReporting-  { progressUpdate :: ProgressEvent -> IO ()-  , inProgress     :: forall a. NormalizedFilePath -> Action a -> Action a-  , progressStop   :: IO ()+data ProgressReporting = ProgressReporting+  { _progressUpdate :: ProgressEvent -> IO (),+    _progressStop   :: IO ()+    -- ^ we are using IO here because creating and stopping the `ProgressReporting`+    -- is different from how we use it.   } -noProgressReporting :: IO ProgressReporting-noProgressReporting = return $ ProgressReporting-  { progressUpdate = const $ pure ()-  , inProgress = const id-  , progressStop   = pure ()+data PerFileProgressReporting = PerFileProgressReporting+  {+    inProgress             :: forall a. NormalizedFilePath -> IO a -> IO a,+    -- ^ see Note [ProgressReporting API and InProgressState]+    progressReportingInner :: ProgressReporting   } +class ProgressReporter a where+    progressUpdate ::  a -> ProgressEvent -> IO ()+    progressStop :: a -> IO ()++instance ProgressReporter ProgressReporting where+    progressUpdate = _progressUpdate+    progressStop = _progressStop++instance ProgressReporter PerFileProgressReporting where+    progressUpdate = _progressUpdate . progressReportingInner+    progressStop = _progressStop . progressReportingInner++{- Note [ProgressReporting API and InProgressState]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The progress of tasks can be tracked in two ways:++1. `ProgressReporting`: we have an internal state that actively tracks the progress.+   Changes to the progress are made directly to this state.++2. `ProgressReporting`: there is an external state that tracks the progress.+   The external state is converted into an STM Int for the purpose of reporting progress.++The `inProgress` function is only useful when we are using `ProgressReporting`.+-}++noProgressReporting :: ProgressReporting+noProgressReporting = ProgressReporting+      { _progressUpdate = const $ pure (),+        _progressStop = pure ()+      }+noPerFileProgressReporting :: IO PerFileProgressReporting+noPerFileProgressReporting =+  return $+    PerFileProgressReporting+      { inProgress = const id,+        progressReportingInner = noProgressReporting+      }+ -- | State used in 'delayedProgressReporting' data State-    = NotStarted-    | Stopped-    | Running (Async ())+  = NotStarted+  | Stopped+  | Running (Async ())  -- | State transitions used in 'delayedProgressReporting' data Transition = Event ProgressEvent | StopProgress  updateState :: IO () -> Transition -> State -> IO State-updateState _      _                    Stopped       = pure Stopped-updateState start (Event KickStarted)   NotStarted    = Running <$> async start-updateState start (Event KickStarted)   (Running job) = cancel job >> Running <$> async start-updateState _     (Event KickCompleted) (Running job) = cancel job $> NotStarted-updateState _     (Event KickCompleted) st            = pure st-updateState _     StopProgress          (Running job) = cancel job $> Stopped-updateState _     StopProgress          st            = pure st+updateState _ _ Stopped = pure Stopped+updateState start (Event ProgressNewStarted) NotStarted = Running <$> async start+updateState start (Event ProgressNewStarted) (Running job) = cancel job >> Running <$> async start+updateState start (Event ProgressStarted) NotStarted = Running <$> async start+updateState _ (Event ProgressStarted) (Running job) = return (Running job)+updateState _ (Event ProgressCompleted) (Running job) = cancel job $> NotStarted+updateState _ (Event ProgressCompleted) st = pure st+updateState _ StopProgress (Running job) = cancel job $> Stopped+updateState _ StopProgress st = pure st  -- | Data structure to track progress across the project-data InProgressState = InProgressState-    { todoVar    :: TVar Int  -- ^ Number of files to do-    , doneVar    :: TVar Int  -- ^ Number of files done-    , currentVar :: STM.Map NormalizedFilePath Int-    }+-- see Note [ProgressReporting API and InProgressState]+data InProgressState+  = InProgressState+      { -- | Number of files to do+        todoVar    :: TVar Int,+        -- | Number of files done+        doneVar    :: TVar Int,+        currentVar :: STM.Map NormalizedFilePath Int+      }  newInProgress :: IO InProgressState newInProgress = InProgressState <$> newTVarIO 0 <*> newTVarIO 0 <*> STM.newIO  recordProgress :: InProgressState -> NormalizedFilePath -> (Int -> Int) -> IO ()-recordProgress InProgressState{..} file shift = do-    (prev, new) <- atomicallyNamed "recordProgress" $ STM.focus alterPrevAndNew file currentVar-    atomicallyNamed "recordProgress2" $ do-        case (prev,new) of-            (Nothing,0) -> modifyTVar' doneVar (+1) >> modifyTVar' todoVar (+1)-            (Nothing,_) -> modifyTVar' todoVar (+1)-            (Just 0, 0) -> pure ()-            (Just 0, _) -> modifyTVar' doneVar pred-            (Just _, 0) -> modifyTVar' doneVar (+1)-            (Just _, _) -> pure ()+recordProgress InProgressState {..} file shift = do+  (prev, new) <- atomicallyNamed "recordProgress" $ STM.focus alterPrevAndNew file currentVar+  atomicallyNamed "recordProgress2" $ case (prev, new) of+    (Nothing, 0) -> modifyTVar' doneVar (+ 1) >> modifyTVar' todoVar (+ 1)+    (Nothing, _) -> modifyTVar' todoVar (+ 1)+    (Just 0, 0)  -> pure ()+    (Just 0, _)  -> modifyTVar' doneVar pred+    (Just _, 0)  -> modifyTVar' doneVar (+ 1)+    (Just _, _)  -> pure ()   where     alterPrevAndNew = do-        prev <- Focus.lookup-        Focus.alter alter-        new <- Focus.lookupWithDefault 0-        return (prev, new)+      prev <- Focus.lookup+      Focus.alter alter+      new <- Focus.lookupWithDefault 0+      return (prev, new)     alter x = let x' = maybe (shift 0) shift x in Just x' -progressReporting-  :: Maybe (LSP.LanguageContextEnv c)-  -> ProgressReportingStyle-  -> IO ProgressReporting-progressReporting Nothing _optProgressStyle = noProgressReporting-progressReporting (Just lspEnv) optProgressStyle = do-    inProgressState <- newInProgress-    progressState <- newVar NotStarted-    let progressUpdate event = updateStateVar $ Event event-        progressStop  = updateStateVar StopProgress-        updateStateVar = modifyVar_ progressState . updateState (lspShakeProgressNew inProgressState)-        inProgress = updateStateForFile inProgressState-    return ProgressReporting{..}-    where-        lspShakeProgressNew :: InProgressState -> IO ()-        lspShakeProgressNew InProgressState{..} =-            LSP.runLspT lspEnv $ withProgress "Processing" Nothing NotCancellable $ \update -> loop update 0-            where-                loop _ _ | optProgressStyle == NoProgress = forever $ liftIO $ threadDelay maxBound-                loop update prevPct = do-                    (todo, done, nextPct) <- liftIO $ atomically $ do-                        todo <- readTVar todoVar-                        done <- readTVar doneVar-                        let nextFrac :: Double-                            nextFrac = if todo == 0 then 0 else fromIntegral done / fromIntegral todo-                            nextPct :: UInt-                            nextPct = floor $ 100 * nextFrac-                        when (nextPct == prevPct) retry-                        pure (todo, done, nextPct) -                    _ <- update (ProgressAmount (Just nextPct) (Just $ T.pack $ show done <> "/" <> show todo))-                    loop update nextPct-        updateStateForFile inProgress file = actionBracket (f succ) (const $ f pred) . const-            -- This functions are deliberately eta-expanded to avoid space leaks.-            -- Do not remove the eta-expansion without profiling a session with at-            -- least 1000 modifications.-            where-              f shift = recordProgress inProgress file shift+-- | `progressReportingNoTrace` initiates a new progress reporting session.+-- It functions similarly to `progressReporting`, but it utilizes an external state for progress tracking.+-- Refer to Note [ProgressReporting API and InProgressState] for more details.+progressReportingNoTrace ::+  STM Int ->+  STM Int ->+  Maybe (LSP.LanguageContextEnv c) ->+  T.Text ->+  ProgressReportingStyle ->+  IO ProgressReporting+progressReportingNoTrace _ _ Nothing _title _optProgressStyle = return noProgressReporting+progressReportingNoTrace todo done (Just lspEnv) title optProgressStyle = do+  progressState <- newVar NotStarted+  let _progressUpdate event = liftIO $ updateStateVar $ Event event+      _progressStop = updateStateVar StopProgress+      updateStateVar = modifyVar_ progressState . updateState (progressCounter lspEnv title optProgressStyle todo done)+  return ProgressReporting {..} -mRunLspT :: Applicative m => Maybe (LSP.LanguageContextEnv c ) -> LSP.LspT c m () -> m ()+-- | `progressReporting` initiates a new progress reporting session.+-- It necessitates the active tracking of progress using the `inProgress` function.+-- Refer to Note [ProgressReporting API and InProgressState] for more details.+progressReporting ::+  Maybe (LSP.LanguageContextEnv c) ->+  T.Text ->+  ProgressReportingStyle ->+  IO PerFileProgressReporting+progressReporting Nothing _title _optProgressStyle = noPerFileProgressReporting+progressReporting (Just lspEnv) title optProgressStyle = do+  inProgressState <- newInProgress+  progressReportingInner <- progressReportingNoTrace (readTVar $ todoVar inProgressState)+                                (readTVar $ doneVar inProgressState) (Just lspEnv) title optProgressStyle+  let+    inProgress :: NormalizedFilePath -> IO a -> IO a+    inProgress = updateStateForFile inProgressState+  return PerFileProgressReporting {..}+  where+    updateStateForFile inProgress file = UnliftIO.bracket (liftIO $ f succ) (const $ liftIO $ f pred) . const+      where+        -- This functions are deliberately eta-expanded to avoid space leaks.+        -- Do not remove the eta-expansion without profiling a session with at+        -- least 1000 modifications.++        f = recordProgress inProgress file++-- Kill this to complete the progress session+progressCounter ::+  LSP.LanguageContextEnv c ->+  T.Text ->+  ProgressReportingStyle ->+  STM Int ->+  STM Int ->+  IO ()+progressCounter lspEnv title optProgressStyle getTodo getDone =+  LSP.runLspT lspEnv $ withProgress title Nothing NotCancellable $ \update -> loop update 0+  where+    loop _ _ | optProgressStyle == NoProgress = forever $ liftIO $ threadDelay maxBound+    loop update prevPct = do+      (todo, done, nextPct) <- liftIO $ atomically $ do+        todo <- getTodo+        done <- getDone+        let nextFrac :: Double+            nextFrac = if todo == 0 then 0 else fromIntegral done / fromIntegral todo+            nextPct :: UInt+            nextPct = floor $ 100 * nextFrac+        when (nextPct == prevPct) retry+        pure (todo, done, nextPct)++      _ <- update (ProgressAmount (Just nextPct) (Just $ T.pack $ show done <> "/" <> show todo))+      loop update nextPct++mRunLspT :: (Applicative m) => Maybe (LSP.LanguageContextEnv c) -> LSP.LspT c m () -> m () mRunLspT (Just lspEnv) f = LSP.runLspT lspEnv f mRunLspT Nothing _       = pure () -mRunLspTCallback :: Monad m-                 => Maybe (LSP.LanguageContextEnv c)-                 -> (LSP.LspT c m a -> LSP.LspT c m a)-                 -> m a-                 -> m a+mRunLspTCallback ::+  (Monad m) =>+  Maybe (LSP.LanguageContextEnv c) ->+  (LSP.LspT c m a -> LSP.LspT c m a) ->+  m a ->+  m a mRunLspTCallback (Just lspEnv) f g = LSP.runLspT lspEnv $ f (lift g) mRunLspTCallback Nothing _ g       = g
src/Development/IDE/Core/RuleTypes.hs view
@@ -24,7 +24,8 @@ import           Data.Time.Clock.POSIX import           Data.Typeable import           Development.IDE.GHC.Compat                   hiding-                                                              (HieFileResult)+                                                              (HieFileResult,+                                                               assert) import           Development.IDE.GHC.Compat.Util import           Development.IDE.GHC.CoreFile import           Development.IDE.GHC.Util@@ -35,11 +36,12 @@ import           GHC.Generics                                 (Generic)  import           Data.ByteString                              (ByteString)-import           Data.Text                                    (Text)+import           Data.Text.Utf16.Rope.Mixed                   (Rope) import           Development.IDE.Import.FindImports           (ArtifactsLocation) import           Development.IDE.Spans.Common import           Development.IDE.Spans.LocalBindings import           Development.IDE.Types.Diagnostics+import           GHC.Driver.Errors.Types                      (WarningMessages) import           GHC.Serialized                               (Serialized) import           Ide.Logger                                   (Pretty (..),                                                                viaShow)@@ -82,7 +84,7 @@ type instance RuleResult GenerateCore = ModGuts  data GenerateCore = GenerateCore-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GenerateCore instance NFData   GenerateCore @@ -102,12 +104,12 @@     rnf = rwhnf  data GetLinkable = GetLinkable-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetLinkable instance NFData   GetLinkable  data GetImportMap = GetImportMap-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetImportMap instance NFData   GetImportMap @@ -157,6 +159,8 @@         -- ^ Which modules did we need at runtime while compiling this file?         -- Used for recompilation checking in the presence of TH         -- Stores the hash of their core file+    , tmrWarnings        :: WarningMessages+        -- ^ Structured warnings for this module.     } instance Show TcModuleResult where     show = show . pm_mod_summary . tmrParsed@@ -275,10 +279,12 @@ type instance RuleResult GetModIface = HiFileResult  -- | Get the contents of a file, either dirty (if the buffer is modified) or Nothing to mean use from disk.-type instance RuleResult GetFileContents = (FileVersion, Maybe Text)+type instance RuleResult GetFileContents = (FileVersion, Maybe Rope)  type instance RuleResult GetFileExists = Bool +type instance RuleResult GetFileHash = Fingerprint+ type instance RuleResult AddWatchedFile = Bool  @@ -329,16 +335,22 @@ instance NFData   GetFileContents  data GetFileExists = GetFileExists-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic)  instance NFData   GetFileExists instance Hashable GetFileExists +data GetFileHash = GetFileHash+    deriving (Eq, Show, Generic)++instance NFData   GetFileHash+instance Hashable GetFileHash+ data FileOfInterestStatus   = OnDisk   | Modified { firstOpen :: !Bool -- ^ was this file just opened              }-  deriving (Eq, Show, Typeable, Generic)+  deriving (Eq, Show, Generic) instance Hashable FileOfInterestStatus instance NFData   FileOfInterestStatus @@ -346,7 +358,7 @@     pretty = viaShow  data IsFileOfInterestResult = NotFOI | IsFOI FileOfInterestStatus-  deriving (Eq, Show, Typeable, Generic)+  deriving (Eq, Show, Generic) instance Hashable IsFileOfInterestResult instance NFData   IsFileOfInterestResult @@ -378,17 +390,17 @@ type instance RuleResult GetModSummaryWithoutTimestamps = ModSummaryResult  data GetParsedModule = GetParsedModule-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetParsedModule instance NFData   GetParsedModule  data GetParsedModuleWithComments = GetParsedModuleWithComments-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetParsedModuleWithComments instance NFData   GetParsedModuleWithComments  data GetLocatedImports = GetLocatedImports-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetLocatedImports instance NFData   GetLocatedImports @@ -396,42 +408,42 @@ type instance RuleResult NeedsCompilation = Maybe LinkableType  data NeedsCompilation = NeedsCompilation-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable NeedsCompilation instance NFData   NeedsCompilation  data GetModuleGraph = GetModuleGraph-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetModuleGraph instance NFData   GetModuleGraph  data ReportImportCycles = ReportImportCycles-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable ReportImportCycles instance NFData   ReportImportCycles  data TypeCheck = TypeCheck-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable TypeCheck instance NFData   TypeCheck  data GetDocMap = GetDocMap-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetDocMap instance NFData   GetDocMap  data GetHieAst = GetHieAst-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetHieAst instance NFData   GetHieAst  data GetBindings = GetBindings-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetBindings instance NFData   GetBindings  data GhcSession = GhcSession-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GhcSession instance NFData   GhcSession @@ -440,7 +452,7 @@         -- Required for interactive evaluation, but leads to more cache invalidations         fullModSummary :: Bool     }-    deriving newtype (Eq, Typeable, Hashable, NFData)+    deriving newtype (Eq, Hashable, NFData)  instance Show GhcSessionDeps where     show (GhcSessionDeps_ False) = "GhcSessionDeps"@@ -450,45 +462,45 @@ pattern GhcSessionDeps = GhcSessionDeps_ False  data GetModIfaceFromDisk = GetModIfaceFromDisk-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetModIfaceFromDisk instance NFData   GetModIfaceFromDisk  data GetModIfaceFromDiskAndIndex = GetModIfaceFromDiskAndIndex-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetModIfaceFromDiskAndIndex instance NFData   GetModIfaceFromDiskAndIndex  data GetModIface = GetModIface-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetModIface instance NFData   GetModIface  data IsFileOfInterest = IsFileOfInterest-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable IsFileOfInterest instance NFData   IsFileOfInterest  data GetModSummaryWithoutTimestamps = GetModSummaryWithoutTimestamps-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetModSummaryWithoutTimestamps instance NFData   GetModSummaryWithoutTimestamps  data GetModSummary = GetModSummary-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetModSummary instance NFData   GetModSummary  -- See Note [Client configuration in Rules] -- | Get the client config stored in the ide state data GetClientSettings = GetClientSettings-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable GetClientSettings instance NFData   GetClientSettings  type instance RuleResult GetClientSettings = Hashed (Maybe Value) -data AddWatchedFile = AddWatchedFile deriving (Eq, Show, Typeable, Generic)+data AddWatchedFile = AddWatchedFile deriving (Eq, Show, Generic) instance Hashable AddWatchedFile instance NFData   AddWatchedFile @@ -508,7 +520,7 @@ instance Show IdeGhcSession where show _ = "IdeGhcSession" instance NFData IdeGhcSession where rnf !_ = () -data GhcSessionIO = GhcSessionIO deriving (Eq, Show, Typeable, Generic)+data GhcSessionIO = GhcSessionIO deriving (Eq, Show, Generic) instance Hashable GhcSessionIO instance NFData   GhcSessionIO 
src/Development/IDE/Core/Rules.hs view
@@ -64,6 +64,7 @@ import           Control.DeepSeq import           Control.Exception                            (evaluate) import           Control.Exception.Safe+import           Control.Lens                                 ((%~), (&), (.~)) import           Control.Monad.Extra import           Control.Monad.IO.Unlift import           Control.Monad.Reader@@ -91,6 +92,7 @@ import           Data.Proxy import qualified Data.Text                                    as T import qualified Data.Text.Encoding                           as T+import qualified Data.Text.Utf16.Rope.Mixed                   as Rope import           Data.Time                                    (UTCTime (..)) import           Data.Time.Clock.POSIX                        (posixSecondsToUTCTime) import           Data.Tuple.Extra@@ -99,6 +101,7 @@ import           Development.IDE.Core.FileExists              hiding (Log,                                                                LogShake) import           Development.IDE.Core.FileStore               (getFileContents,+                                                               getFileModTimeContents,                                                                getModTime) import           Development.IDE.Core.IdeConfiguration import           Development.IDE.Core.OfInterest              hiding (Log,@@ -159,6 +162,7 @@ import           Language.LSP.Protocol.Message                (SMethod (SMethod_CustomMethod, SMethod_WindowShowMessage)) import           Language.LSP.Protocol.Types                  (MessageType (MessageType_Info),                                                                ShowMessageParams (ShowMessageParams))+import qualified Language.LSP.Protocol.Lens                   as JL import           Language.LSP.Server                          (LspT) import qualified Language.LSP.Server                          as LSP import           Language.LSP.VFS@@ -167,19 +171,10 @@ import           System.Info.Extra                            (isWindows)  -import           GHC.Fingerprint---- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if !MIN_VERSION_ghc(9,3,0)-import           GHC                                          (mgModSummaries)-#endif--#if MIN_VERSION_ghc(9,3,0) import qualified Data.IntMap                                  as IM-#endif-+import           GHC.Fingerprint +import           GHC.Driver.Env                      (hsc_all_home_unit_ids)  data Log   = LogShake Shake.Log@@ -230,10 +225,10 @@ -- TODO: return text --> return rope getSourceFileSource :: NormalizedFilePath -> Action BS.ByteString getSourceFileSource nfp = do-    (_, msource) <- getFileContents nfp+    msource <- getFileContents nfp     case msource of         Nothing     -> liftIO $ BS.readFile (fromNormalizedFilePath nfp)-        Just source -> pure $ T.encodeUtf8 source+        Just source -> pure $ T.encodeUtf8 $ Rope.toText source  -- | Parse the contents of a haskell file. getParsedModule :: NormalizedFilePath -> Action (Maybe ParsedModule)@@ -324,18 +319,11 @@         (KnownTargets targets targetsMap) <- useNoFile_ GetKnownTargets         let imports = [(False, imp) | imp <- ms_textual_imps ms] ++ [(True, imp) | imp <- ms_srcimps ms]         env_eq <- use_ GhcSession file-        let env = hscEnvWithImportPaths env_eq-        let import_dirs = deps env_eq+        let env = hscEnv env_eq+        let import_dirs = map (second homeUnitEnv_dflags) $ hugElts $ hsc_HUG env         let dflags = hsc_dflags env-            isImplicitCradle = isNothing $ envImportPaths env_eq-        let dflags' = if isImplicitCradle-                    then addRelativeImport file (moduleName $ ms_mod ms) dflags-                    else dflags         opt <- getIdeOptions         let getTargetFor modName nfp-                | isImplicitCradle = do-                    itExists <- getFileExists nfp-                    return $ if itExists then Just nfp else Nothing                 | Just (TargetFile nfp') <- HM.lookup (TargetFile nfp) targetsMap = do                     -- reuse the existing NormalizedFilePath in order to maximize sharing                     itExists <- getFileExists nfp'@@ -346,10 +334,11 @@                         nfp' = HM.lookupDefault nfp nfp ttmap                     itExists <- getFileExists nfp'                     return $ if itExists then Just nfp' else Nothing-                | otherwise-                = return Nothing+                | otherwise = do+                    itExists <- getFileExists nfp+                    return $ if itExists then Just nfp else Nothing         (diags, imports') <- fmap unzip $ forM imports $ \(isSource, (mbPkgName, modName)) -> do-            diagOrImp <- locateModule (hscSetFlags dflags' env) import_dirs (optExtensions opt) getTargetFor modName mbPkgName isSource+            diagOrImp <- locateModule (hscSetFlags dflags env) import_dirs (optExtensions opt) getTargetFor modName mbPkgName isSource             case diagOrImp of                 Left diags              -> pure (diags, Just (modName, Nothing))                 Right (FileImport path) -> pure ([], Just (modName, Just path))@@ -500,17 +489,9 @@     where cycleErrorInFile f (PartOfCycle imp fs)             | f `elem` fs = Just (imp, fs)           cycleErrorInFile _ _ = Nothing-          toDiag imp mods = (fp , ShowDiag , ) $ Diagnostic-            { _range = rng-            , _severity = Just DiagnosticSeverity_Error-            , _source = Just "Import cycle detection"-            , _message = "Cyclic module dependency between " <> showCycle mods-            , _code = Nothing-            , _relatedInformation = Nothing-            , _tags = Nothing-            , _codeDescription = Nothing-            , _data_ = Nothing-            }+          toDiag imp mods =+            ideErrorWithSource (Just "Import cycle detection") (Just DiagnosticSeverity_Error) fp ("Cyclic module dependency between " <> showCycle mods) Nothing+              & fdLspDiagnosticL %~ JL.range .~ rng             where rng = fromMaybe noRange $ srcSpanToRange (getLoc imp)                   fp = toNormalizedFilePath' $ fromMaybe noFilePath $ srcSpanToFilename (getLoc imp)           getModuleName file = do@@ -539,7 +520,12 @@  getHieAstRuleDefinition :: NormalizedFilePath -> HscEnv -> TcModuleResult -> Action (IdeResult HieAstResult) getHieAstRuleDefinition f hsc tmr = do-  (diags, masts) <- liftIO $ generateHieAsts hsc tmr+  (diags, masts') <- liftIO $ generateHieAsts hsc tmr+#if MIN_VERSION_ghc(9,11,0)+  let masts = fst <$> masts'+#else+  let masts = masts'+#endif   se <- getShakeExtras    isFoi <- use_ IsFileOfInterest f@@ -549,7 +535,7 @@         LSP.sendNotification (SMethod_CustomMethod (Proxy @"ghcide/reference/ready")) $           toJSON $ fromNormalizedFilePath f       pure []-    _ | Just asts <- masts -> do+    _ | Just asts <- masts' -> do           source <- getSourceFileSource f           let exports = tcg_exports $ tmrTypechecked tmr               modSummary = tmrModSummary tmr@@ -630,6 +616,13 @@   fs <- knownTargets   pure (LBS.toStrict $ B.encode $ hash fs, unhashed fs) +getFileHashRule :: Recorder (WithPriority Log) -> Rules ()+getFileHashRule recorder =+    defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetFileHash file -> do+        void $ use_ GetModificationTime file+        fileHash <- liftIO $ Util.getFileHash (fromNormalizedFilePath file)+        return (Just (fingerprintToBS fileHash), ([], Just fileHash))+ getModuleGraphRule :: Recorder (WithPriority Log) -> Rules () getModuleGraphRule recorder = defineEarlyCutOffNoFile (cmapWithPrio LogShake recorder) $ \GetModuleGraph -> do   fs <- toKnownFiles <$> useNoFile_ GetKnownTargets@@ -641,7 +634,6 @@   let (all_fs, _all_ids) = unzip $ HM.toList $ pathToIdMap $ rawPathIdMap rawDepInfo   msrs <- uses GetModSummaryWithoutTimestamps all_fs   let mss = map (fmap msrModSummary) msrs-#if MIN_VERSION_ghc(9,3,0)   let deps = map (\i -> IM.lookup (getFilePathId i) (rawImports rawDepInfo)) _all_ids       nodeKeys = IM.fromList $ catMaybes $ zipWith (\fi mms -> (getFilePathId fi,) . NodeKey_Module . msKey <$> mms) _all_ids mss       mns = catMaybes $ zipWith go mss deps@@ -651,14 +643,6 @@       go (Just ms) _ = Just $ ModuleNode [] ms       go _ _ = Nothing       mg = mkModuleGraph mns-#else-  let mg = mkModuleGraph $-        -- We don't do any instantiation for backpack at this point of time, so it is OK to use-        -- 'extendModSummaryNoDeps'.-        -- This may have to change in the future.-          map extendModSummaryNoDeps $-          catMaybes mss-#endif   pure (fingerprintToBS $ Util.fingerprintFingerprints $ map (maybe fingerprint0 msrFingerprint) msrs, processDependencyInformation rawDepInfo bm mg)  -- This is factored out so it can be directly called from the GetModIface@@ -675,6 +659,7 @@   unlift <- askUnliftIO   let dets = TypecheckHelpers            { getLinkables = unliftIO unlift . uses_ GetLinkable+           , getModuleGraph = unliftIO unlift $ useNoFile_ GetModuleGraph            }   addUsageDependencies $ liftIO $     typecheckModule defer hsc dets pm@@ -776,7 +761,6 @@               then depModuleGraph <$> useNoFile_ GetModuleGraph               else do                 let mgs = map hsc_mod_graph depSessions-#if MIN_VERSION_ghc(9,3,0)                 -- On GHC 9.4+, the module graph contains not only ModSummary's but each `ModuleNode` in the graph                 -- also points to all the direct descendants of the current module. To get the keys for the descendants                 -- we must get their `ModSummary`s@@ -785,17 +769,10 @@                   return $!! map (NodeKey_Module . msKey) dep_mss                 let module_graph_nodes =                       nubOrdOn mkNodeKey (ModuleNode final_deps ms : concatMap mgModSummaries' mgs)-#else-                let module_graph_nodes =-                      -- We don't do any instantiation for backpack at this point of time, so it is OK to use-                      -- 'extendModSummaryNoDeps'.-                      -- This may have to change in the future.-                      map extendModSummaryNoDeps $-                      nubOrdOn ms_mod (ms : concatMap mgModSummaries mgs)-#endif                 liftIO $ evaluate $ liftRnf rwhnf module_graph_nodes                 return $ mkModuleGraph module_graph_nodes-            session' <- liftIO $ mergeEnvs hsc mg ms inLoadOrder depSessions+            de <- useNoFile_ GetModuleGraph+            session' <- liftIO $ mergeEnvs hsc mg de ms inLoadOrder depSessions              -- Here we avoid a call to to `newHscEnvEqWithImportPaths`, which creates a new             -- ExportsMap when it is called. We only need to create the ExportsMap once per@@ -824,9 +801,11 @@             , old_value = m_old             , get_file_version = use GetModificationTime_{missingFileDiagnostics = False}             , get_linkable_hashes = \fs -> map (snd . fromJust . hirCoreFp) <$> uses_ GetModIface fs+            , get_module_graph = useNoFile_ GetModuleGraph             , regenerate = regenerateHiFile session f ms             }-      r <- loadInterface (hscEnv session) ms linkableType recompInfo+      hsc_env' <- setFileCacheHook (hscEnv session)+      r <- loadInterface hsc_env' ms linkableType recompInfo       case r of         (diags, Nothing) -> return (Nothing, (diags, Nothing))         (diags, Just x) -> do@@ -894,23 +873,18 @@     defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetModSummary f -> do         session' <- hscEnv <$> use_ GhcSession f         modify_dflags <- getModifyDynFlags dynFlagsModifyGlobal-        let session = hscSetFlags (modify_dflags $ hsc_dflags session') session'-        (modTime, mFileContent) <- getFileContents f+        let session = setNonHomeFCHook $ hscSetFlags (modify_dflags $ hsc_dflags session') session' -- TODO wz1000+        (modTime, mFileContent) <- getFileModTimeContents f         let fp = fromNormalizedFilePath f         modS <- liftIO $ runExceptT $-                getModSummaryFromImports session fp modTime (textToStringBuffer <$> mFileContent)+                getModSummaryFromImports session fp modTime (textToStringBuffer . Rope.toText <$> mFileContent)         case modS of             Right res -> do                 -- Check for Template Haskell                 when (uses_th_qq $ msrModSummary res) $ do                     DisplayTHWarning act <- getIdeGlobalAction                     liftIO act-#if MIN_VERSION_ghc(9,3,0)                 let bufFingerPrint = ms_hs_hash (msrModSummary res)-#else-                bufFingerPrint <- liftIO $-                    fingerprintFromStringBuffer $ fromJust $ ms_hspp_buf $ msrModSummary res-#endif                 let fingerPrint = Util.fingerprintFingerprints                         [ msrFingerprint res, bufFingerPrint ]                 return ( Just (fingerprintToBS fingerPrint) , ([], Just res))@@ -921,9 +895,6 @@         case mbMs of             Just res@ModSummaryResult{..} -> do                 let ms = msrModSummary {-#if !MIN_VERSION_ghc(9,3,0)-                    ms_hs_date = error "use GetModSummary instead of GetModSummaryWithoutTimestamps",-#endif                     ms_hspp_buf = error "use GetModSummary instead of GetModSummaryWithoutTimestamps"                     }                     fp = fingerprintToBS msrFingerprint@@ -933,8 +904,9 @@ generateCore :: RunSimplifier -> NormalizedFilePath -> Action (IdeResult ModGuts) generateCore runSimplifier file = do     packageState <- hscEnv <$> use_ GhcSessionDeps file+    hsc' <- setFileCacheHook packageState     tm <- use_ TypeCheck file-    liftIO $ compileModule runSimplifier packageState (tmrModSummary tm) (tmrTypechecked tm)+    liftIO $ compileModule runSimplifier hsc' (tmrModSummary tm) (tmrTypechecked tm)  generateCoreRule :: Recorder (WithPriority Log) -> Rules () generateCoreRule recorder =@@ -949,14 +921,15 @@       tmr <- use_ TypeCheck f       linkableType <- getLinkableType f       hsc <- hscEnv <$> use_ GhcSessionDeps f+      hsc' <- setFileCacheHook hsc       let compile = fmap ([],) $ use GenerateCore f       se <- getShakeExtras-      (diags, !mbHiFile) <- writeCoreFileIfNeeded se hsc linkableType compile tmr+      (diags, !mbHiFile) <- writeCoreFileIfNeeded se hsc' linkableType compile tmr       let fp = hiFileFingerPrint <$> mbHiFile       hiDiags <- case mbHiFile of         Just hiFile           | OnDisk <- status-          , not (tmrDeferredError tmr) -> liftIO $ writeHiFile se hsc hiFile+          , not (tmrDeferredError tmr) -> liftIO $ writeHiFile se hsc' hiFile         _ -> pure []       return (fp, (diags++hiDiags, mbHiFile))     NotFOI -> do@@ -980,12 +953,21 @@   count <- getRebuildCountVar <$> getIdeGlobalAction   liftIO $ atomically $ modifyTVar' count (+1) +setFileCacheHook :: HscEnv -> Action HscEnv+setFileCacheHook old_hsc_env = do+#if MIN_VERSION_ghc(9,11,0)+  unlift <- askUnliftIO+  return $ old_hsc_env { hsc_FC = (hsc_FC old_hsc_env) { lookupFileCache = unliftIO unlift . use_ GetFileHash . toNormalizedFilePath'  } }+#else+  return old_hsc_env+#endif+ -- | Also generates and indexes the `.hie` file, along with the `.o` file if needed -- Invariant maintained is that if the `.hi` file was successfully written, then the -- `.hie` and `.o` file (if needed) were also successfully written regenerateHiFile :: HscEnvEq -> NormalizedFilePath -> ModSummary -> Maybe LinkableType -> Action ([FileDiagnostic], Maybe HiFileResult) regenerateHiFile sess f ms compNeeded = do-    let hsc = hscEnv sess+    hsc <- setFileCacheHook (hscEnv sess)     opt <- getIdeOptions      -- Embed haddocks in the interface file@@ -1081,10 +1063,16 @@ getLinkableRule :: Recorder (WithPriority Log) -> Rules () getLinkableRule recorder =   defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetLinkable f -> do-    ModSummaryResult{msrModSummary = ms} <- use_ GetModSummary f-    HiFileResult{hirModIface, hirModDetails, hirCoreFp} <- use_ GetModIface f-    let obj_file  = ml_obj_file (ms_location ms)-        core_file = ml_core_file (ms_location ms)+    HiFileResult{hirModSummary, hirModIface, hirModDetails, hirCoreFp} <- use_ GetModIface f+    let obj_file  = ml_obj_file (ms_location hirModSummary)+        core_file = ml_core_file (ms_location hirModSummary)+#if MIN_VERSION_ghc(9,11,0)+        mkLinkable t mod l = Linkable t mod (pure l)+        dotO o = DotO o ModuleObject+#else+        mkLinkable t mod l = LM t mod [l]+        dotO = DotO+#endif     case hirCoreFp of       Nothing -> error $ "called GetLinkable for a file without a linkable: " ++ show f       Just (bin_core, fileHash) -> do@@ -1097,7 +1085,7 @@         core_t <- liftIO $ getModTime core_file         (warns, hmi) <- case linkableType of           -- Bytecode needs to be regenerated from the core file-          BCOLinkable -> liftIO $ coreFileToLinkable linkableType (hscEnv session) ms hirModIface hirModDetails bin_core (posixSecondsToUTCTime core_t)+          BCOLinkable -> liftIO $ coreFileToLinkable linkableType (hscEnv session) hirModSummary hirModIface hirModDetails bin_core (posixSecondsToUTCTime core_t)           -- Object code can be read from the disk           ObjectLinkable -> do             -- object file is up to date if it is newer than the core file@@ -1110,10 +1098,15 @@               else pure Nothing             case mobj_time of               Just obj_t-                | obj_t >= core_t -> pure ([], Just $ HomeModInfo hirModIface hirModDetails (justObjects $ LM (posixSecondsToUTCTime obj_t) (ms_mod ms) [DotO obj_file]))-              _ -> liftIO $ coreFileToLinkable linkableType (hscEnv session) ms hirModIface hirModDetails bin_core (error "object doesn't have time")+                | obj_t >= core_t -> pure ([], Just $ HomeModInfo hirModIface hirModDetails (justObjects $ mkLinkable (posixSecondsToUTCTime obj_t) (ms_mod hirModSummary) (dotO obj_file)))+              _ -> liftIO $ coreFileToLinkable linkableType (hscEnv session) hirModSummary hirModIface hirModDetails bin_core (error "object doesn't have time")         -- Record the linkable so we know not to unload it, and unload old versions-        whenJust ((homeModInfoByteCode =<< hmi) <|> (homeModInfoObject =<< hmi)) $ \(LM time mod _) -> do+        whenJust ((homeModInfoByteCode =<< hmi) <|> (homeModInfoObject =<< hmi))+#if MIN_VERSION_ghc(9,11,0)+          $ \(Linkable time mod _) -> do+#else+          $ \(LM time mod _) -> do+#endif             compiledLinkables <- getCompiledLinkables <$> getIdeGlobalAction             liftIO $ modifyVar compiledLinkables $ \old -> do               let !to_keep = extendModuleEnv old mod time@@ -1127,7 +1120,9 @@               --just before returning it to be loaded. This has a substantial effect on recompile               --times as the number of loaded modules and splices increases.               ---              unload (hscEnv session) (map (\(mod', time') -> LM time' mod' []) $ moduleEnvToList to_keep)+              --We use a dummy DotA linkable part to fake a NativeCode linkable.+              --The unload function doesn't care about the exact linkable parts.+              unload (hscEnv session) (map (\(mod', time') -> mkLinkable time' mod' (DotA "dummy")) $ moduleEnvToList to_keep)               return (to_keep, ())         return (fileHash <$ hmi, (warns, LinkableResult <$> hmi <*> pure fileHash)) @@ -1225,12 +1220,13 @@     reportImportCyclesRule recorder     typeCheckRule recorder     getDocMapRule recorder-    loadGhcSession recorder GhcSessionDepsConfig{fullModuleGraph}+    loadGhcSession recorder def{fullModuleGraph}     getModIfaceFromDiskRule recorder     getModIfaceFromDiskAndIndexRule recorder     getModIfaceRule recorder     getModSummaryRule templateHaskellWarning recorder     getModuleGraphRule recorder+    getFileHashRule recorder     knownFilesRule recorder     getClientSettingsRule recorder     getHieAstsRule recorder
src/Development/IDE/Core/Shake.hs view
@@ -73,7 +73,8 @@     garbageCollectDirtyKeysOlderThan,     Log(..),     VFSModified(..), getClientConfigAction,-    ThreadQueue(..)+    ThreadQueue(..),+    runWithSignal     ) where  import           Control.Concurrent.Async@@ -82,7 +83,7 @@ import           Control.Concurrent.Strict import           Control.DeepSeq import           Control.Exception.Extra                hiding (bracket_)-import           Control.Lens                           ((&), (?~))+import           Control.Lens                           ((%~), (&), (?~)) import           Control.Monad.Extra import           Control.Monad.IO.Class import           Control.Monad.Reader@@ -123,9 +124,14 @@ import           Development.IDE.Core.PositionMapping import           Development.IDE.Core.ProgressReporting import           Development.IDE.Core.RuleTypes+import           Development.IDE.Types.Options          as Options+import qualified Language.LSP.Protocol.Message          as LSP+import qualified Language.LSP.Server                    as LSP+ import           Development.IDE.Core.Tracing import           Development.IDE.Core.WorkerThread import           Development.IDE.GHC.Compat             (NameCache,+                                                         NameCacheUpdater,                                                          initNameCache,                                                          knownKeyNames) import           Development.IDE.GHC.Orphans            ()@@ -146,25 +152,21 @@ import           Development.IDE.Types.KnownTargets import           Development.IDE.Types.Location import           Development.IDE.Types.Monitoring       (Monitoring (..))-import           Development.IDE.Types.Options import           Development.IDE.Types.Shake import qualified Focus import           GHC.Fingerprint import           GHC.Stack                              (HasCallStack)+import           GHC.TypeLits                           (KnownSymbol) import           HieDb.Types import           Ide.Logger                             hiding (Priority) import qualified Ide.Logger                             as Logger import           Ide.Plugin.Config import qualified Ide.PluginUtils                        as HLS-import           Ide.Types                              (IdePlugins (IdePlugins),-                                                         PluginDescriptor (pluginId),-                                                         PluginId)-import           Language.LSP.Diagnostics+import           Ide.Types import qualified Language.LSP.Protocol.Lens             as L import           Language.LSP.Protocol.Message import           Language.LSP.Protocol.Types import qualified Language.LSP.Protocol.Types            as LSP-import qualified Language.LSP.Server                    as LSP import           Language.LSP.VFS                       hiding (start) import qualified "list-t" ListT import           OpenTelemetry.Eventlog                 hiding (addEvent)@@ -173,20 +175,9 @@ import           System.FilePath                        hiding (makeRelative) import           System.IO.Unsafe                       (unsafePerformIO) import           System.Time.Extra+import           UnliftIO                               (MonadUnliftIO (withRunInIO)) --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           Data.IORef-import           Development.IDE.GHC.Compat             (NameCacheUpdater (NCU),-                                                         mkSplitUniqSupply,-                                                         upNameCache)-#endif--#if MIN_VERSION_ghc(9,3,0)-import           Development.IDE.GHC.Compat             (NameCacheUpdater)-#endif- data Log   = LogCreateHieDbExportsMapStart   | LogCreateHieDbExportsMapFinish !Int@@ -252,11 +243,10 @@ -- a worker thread. data HieDbWriter   = HieDbWriter-  { indexQueue         :: IndexQueue-  , indexPending       :: TVar (HMap.HashMap NormalizedFilePath Fingerprint) -- ^ Avoid unnecessary/out of date indexing-  , indexCompleted     :: TVar Int -- ^ to report progress-  , indexProgressToken :: Var (Maybe LSP.ProgressToken)-  -- ^ This is a Var instead of a TVar since we need to do IO to initialise/update, so we need a lock+  { indexQueue             :: IndexQueue+  , indexPending           :: TVar (HMap.HashMap NormalizedFilePath Fingerprint) -- ^ Avoid unnecessary/out of date indexing+  , indexCompleted         :: TVar Int -- ^ to report progress+  , indexProgressReporting :: ProgressReporting   }  -- | Actions to queue up on the index worker thread@@ -290,7 +280,7 @@     ,state :: Values     ,diagnostics :: STMDiagnosticStore     ,hiddenDiagnostics :: STMDiagnosticStore-    ,publishedDiagnostics :: STM.Map NormalizedUri [Diagnostic]+    ,publishedDiagnostics :: STM.Map NormalizedUri [FileDiagnostic]     -- ^ This represents the set of diagnostics that we have published.     -- Due to debouncing not every change might get published. @@ -306,7 +296,7 @@     -- positions in a version of that document to positions in the latest version     -- First mapping is delta from previous version and second one is an     -- accumulation to the current version.-    ,progress :: ProgressReporting+    ,progress :: PerFileProgressReporting     ,ideTesting :: IdeTesting     -- ^ Whether to enable additional lsp messages used by the test suite for checking invariants     ,restartShakeSession@@ -315,11 +305,7 @@         -> [DelayedAction ()]         -> IO [Key]         -> IO ()-#if MIN_VERSION_ghc(9,3,0)     ,ideNc :: NameCache-#else-    ,ideNc :: IORef NameCache-#endif     -- | A mapping of module name to known target (or candidate targets, if missing)     ,knownTargetsVar :: TVar (Hashed KnownTargets)     -- | A mapping of exported identifiers for local modules. Updated on kick@@ -677,12 +663,7 @@         restartQueue = tRestartQueue threadQueue         loaderQueue = tLoaderQueue threadQueue -#if MIN_VERSION_ghc(9,3,0)     ideNc <- initNameCache 'r' knownKeyNames-#else-    us <- mkSplitUniqSupply 'r'-    ideNc <- newIORef (initNameCache us knownKeyNames)-#endif     shakeExtras <- do         globals <- newTVarIO HMap.empty         state <- STM.newIO@@ -697,7 +678,10 @@         indexPending <- newTVarIO HMap.empty         indexCompleted <- newTVarIO 0         semanticTokensId <- newTVarIO 0-        indexProgressToken <- newVar Nothing+        indexProgressReporting <- progressReportingNoTrace+            (liftM2 (+) (length <$> readTVar indexPending) (readTVar indexCompleted))+            (readTVar indexCompleted)+            lspEnv "Indexing" optProgressStyle         let hiedbWriter = HieDbWriter{..}         exportsMap <- newTVarIO mempty         -- lazily initialize the exports map with the contents of the hiedb@@ -710,8 +694,8 @@          progress <-             if reportProgress-                then progressReporting lspEnv optProgressStyle-                else noProgressReporting+                then progressReporting lspEnv "Processing" optProgressStyle+                else noPerFileProgressReporting         actionQueue <- newQueue          let clientCapabilities = maybe def LSP.resClientCapabilities lspEnv@@ -775,6 +759,7 @@     for_ runner cancelShakeSession     void $ shakeDatabaseProfile shakeDb     progressStop $ progress shakeExtras+    progressStop $ indexProgressReporting $ hiedbWriter shakeExtras     stopMonitoring  @@ -1080,13 +1065,8 @@ askShake = ask  -#if MIN_VERSION_ghc(9,3,0) mkUpdater :: NameCache -> NameCacheUpdater mkUpdater = id-#else-mkUpdater :: IORef NameCache -> NameCacheUpdater-mkUpdater ref = NCU (upNameCache ref)-#endif  -- | A (maybe) stale result now, and an up to date one later data FastResult a = FastResult { stale :: Maybe (a,PositionMapping), uptoDate :: IO (Maybe a)  }@@ -1192,7 +1172,7 @@     extras <- getShakeExtras     let diagnostics ver diags = do             traceDiagnostics diags-            updateFileDiagnostics recorder file ver (newKey key) extras . map (\(_,y,z) -> (y,z)) $ diags+            updateFileDiagnostics recorder file ver (newKey key) extras diags     defineEarlyCutoff' diagnostics (==) key file old mode $ const $ op key file defineEarlyCutoff recorder (RuleNoDiagnostics op) = addRule $ \(Q (key, file)) (old :: Maybe BS.ByteString) mode -> otTracedAction key file mode traceA $ \traceDiagnostics -> do     let diagnostics _ver diags = do@@ -1211,7 +1191,7 @@     extras <- getShakeExtras     let diagnostics ver diags = do             traceDiagnostics diags-            updateFileDiagnostics recorder file ver (newKey key) extras . map (\(_,y,z) -> (y,z)) $ diags+            updateFileDiagnostics recorder file ver (newKey key) extras diags     defineEarlyCutoff' diagnostics (==) key file old mode $ op key file  defineNoFile :: IdeRule k v => Recorder (WithPriority Log) -> (k -> Action v) -> Rules ()@@ -1238,7 +1218,8 @@ defineEarlyCutoff' doDiagnostics cmp key file mbOld mode action = do     ShakeExtras{state, progress, dirtyKeys} <- getShakeExtras     options <- getIdeOptions-    (if optSkipProgress options key then id else inProgress progress file) $ do+    let trans g x =  withRunInIO $ \run -> g (run x)+    (if optSkipProgress options key then id else trans (inProgress progress file)) $ do         val <- case mbOld of             Just old | mode == RunDependenciesSame -> do                 mbValue <- liftIO $ atomicallyNamed "define - read 1" $ getValues state key file@@ -1265,7 +1246,7 @@                 (mbBs, (diags, mbRes)) <- actionCatch                     (do v <- action staleV; liftIO $ evaluate $ force v) $                     \(e :: SomeException) -> do-                        pure (Nothing, ([ideErrorText file $ T.pack $ show e | not $ isBadDependency e],Nothing))+                        pure (Nothing, ([ideErrorText file (T.pack $ show (key, file) ++ show e) | not $ isBadDependency e],Nothing))                  ver <- estimateFileVersionUnsafely key mbRes file                 (bs, res) <- case mbRes of@@ -1347,52 +1328,51 @@   -> Maybe Int32   -> Key   -> ShakeExtras-  -> [(ShowDiagnostic,Diagnostic)] -- ^ current results+  -> [FileDiagnostic] -- ^ current results   -> m ()-updateFileDiagnostics recorder fp ver k ShakeExtras{diagnostics, hiddenDiagnostics, publishedDiagnostics, debouncer, lspEnv, ideTesting} current0 =+updateFileDiagnostics recorder fp ver k ShakeExtras{diagnostics, hiddenDiagnostics, publishedDiagnostics, debouncer, lspEnv, ideTesting} current0 = do   liftIO $ withTrace ("update diagnostics " <> fromString(fromNormalizedFilePath fp)) $ \ addTag -> do     addTag "key" (show k)-    let (currentShown, currentHidden) = partition ((== ShowDiag) . fst) current+    let (currentShown, currentHidden) = partition ((== ShowDiag) . fdShouldShowDiagnostic) current         uri = filePathToUri' fp         addTagUnsafe :: String -> String -> String -> a -> a         addTagUnsafe msg t x v = unsafePerformIO(addTag (msg <> t) x) `seq` v-        update :: (forall a. String -> String -> a -> a) -> [Diagnostic] -> STMDiagnosticStore -> STM [Diagnostic]+        update :: (forall a. String -> String -> a -> a) -> [FileDiagnostic] -> STMDiagnosticStore -> STM [FileDiagnostic]         update addTagUnsafeMethod new store = addTagUnsafeMethod "count" (show $ Prelude.length new) $ setStageDiagnostics addTagUnsafeMethod uri ver (renderKey k) new store-        current = second diagsFromRule <$> current0+        current = map (fdLspDiagnosticL %~ diagsFromRule) current0     addTag "version" (show ver)     mask_ $ do         -- Mask async exceptions to ensure that updated diagnostics are always         -- published. Otherwise, we might never publish certain diagnostics if         -- an exception strikes between modifyVar but before         -- publishDiagnosticsNotification.-        newDiags <- liftIO $ atomicallyNamed "diagnostics - update" $ update (addTagUnsafe "shown ") (map snd currentShown) diagnostics-        _ <- liftIO $ atomicallyNamed "diagnostics - hidden" $ update (addTagUnsafe "hidden ") (map snd currentHidden) hiddenDiagnostics+        newDiags <- liftIO $ atomicallyNamed "diagnostics - update" $ update (addTagUnsafe "shown ") currentShown diagnostics+        _ <- liftIO $ atomicallyNamed "diagnostics - hidden" $ update (addTagUnsafe "hidden ") currentHidden hiddenDiagnostics         let uri' = filePathToUri' fp         let delay = if null newDiags then 0.1 else 0         registerEvent debouncer delay uri' $ withTrace ("report diagnostics " <> fromString (fromNormalizedFilePath fp)) $ \tag -> do-             join $ mask_ $ do-                 lastPublish <- atomicallyNamed "diagnostics - publish" $ STM.focus (Focus.lookupWithDefault [] <* Focus.insert newDiags) uri' publishedDiagnostics-                 let action = when (lastPublish /= newDiags) $ case lspEnv of+            join $ mask_ $ do+                lastPublish <- atomicallyNamed "diagnostics - publish" $ STM.focus (Focus.lookupWithDefault [] <* Focus.insert newDiags) uri' publishedDiagnostics+                let action = when (lastPublish /= newDiags) $ case lspEnv of                         Nothing -> -- Print an LSP event.-                            logWith recorder Info $ LogDiagsDiffButNoLspEnv (map (fp, ShowDiag,) newDiags)+                            logWith recorder Info $ LogDiagsDiffButNoLspEnv newDiags                         Just env -> LSP.runLspT env $ do                             liftIO $ tag "count" (show $ Prelude.length newDiags)                             liftIO $ tag "key" (show k)                             LSP.sendNotification SMethod_TextDocumentPublishDiagnostics $-                                LSP.PublishDiagnosticsParams (fromNormalizedUri uri') (fmap fromIntegral ver) newDiags-                 return action+                                LSP.PublishDiagnosticsParams (fromNormalizedUri uri') (fmap fromIntegral ver) (map fdLspDiagnostic newDiags)+                return action     where         diagsFromRule :: Diagnostic -> Diagnostic         diagsFromRule c@Diagnostic{_range}             | coerce ideTesting = c & L.relatedInformation ?~-                         [-                        DiagnosticRelatedInformation+                        [ DiagnosticRelatedInformation                             (Location                                 (filePathToUri $ fromNormalizedFilePath fp)                                 _range                             )                             (T.pack $ show k)-                            ]+                        ]             | otherwise = c  @@ -1403,26 +1383,28 @@ actionLogger = shakeRecorder <$> getShakeExtras  ---------------------------------------------------------------------------------type STMDiagnosticStore = STM.Map NormalizedUri StoreItem+type STMDiagnosticStore = STM.Map NormalizedUri StoreItem'+data StoreItem' = StoreItem' (Maybe Int32) FileDiagnosticsBySource+type FileDiagnosticsBySource = Map.Map (Maybe T.Text) (SL.SortedList FileDiagnostic) -getDiagnosticsFromStore :: StoreItem -> [Diagnostic]-getDiagnosticsFromStore (StoreItem _ diags) = concatMap SL.fromSortedList $ Map.elems diags+getDiagnosticsFromStore :: StoreItem' -> [FileDiagnostic]+getDiagnosticsFromStore (StoreItem' _ diags) = concatMap SL.fromSortedList $ Map.elems diags  updateSTMDiagnostics ::   (forall a. String -> String -> a -> a) ->   STMDiagnosticStore ->   NormalizedUri ->   Maybe Int32 ->-  DiagnosticsBySource ->-  STM [LSP.Diagnostic]+  FileDiagnosticsBySource ->+  STM [FileDiagnostic] updateSTMDiagnostics addTag store uri mv newDiagsBySource =     getDiagnosticsFromStore . fromJust <$> STM.focus (Focus.alter update *> Focus.lookup) uri store   where-    update (Just(StoreItem mvs dbs))+    update (Just(StoreItem' mvs dbs))       | addTag "previous version" (show mvs) $         addTag "previous count" (show $ Prelude.length $ filter (not.null) $ Map.elems dbs) False = undefined-      | mvs == mv = Just (StoreItem mv (newDiagsBySource <> dbs))-    update _ = Just (StoreItem mv newDiagsBySource)+      | mvs == mv = Just (StoreItem' mv (newDiagsBySource <> dbs))+    update _ = Just (StoreItem' mv newDiagsBySource)  -- | Sets the diagnostics for a file and compilation step --   if you want to clear the diagnostics call this with an empty list@@ -1431,9 +1413,9 @@     -> NormalizedUri     -> Maybe Int32 -- ^ the time that the file these diagnostics originate from was last edited     -> T.Text-    -> [LSP.Diagnostic]+    -> [FileDiagnostic]     -> STMDiagnosticStore-    -> STM [LSP.Diagnostic]+    -> STM [FileDiagnostic] setStageDiagnostics addTag uri ver stage diags ds = updateSTMDiagnostics addTag ds uri ver updatedDiags   where     !updatedDiags = Map.singleton (Just stage) $! SL.toSortedList diags@@ -1442,7 +1424,7 @@     STMDiagnosticStore ->     STM [FileDiagnostic] getAllDiagnostics =-    fmap (concatMap (\(k,v) -> map (fromUri k,ShowDiag,) $ getDiagnosticsFromStore v)) . ListT.toList . STM.listT+    fmap (concatMap (\(_,v) -> getDiagnosticsFromStore v)) . ListT.toList . STM.listT  updatePositionMapping :: IdeState -> VersionedTextDocumentIdentifier -> [TextDocumentContentChangeEvent] -> STM () updatePositionMapping IdeState{shakeExtras = ShakeExtras{positionMapping}} VersionedTextDocumentIdentifier{..} changes =@@ -1464,3 +1446,19 @@         EM.mapAccumRWithKey (\acc _k (delta, _) -> let new = addOldDelta delta acc in (new, (delta, acc)))             zeroMapping             (EM.insert ver (mkDelta changes, zeroMapping) mappingForUri)++-- | sends a signal whenever shake session is run/restarted+-- being used in cabal and hlint plugin tests to know when its time+-- to look for file diagnostics+kickSignal :: KnownSymbol s => Bool -> Maybe (LSP.LanguageContextEnv c) -> [NormalizedFilePath] -> Proxy s -> Action ()+kickSignal testing lspEnv files msg = when testing $ liftIO $ mRunLspT lspEnv $+  LSP.sendNotification (LSP.SMethod_CustomMethod msg) $+  toJSON $ map fromNormalizedFilePath files++-- | Add kick start/done signal to rule+runWithSignal :: (KnownSymbol s0, KnownSymbol s1, IdeRule k v) => Proxy s0 -> Proxy s1 -> [NormalizedFilePath] -> k -> Action ()+runWithSignal msgStart msgEnd files rule = do+  ShakeExtras{ideTesting = Options.IdeTesting testing, lspEnv} <- getShakeExtras+  kickSignal testing lspEnv files msgStart+  void $ uses rule files+  kickSignal testing lspEnv files msgEnd
src/Development/IDE/Core/Tracing.hs view
@@ -61,7 +61,7 @@ -- | Returns a logger that produces telemetry events in a single span. telemetryLogRecorder :: SpanInFlight -> Recorder (WithPriority (Doc a)) telemetryLogRecorder sp = Recorder $ \WithPriority {..} ->-  liftIO $ addEvent sp (fromString $ show priority) (encodeUtf8 $ trim $ renderStrict $ layoutCompact $ payload)+  liftIO $ addEvent sp (fromString $ show priority) (encodeUtf8 $ trim $ renderStrict $ layoutCompact payload)   where     -- eventlog message size is limited by EVENT_PAYLOAD_SIZE_MAX = STG_WORD16_MAX     trim = T.take (fromIntegral(maxBound :: Word16) - 10)
src/Development/IDE/Core/WorkerThread.hs view
@@ -10,10 +10,13 @@     (withWorkerQueue, awaitRunInThread)  where -import           Control.Concurrent.Async  (withAsync)+import           Control.Concurrent.Async  (AsyncCancelled (AsyncCancelled),+                                            withAsync) import           Control.Concurrent.STM import           Control.Concurrent.Strict (newBarrier, signalBarrier,                                             waitBarrier)+import           Control.Exception.Safe    (Exception (fromException),+                                            SomeException, throwIO, try) import           Control.Monad             (forever) import           Control.Monad.Cont        (ContT (ContT)) @@ -42,13 +45,15 @@                 workerAction l  -- | 'awaitRunInThread' queues up an 'IO' action to be run by a worker thread,--- and then blocks until the result is computed.+-- and then blocks until the result is computed. If the action throws an+-- non-async exception, it is rethrown in the calling thread. awaitRunInThread :: TQueue (IO ()) -> IO result -> IO result awaitRunInThread q act = do     -- Take an action from TQueue, run it and     -- use barrier to wait for the result     barrier <- newBarrier-    atomically $ writeTQueue q $ do-        res <- act-        signalBarrier barrier res-    waitBarrier barrier+    atomically $ writeTQueue q $ try act >>= signalBarrier barrier+    resultOrException <- waitBarrier barrier+    case resultOrException of+        Left e  -> throwIO (e :: SomeException)+        Right r -> return r
src/Development/IDE/GHC/CPP.hs view
@@ -22,16 +22,16 @@  -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import qualified GHC.Driver.Pipeline             as Pipeline-#endif--#if MIN_VERSION_ghc(9,3,0) && !MIN_VERSION_ghc(9,5,0)+#if !MIN_VERSION_ghc(9,5,0) import qualified GHC.Driver.Pipeline.Execute     as Pipeline #endif  #if MIN_VERSION_ghc(9,5,0) import qualified GHC.SysTools.Cpp                as Pipeline+#endif++#if MIN_VERSION_ghc(9,11,0)+import qualified GHC.SysTools.Tasks              as Pipeline #endif  #if MIN_VERSION_ghc(9,11,0)
src/Development/IDE/GHC/Compat.hs view
@@ -98,20 +98,9 @@     extract_cons,     recDotDot, -#if !MIN_VERSION_ghc(9,3,0)-    Dependencies(dep_mods),-    NameCacheUpdater(NCU),-    extendModSummaryNoDeps,-    emsModSummary,-    nonDetNameEnvElts,-    nonDetOccEnvElts,-    upNameCache,-#endif -#if MIN_VERSION_ghc(9,3,0)     Dependencies(dep_direct_mods),     NameCacheUpdater,-#endif  #if MIN_VERSION_ghc(9,5,0)     XModulePs(..),@@ -180,6 +169,7 @@ import           GHC.ByteCode.Types import           GHC.CoreToStg import           GHC.Data.Maybe+import           GHC.Driver.Config.Stg.Pipeline import           GHC.Driver.Env                          as Env import           GHC.Iface.Env import           GHC.Linker.Loader                       (loadDecls, loadExpr)@@ -192,24 +182,12 @@ import           GHC.Types.SrcLoc                        (combineRealSrcSpans) import           GHC.Unit.Home.ModInfo                   (HomePackageTable,                                                           lookupHpt)+import           GHC.Unit.Module.Deps                    (Dependencies (dep_direct_mods),+                                                          Usage (..)) import           GHC.Unit.Module.ModIface  -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           Data.IORef-import           GHC.Runtime.Interpreter-import           GHC.Unit.Module.Deps                    (Dependencies (dep_mods),-                                                          Usage (..))-import           GHC.Unit.Module.ModSummary-#endif--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Driver.Config.Stg.Pipeline-import           GHC.Unit.Module.Deps                    (Dependencies (dep_direct_mods),-                                                          Usage (..))-#endif- #if !MIN_VERSION_ghc(9,5,0) import           GHC.Core.Lint                           (lintInteractiveExpr) #endif@@ -234,35 +212,19 @@ nonDetFoldOccEnv = foldOccEnv #endif -#if !MIN_VERSION_ghc(9,3,0)-nonDetOccEnvElts :: OccEnv a -> [a]-nonDetOccEnvElts = occEnvElts-#endif  type ModIfaceAnnotation = Annotation -#if !MIN_VERSION_ghc(9,3,0)-nonDetNameEnvElts :: NameEnv a -> [a]-nonDetNameEnvElts = nameEnvElts-#endif  myCoreToStgExpr :: Logger -> DynFlags -> InteractiveContext-#if MIN_VERSION_ghc(9,3,0)             -> Bool-#endif                 -> Module -> ModLocation -> CoreExpr                 -> IO ( Id-#if MIN_VERSION_ghc(9,3,0)                       ,[CgStgTopBinding] -- output program-#else-                      ,[StgTopBinding] -- output program-#endif                       , InfoTableProvMap                       , CollectedCCs ) myCoreToStgExpr logger dflags ictxt-#if MIN_VERSION_ghc(9,3,0)                 for_bytecode-#endif                 this_mod ml prepd_expr = do     {- Create a temporary binding (just because myCoreToStg needs a        binding for the stg2stg step) -}@@ -278,30 +240,20 @@        myCoreToStg logger                    dflags                    ictxt-#if MIN_VERSION_ghc(9,3,0)                    for_bytecode-#endif                    this_mod                    ml                    [NonRec bco_tmp_id prepd_expr]     return (bco_tmp_id, stg_binds, prov_map, collected_ccs)  myCoreToStg :: Logger -> DynFlags -> InteractiveContext-#if MIN_VERSION_ghc(9,3,0)             -> Bool-#endif             -> Module -> ModLocation -> CoreProgram-#if MIN_VERSION_ghc(9,3,0)             -> IO ( [CgStgTopBinding] -- output program-#else-            -> IO ( [StgTopBinding] -- output program-#endif                   , InfoTableProvMap                   , CollectedCCs )  -- CAF cost centre info (declared and used) myCoreToStg logger dflags ictxt-#if MIN_VERSION_ghc(9,3,0)             for_bytecode-#endif             this_mod ml prepd_binds = do     let (stg_binds, denv, cost_centre_info)          = {-# SCC "Core2Stg" #-}@@ -321,7 +273,6 @@     stg_binds2 #endif         <- {-# SCC "Stg2Stg" #-}-#if MIN_VERSION_ghc(9,3,0)            stg2stg logger #if MIN_VERSION_ghc(9,5,0)                    (interactiveInScope ictxt)@@ -329,9 +280,6 @@                    ictxt #endif                    (initStgPipelineOpts dflags for_bytecode) this_mod stg_binds-#else-           stg2stg logger dflags ictxt this_mod stg_binds-#endif      return (stg_binds2, denv, cost_centre_info) @@ -342,11 +290,7 @@ #endif  getDependentMods :: ModIface -> [ModuleName]-#if MIN_VERSION_ghc(9,3,0) getDependentMods = map (gwib_mod . snd) . S.toList . dep_direct_mods . mi_deps-#else-getDependentMods = map gwib_mod . dep_mods . mi_deps-#endif  simplifyExpr :: DynFlags -> HscEnv -> CoreExpr -> IO CoreExpr #if MIN_VERSION_ghc(9,5,0)@@ -366,57 +310,48 @@  renderMessages :: PsMessages -> (Bag WarnMsg, Bag ErrMsg) renderMessages msgs =-#if MIN_VERSION_ghc(9,3,0)-  let renderMsgs extractor = (fmap . fmap) renderDiagnosticMessageWithHints . getMessages $ extractor msgs+#if MIN_VERSION_ghc(9,5,0)+  let renderMsgs extractor = (fmap . fmap) GhcPsMessage . getMessages $ extractor msgs   in (renderMsgs psWarnings, renderMsgs psErrors) #else-  msgs+  let renderMsgs extractor = (fmap . fmap) renderDiagnosticMessageWithHints . getMessages $ extractor msgs+  in (renderMsgs psWarnings, renderMsgs psErrors) #endif +#if MIN_VERSION_ghc(9,5,0)+pattern PFailedWithErrorMessages :: forall a b. (b -> Bag (MsgEnvelope GhcMessage)) -> ParseResult a+#else pattern PFailedWithErrorMessages :: forall a b. (b -> Bag (MsgEnvelope DecoratedSDoc)) -> ParseResult a+#endif pattern PFailedWithErrorMessages msgs-#if MIN_VERSION_ghc(9,3,0)-     <- PFailed (const . fmap (fmap renderDiagnosticMessageWithHints) . getMessages . getPsErrorMessages -> msgs)+#if MIN_VERSION_ghc(9,5,0)+     <- PFailed (const . fmap (fmap GhcPsMessage) . getMessages . getPsErrorMessages -> msgs) #else-     <- PFailed (const . fmap pprError . getErrorMessages -> msgs)+     <- PFailed (const . fmap (fmap renderDiagnosticMessageWithHints) . getMessages . getPsErrorMessages -> msgs) #endif {-# COMPLETE POk, PFailedWithErrorMessages #-}  hieExportNames :: HieFile -> [(SrcSpan, Name)] hieExportNames = nameListFromAvails . hie_exports -#if MIN_VERSION_ghc(9,3,0) type NameCacheUpdater = NameCache-#else -lookupNameCache :: Module -> OccName -> NameCache -> (NameCache, Name)--- Lookup up the (Module,OccName) in the NameCache--- If you find it, return it; if not, allocate a fresh original name and extend--- the NameCache.--- Reason: this may the first occurrence of (say) Foo.bar we have encountered.--- If we need to explore its value we will load Foo.hi; but meanwhile all we--- need is a Name for it.-lookupNameCache mod occ name_cache =-  case lookupOrigNameCache (nsNames name_cache) mod occ of {-    Just name -> (name_cache, name);-    Nothing   ->-        case takeUniqFromSupply (nsUniqs name_cache) of {-          (uniq, us) ->-              let-                name      = mkExternalName uniq mod occ noSrcSpan-                new_cache = extendNameCache (nsNames name_cache) mod occ name-              in (name_cache{ nsUniqs = us, nsNames = new_cache }, name) }}--upNameCache :: IORef NameCache -> (NameCache -> (NameCache, c)) -> IO c-upNameCache = updNameCache-#endif- mkHieFile' :: ModSummary            -> [Avail.AvailInfo]+#if MIN_VERSION_ghc(9,11,0)+           -> (HieASTs Type, NameEntityInfo)+#else            -> HieASTs Type+#endif            -> BS.ByteString            -> Hsc HieFile-mkHieFile' ms exports asts src = do+mkHieFile' ms exports+#if MIN_VERSION_ghc(9,11,0)+            (asts, entityInfo)+#else+            asts+#endif+            src = do   let Just src_file = ml_hs_file $ ms_location ms       (asts',arr) = compressTypes asts   return $ HieFile@@ -424,6 +359,9 @@       , hie_module = ms_mod ms       , hie_types = arr       , hie_asts = asts'+#if MIN_VERSION_ghc(9,11,0)+      , hie_entity_infos = entityInfo+#endif       -- mkIfaceExports sorts the AvailInfos for stability       , hie_exports = mkIfaceExports exports       , hie_hs_src = src@@ -515,18 +453,20 @@ generatedNodeInfo = Map.lookup GeneratedInfo . getSourcedNodeInfo . sourcedNodeInfo  data GhcVersion-  = GHC92-  | GHC94+  = GHC94   | GHC96   | GHC98   | GHC910+  | GHC912   deriving (Eq, Ord, Show, Enum)  ghcVersionStr :: String ghcVersionStr = VERSION_ghc  ghcVersion :: GhcVersion-#if MIN_VERSION_GLASGOW_HASKELL(9,10,0,0)+#if MIN_VERSION_GLASGOW_HASKELL(9,12,0,0)+ghcVersion = GHC912+#elif MIN_VERSION_GLASGOW_HASKELL(9,10,0,0) ghcVersion = GHC910 #elif MIN_VERSION_GLASGOW_HASKELL(9,8,0,0) ghcVersion = GHC98@@ -534,8 +474,6 @@ ghcVersion = GHC96 #elif MIN_VERSION_GLASGOW_HASKELL(9,4,0,0) ghcVersion = GHC94-#elif MIN_VERSION_GLASGOW_HASKELL(9,2,0,0)-ghcVersion = GHC92 #endif  simpleNodeInfoCompat :: FastStringCompat -> FastStringCompat -> NodeInfo a@@ -568,16 +506,7 @@     -> HscEnv     -> HscEnv loadModulesHome mod_infos e =-#if MIN_VERSION_ghc(9,3,0)   hscUpdateHUG (\hug -> foldl' (flip addHomeModInfoToHug) hug mod_infos) (e { hsc_type_env_vars = emptyKnotVars })-#else-  let !new_modules = addListToHpt (hsc_HPT e) [(mod_name x, x) | x <- mod_infos]-  in e { hsc_HPT = new_modules-       , hsc_type_env_var = Nothing-       }-    where-      mod_name = moduleName . mi_module . hm_iface-#endif  recDotDot :: HsRecFields (GhcPass p) arg -> Maybe Int recDotDot x =
src/Development/IDE/GHC/Compat/CmdLine.hs view
@@ -13,26 +13,7 @@         , liftEwM     ) where -#if MIN_VERSION_ghc(9,3,0) import           GHC.Driver.CmdLine-import           GHC.Driver.Session     (CmdLineP (..), getCmdLineState,-                                         processCmdLineP, putCmdLineState)-#else-import           Control.Monad.IO.Class-import           GHC                    (Located)-import           GHC.Driver.CmdLine-#endif+import           GHC.Driver.Session (CmdLineP (..), getCmdLineState,+                                     processCmdLineP, putCmdLineState) -#if !MIN_VERSION_ghc(9,3,0)--- | A helper to parse a set of flags from a list of command-line arguments, handling--- response files.-processCmdLineP-    :: forall s m. MonadIO m-    => [Flag (CmdLineP s)]  -- ^ valid flags to match against-    -> s                    -- ^ current state-    -> [Located String]     -- ^ arguments to parse-    -> m (([Located String], [Err], [Warn]), s)-                            -- ^ (leftovers, errors, warnings)-processCmdLineP activeFlags s0 args =-    pure $ runCmdLine (processArgs activeFlags args) s0-#endif
src/Development/IDE/GHC/Compat/Core.hs view
@@ -58,9 +58,6 @@     pattern ExposePackage,     parseDynamicFlagsCmdLine,     parseDynamicFilePragma,-#if !MIN_VERSION_ghc(9,3,0)-    WarnReason(..),-#endif     wWarningFlags,     updOptLevel,     -- slightly unsafe@@ -72,12 +69,14 @@     IfaceTyCon(..),     ModIface,     ModIface_(..),+#if MIN_VERSION_ghc(9,11,0)+    pattern ModIface,+    set_mi_top_env,+    set_mi_usages,+#endif     HscSource(..),     WhereFrom(..),     loadInterface,-#if !MIN_VERSION_ghc(9,3,0)-    SourceModified(..),-#endif     loadModuleInterface,     RecompileRequired(..),     mkPartialIface,@@ -236,7 +235,11 @@     ModuleOrigin(..),     PackageName(..),     -- * Linker+#if MIN_VERSION_ghc(9,11,0)+    LinkablePart(..),+#else     Unlinked(..),+#endif     Linkable(..),     unload,     -- * Hooks@@ -359,7 +362,6 @@     module GHC.Parser.Header,     module GHC.Parser.Lexer,     module GHC.Utils.Panic,-#if MIN_VERSION_ghc(9,3,0)     CompileReason(..),     hsc_type_env_vars,     hscUpdateHUG, hsc_HUG,@@ -372,7 +374,6 @@     module GHC.Unit.Finder.Types,     module GHC.Unit.Env,     module GHC.Driver.Phases,-#endif #if !MIN_VERSION_ghc(9,4,0)     pattern HsFieldBind,     hfbAnn,@@ -460,7 +461,7 @@ import           GHC.Tc.Utils.Env import           GHC.Tc.Utils.Monad          hiding (Applicative (..), IORef,                                               MonadFix (..), MonadIO (..), allM,-                                              anyM, concatMapM, mapMaybeM,+                                              anyM, concatMapM, mapMaybeM, foldMapM,                                               (<$>)) import           GHC.Tc.Utils.TcType         as TcType import qualified GHC.Types.Avail             as Avail@@ -495,12 +496,15 @@ import           Data.Foldable               (toList) import           GHC.Core.Multiplicity       (scaledThing) import           GHC.Data.Bag+import qualified GHC.Data.Strict             as Strict+import qualified GHC.Driver.Config.Finder    as GHC+import qualified GHC.Driver.Config.Tidy      as GHC import           GHC.Driver.Env-import           GHC.Hs                       (HsModule (..))-#if !MIN_VERSION_ghc(9,9,0)-import           GHC.Hs                       (SrcSpanAnn')-#endif-import           GHC.Hs.Decls                 hiding (FunDep)+import           GHC.Driver.Env              as GHCi+import           GHC.Driver.Env.KnotVars+import           GHC.Driver.Errors.Types+import           GHC.Hs                      (HsModule (..))+import           GHC.Hs.Decls                hiding (FunDep) import           GHC.Hs.Doc import           GHC.Hs.Expr import           GHC.Hs.Extension@@ -524,73 +528,66 @@ import           GHC.Types.Target            (Target (..), TargetId (..)) import           GHC.Types.TyThing import           GHC.Types.TyThing.Ppr+import           GHC.Types.Unique+import           GHC.Types.Unique.Map+import           GHC.Unit.Env import           GHC.Unit.Finder             hiding (mkHomeModLocation)+import qualified GHC.Unit.Finder             as GHC+import           GHC.Unit.Finder.Types import           GHC.Unit.Home.ModInfo+import           GHC.Unit.Module.Graph import           GHC.Unit.Module.Imported import           GHC.Unit.Module.ModDetails import           GHC.Unit.Module.ModGuts+#if !MIN_VERSION_ghc(9,9,0)+import           GHC.Hs                      (SrcSpanAnn')+#endif import           GHC.Unit.Module.ModIface    (IfaceExport, ModIface,-                                              ModIface_ (..), mi_fix)+                                              ModIface_ (..), mi_fix+#if MIN_VERSION_ghc(9,11,0)+                                             , pattern ModIface+                                             , set_mi_top_env+                                             , set_mi_usages+#endif+                                             ) import           GHC.Unit.Module.ModSummary  (ModSummary (..))+import           GHC.Utils.Error             (mkPlainErrorMsgEnvelope)+import           GHC.Utils.Panic+import           GHC.Utils.TmpFs import           Language.Haskell.Syntax     hiding (FunDep) --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Types.SourceFile        (SourceModified (..))-import qualified GHC.Unit.Finder             as GHC-import           GHC.Unit.Module.Graph       (mkModuleGraph)-#endif+-- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if MIN_VERSION_ghc(9,3,0)-import qualified GHC.Data.Strict             as Strict-import qualified GHC.Driver.Config.Finder    as GHC-import qualified GHC.Driver.Config.Tidy      as GHC-import           GHC.Driver.Env              as GHCi-import           GHC.Driver.Env.KnotVars-import           GHC.Driver.Errors.Types-import           GHC.Types.Unique-import           GHC.Types.Unique.Map-import           GHC.Unit.Env-import qualified GHC.Unit.Finder             as GHC-import           GHC.Unit.Finder.Types-import           GHC.Unit.Module.Graph-import           GHC.Utils.Error             (mkPlainErrorMsgEnvelope)-import           GHC.Utils.Panic-import           GHC.Utils.TmpFs+#if MIN_VERSION_ghc(9,11,0)+import System.OsPath #endif  #if !MIN_VERSION_ghc(9,7,0) import           GHC.Types.Avail             (greNamePrintableName) #endif +#if !MIN_VERSION_ghc(9,9,0)+import           GHC.Hs                      (SrcSpanAnn')+#endif+ mkHomeModLocation :: DynFlags -> ModuleName -> FilePath -> IO Module.ModLocation-#if MIN_VERSION_ghc(9,3,0)-mkHomeModLocation df mn f = pure $ GHC.mkHomeModLocation (GHC.initFinderOpts df) mn f+#if MIN_VERSION_ghc(9,11,0)+mkHomeModLocation df mn f =+  let osf = unsafeEncodeUtf f+  in pure $ GHC.mkHomeModLocation (GHC.initFinderOpts df) mn osf #else-mkHomeModLocation = GHC.mkHomeModLocation+mkHomeModLocation df mn f = pure $ GHC.mkHomeModLocation (GHC.initFinderOpts df) mn f #endif -#if MIN_VERSION_ghc(9,3,0) pattern RealSrcSpan :: SrcLoc.RealSrcSpan -> Maybe BufSpan -> SrcLoc.SrcSpan-#else-pattern RealSrcSpan :: SrcLoc.RealSrcSpan -> Maybe BufSpan -> SrcLoc.SrcSpan-#endif -#if MIN_VERSION_ghc(9,3,0) pattern RealSrcSpan x y <- SrcLoc.RealSrcSpan x ((\case Strict.Nothing -> Nothing; Strict.Just a -> Just a) -> y) where   RealSrcSpan x y = SrcLoc.RealSrcSpan x (case y of Nothing -> Strict.Nothing; Just a -> Strict.Just a) -#else-pattern RealSrcSpan x y = SrcLoc.RealSrcSpan x y-#endif {-# COMPLETE RealSrcSpan, UnhelpfulSpan #-} -#if MIN_VERSION_ghc(9,3,0) pattern RealSrcLoc :: SrcLoc.RealSrcLoc -> Strict.Maybe BufPos-> SrcLoc.SrcLoc-#else-pattern RealSrcLoc :: SrcLoc.RealSrcLoc -> Maybe BufPos-> SrcLoc.SrcLoc-#endif pattern RealSrcLoc x y = SrcLoc.RealSrcLoc x y {-# COMPLETE RealSrcLoc, UnhelpfulLoc #-} @@ -664,6 +661,8 @@ #if MIN_VERSION_ghc(9,9,0) instance HasSrcSpan (SrcLoc.GenLocated (EpAnn ann) a) where   getLoc (L l _) = getLoc l+instance HasSrcSpan (SrcLoc.GenLocated (GHC.EpaLocation) a) where+  getLoc = GHC.getHasLoc #else instance HasSrcSpan (SrcSpanAnn' ann) where   getLoc = GHC.locA@@ -703,7 +702,7 @@ loadDLL :: HscEnv -> String -> IO (Maybe String) loadDLL env str = do     res <- GHCi.loadDLL (GHCi.hscInterp env) str-#if MIN_VERSION_ghc(9,11,0)+#if MIN_VERSION_ghc(9,11,0) || (MIN_VERSION_ghc(9, 8, 3) && !MIN_VERSION_ghc(9, 9, 0))     pure $       case res of         Left err_msg -> Just err_msg@@ -718,12 +717,6 @@     (GHCi.hscInterp hsc_env)     hsc_env linkables -#if !MIN_VERSION_ghc(9,3,0)-setOutputFile :: FilePath -> DynFlags -> DynFlags-setOutputFile f d = d {-  outputFile_    = Just f-  }-#endif  isSubspanOfA :: LocatedAn la a -> LocatedAn lb b -> Bool isSubspanOfA a b = SrcLoc.isSubspanOf (GHC.getLocA a) (GHC.getLocA b)@@ -744,7 +737,7 @@ #endif     ,gre_par, gre_lcl, gre_imp = (toList -> gre_imp)} -collectHsBindsBinders :: CollectPass p => Bag (XRec p (HsBindLR p idR)) -> [IdP p]+collectHsBindsBinders :: CollectPass p => LHsBindsLR p idR -> [IdP p] collectHsBindsBinders x = GHC.collectHsBindsBinders CollNoDictBinders x  @@ -752,54 +745,28 @@ makeSimpleDetails :: HscEnv -> TcGblEnv -> IO ModDetails makeSimpleDetails hsc_env =   GHC.makeSimpleDetails-#if MIN_VERSION_ghc(9,3,0)               (hsc_logger hsc_env)-#else-              hsc_env-#endif  mkIfaceTc :: HscEnv -> GHC.SafeHaskellMode -> ModDetails -> ModSummary -> Maybe CoreProgram -> TcGblEnv -> IO ModIface mkIfaceTc hscEnv shm md _ms _mcp = #if MIN_VERSION_ghc(9,5,0)   GHC.mkIfaceTc hscEnv shm md _ms _mcp -- mcp::Maybe CoreProgram is only used in GHC >= 9.6-#elif MIN_VERSION_ghc(9,3,0)-  GHC.mkIfaceTc hscEnv shm md _ms -- ms::ModSummary is only used in GHC >= 9.4 #else-  GHC.mkIfaceTc hscEnv shm md+  GHC.mkIfaceTc hscEnv shm md _ms -- ms::ModSummary is only used in GHC >= 9.4 #endif  mkBootModDetailsTc :: HscEnv -> TcGblEnv -> IO ModDetails mkBootModDetailsTc session = GHC.mkBootModDetailsTc-#if MIN_VERSION_ghc(9,3,0)           (hsc_logger session)-#else-          session-#endif -#if !MIN_VERSION_ghc(9,3,0)-type TidyOpts = HscEnv-#endif  initTidyOpts :: HscEnv -> IO TidyOpts initTidyOpts =-#if MIN_VERSION_ghc(9,3,0)   GHC.initTidyOpts-#else-  pure-#endif -#if MIN_VERSION_ghc(9,3,0) driverNoStop :: StopPhase driverNoStop = NoStop-#else-driverNoStop :: Phase-driverNoStop = StopLn-#endif -#if !MIN_VERSION_ghc(9,3,0)-hscUpdateHPT :: (HomePackageTable -> HomePackageTable) -> HscEnv -> HscEnv-hscUpdateHPT k session = session { hsc_HPT = k (hsc_HPT session) }-#endif  #if !MIN_VERSION_ghc(9,4,0) pattern HsFieldBind :: XHsRecField id -> id -> arg -> Bool -> HsRecField' id arg@@ -846,11 +813,7 @@ #endif  mkSimpleTarget :: DynFlags -> FilePath -> Target-#if MIN_VERSION_ghc(9,3,0) mkSimpleTarget df fp = Target (TargetFile fp Nothing) True (homeUnitId_ df) Nothing-#else-mkSimpleTarget _ fp = Target (TargetFile fp Nothing) True Nothing-#endif  #if MIN_VERSION_ghc(9,7,0) lookupGlobalRdrEnv gre_env occ = lookupGRE gre_env (LookupOccName occ AllRelevantGREs)
+ src/Development/IDE/GHC/Compat/Driver.hs view
@@ -0,0 +1,155 @@+-- ============================================================================+-- DO NOT EDIT+-- This module copies parts of the driver code in GHC.Driver.Main to provide+-- `hscTypecheckRenameWithDiagnostics`.+-- Issue to add this function: https://gitlab.haskell.org/ghc/ghc/-/issues/24996+-- MR to add this function: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/12891+-- ============================================================================++{-# LANGUAGE CPP #-}++module Development.IDE.GHC.Compat.Driver+    ( hscTypecheckRenameWithDiagnostics+    ) where++#if MIN_VERSION_ghc(9,11,0)++import           GHC.Driver.Main            (hscTypecheckRenameWithDiagnostics)++#else++import           Control.Monad+import           GHC.Core+import           GHC.Data.FastString+import           GHC.Data.Maybe+import           GHC.Driver.Env+import           GHC.Driver.Errors.Types+import           GHC.Driver.Main+import           GHC.Driver.Session+import           GHC.Hs+import           GHC.Hs.Dump+import           GHC.Iface.Ext.Ast          (mkHieFile)+import           GHC.Iface.Ext.Binary       (hie_file_result, readHieFile,+                                             writeHieFile)+import           GHC.Iface.Ext.Debug        (diffFile, validateScopes)+import           GHC.Iface.Ext.Types        (getAsts, hie_asts, hie_module)+import           GHC.Tc.Module+import           GHC.Tc.Utils.Monad+import           GHC.Types.SourceFile+import           GHC.Types.SrcLoc+import           GHC.Unit+import           GHC.Unit.Module.ModDetails+import           GHC.Unit.Module.ModIface+import           GHC.Unit.Module.ModSummary+import           GHC.Utils.Error+import           GHC.Utils.Logger+import           GHC.Utils.Outputable+import           GHC.Utils.Panic.Plain++hscTypecheckRenameWithDiagnostics :: HscEnv -> ModSummary -> HsParsedModule+                   -> IO ((TcGblEnv, RenamedStuff), Messages GhcMessage)+hscTypecheckRenameWithDiagnostics hsc_env mod_summary rdr_module =+    runHsc' hsc_env $ hsc_typecheck True mod_summary (Just rdr_module)++-- ============================================================================+-- DO NOT EDIT - Refer to top of file+-- ============================================================================+hsc_typecheck :: Bool -- ^ Keep renamed source?+              -> ModSummary -> Maybe HsParsedModule+              -> Hsc (TcGblEnv, RenamedStuff)+hsc_typecheck keep_rn mod_summary mb_rdr_module = do+    hsc_env <- getHscEnv+    let hsc_src = ms_hsc_src mod_summary+        dflags = hsc_dflags hsc_env+        home_unit = hsc_home_unit hsc_env+        outer_mod = ms_mod mod_summary+        mod_name = moduleName outer_mod+        outer_mod' = mkHomeModule home_unit mod_name+        inner_mod = homeModuleNameInstantiation home_unit mod_name+        src_filename  = ms_hspp_file mod_summary+        real_loc = realSrcLocSpan $ mkRealSrcLoc (mkFastString src_filename) 1 1+        keep_rn' = gopt Opt_WriteHie dflags || keep_rn+    massert (isHomeModule home_unit outer_mod)+    tc_result <- if hsc_src == HsigFile && not (isHoleModule inner_mod)+        then ioMsgMaybe $ hoistTcRnMessage $ tcRnInstantiateSignature hsc_env outer_mod' real_loc+        else+         do hpm <- case mb_rdr_module of+                    Just hpm -> return hpm+                    Nothing  -> hscParse' mod_summary+            tc_result0 <- tcRnModule' mod_summary keep_rn' hpm+            if hsc_src == HsigFile+                then+#if MIN_VERSION_ghc(9,5,0)+                     do (iface, _) <- liftIO $ hscSimpleIface hsc_env Nothing tc_result0 mod_summary+#else+                     do (iface, _) <- liftIO $ hscSimpleIface hsc_env tc_result0 mod_summary+#endif+                        ioMsgMaybe $ hoistTcRnMessage $+                            tcRnMergeSignatures hsc_env hpm tc_result0 iface+                else return tc_result0+    rn_info <- extract_renamed_stuff mod_summary tc_result+    return (tc_result, rn_info)++-- ============================================================================+-- DO NOT EDIT - Refer to top of file+-- ============================================================================+extract_renamed_stuff :: ModSummary -> TcGblEnv -> Hsc RenamedStuff+extract_renamed_stuff mod_summary tc_result = do+    let rn_info = getRenamedStuff tc_result++    dflags <- getDynFlags+    logger <- getLogger+    liftIO $ putDumpFileMaybe logger Opt_D_dump_rn_ast "Renamer"+                FormatHaskell (showAstData NoBlankSrcSpan NoBlankEpAnnotations rn_info)++    -- Create HIE files+    when (gopt Opt_WriteHie dflags) $ do+        -- I assume this fromJust is safe because `-fwrite-hie-file`+        -- enables the option which keeps the renamed source.+        hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info)+        let out_file = ml_hie_file $ ms_location mod_summary+        liftIO $ writeHieFile out_file hieFile+        liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile)++        -- Validate HIE files+        when (gopt Opt_ValidateHie dflags) $ do+            hs_env <- Hsc $ \e w -> return (e, w)+            liftIO $ do+              -- Validate Scopes+              case validateScopes (hie_module hieFile) $ getAsts $ hie_asts hieFile of+                  [] -> putMsg logger $ text "Got valid scopes"+                  xs -> do+                    putMsg logger $ text "Got invalid scopes"+                    mapM_ (putMsg logger) xs+              -- Roundtrip testing+              file' <- readHieFile (hsc_NC hs_env) out_file+              case diffFile hieFile (hie_file_result file') of+                [] ->+                  putMsg logger $ text "Got no roundtrip errors"+                xs -> do+                  putMsg logger $ text "Got roundtrip errors"+                  let logger' = updateLogFlags logger (log_set_dopt Opt_D_ppr_debug)+                  mapM_ (putMsg logger') xs+    return rn_info++-- ============================================================================+-- DO NOT EDIT - Refer to top of file+-- ============================================================================+#if MIN_VERSION_ghc(9,5,0)+hscSimpleIface :: HscEnv+               -> Maybe CoreProgram+               -> TcGblEnv+               -> ModSummary+               -> IO (ModIface, ModDetails)+hscSimpleIface hsc_env mb_core_program tc_result summary+    = runHsc hsc_env $ hscSimpleIface' mb_core_program tc_result summary+#else+hscSimpleIface :: HscEnv+               -> TcGblEnv+               -> ModSummary+               -> IO (ModIface, ModDetails)+hscSimpleIface hsc_env tc_result summary+    = runHsc hsc_env $ hscSimpleIface' tc_result summary+#endif++#endif
src/Development/IDE/GHC/Compat/Env.hs view
@@ -4,11 +4,7 @@ -- 'UnitEnv' and some DynFlags compat functions. module Development.IDE.GHC.Compat.Env (     Env.HscEnv(hsc_FC, hsc_NC, hsc_IC, hsc_mod_graph-#if MIN_VERSION_ghc(9,3,0)               , hsc_type_env_vars-#else-              , hsc_type_env_var-#endif               ),     Env.hsc_HPT,     InteractiveContext(..),@@ -19,9 +15,6 @@     Env.hsc_logger,     Env.hsc_tmpfs,     Env.hsc_unit_env,-#if !MIN_VERSION_ghc(9,3,0)-    Env.hsc_unit_dbs,-#endif     Env.hsc_hooks,     hscSetHooks,     TmpFs,@@ -64,6 +57,7 @@ import           GHC                 (setInteractiveDynFlags)  import           GHC.Driver.Backend  as Backend+import           GHC.Driver.Env      (HscEnv, hscSetActiveUnitId) import qualified GHC.Driver.Env      as Env import           GHC.Driver.Hooks    (Hooks) import           GHC.Driver.Session@@ -76,41 +70,12 @@ import           GHC.Utils.Logger import           GHC.Utils.TmpFs --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import qualified Data.Set            as S-import           GHC.Driver.Env      (HscEnv, hsc_EPS)-#endif--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Driver.Env      (HscEnv, hscSetActiveUnitId)-#endif---#if !MIN_VERSION_ghc(9,3,0)-hscSetActiveUnitId :: UnitId -> HscEnv -> HscEnv-hscSetActiveUnitId _ env = env--reexportedModules :: HscEnv -> S.Set a-reexportedModules _ = S.empty-#endif--#if MIN_VERSION_ghc(9,3,0) hsc_EPS :: HscEnv -> UnitEnv hsc_EPS = Env.hsc_unit_env-#endif -#if !MIN_VERSION_ghc(9,3,0)-workingDirectory :: a -> Maybe b-workingDirectory _ = Nothing- setWorkingDirectory :: FilePath -> DynFlags -> DynFlags-setWorkingDirectory = const id-#else-setWorkingDirectory :: FilePath -> DynFlags -> DynFlags setWorkingDirectory p d = d { workingDirectory =  Just p }-#endif  setHomeUnitId_ :: UnitId -> DynFlags -> DynFlags setHomeUnitId_ uid df = df { Session.homeUnitId_ = uid }
+ src/Development/IDE/GHC/Compat/Error.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE CPP             #-}+{-# LANGUAGE TemplateHaskell #-}+module Development.IDE.GHC.Compat.Error (+  -- * Top-level error types and lens for easy access+  MsgEnvelope(..),+  msgEnvelopeErrorL,+  GhcMessage(..),+  -- * Error messages for the typechecking and renamer phase+  TcRnMessage (..),+  TcRnMessageDetailed (..),+  stripTcRnMessageContext,+  -- * Parsing error message+  PsMessage(..),+  -- * Desugaring diagnostic+  DsMessage (..),+  -- * Driver error message+  DriverMessage (..),+  -- * General Diagnostics+  Diagnostic(..),+  -- * Prisms for error selection+  _TcRnMessage,+  _GhcPsMessage,+  _GhcDsMessage,+  _GhcDriverMessage,+  ) where++import           Control.Lens+import           GHC.Driver.Errors.Types+import           GHC.HsToCore.Errors.Types+import           GHC.Tc.Errors.Types+import           GHC.Types.Error++_TcRnMessage :: Prism' GhcMessage TcRnMessage+_TcRnMessage = prism' GhcTcRnMessage (\case+  GhcTcRnMessage tcRnMsg -> Just tcRnMsg+  _ -> Nothing)++_GhcPsMessage :: Prism' GhcMessage PsMessage+_GhcPsMessage = prism' GhcPsMessage (\case+  GhcPsMessage psMsg -> Just psMsg+  _ -> Nothing)++_GhcDsMessage :: Prism' GhcMessage DsMessage+_GhcDsMessage = prism' GhcDsMessage (\case+  GhcDsMessage dsMsg -> Just dsMsg+  _ -> Nothing)++_GhcDriverMessage :: Prism' GhcMessage DriverMessage+_GhcDriverMessage = prism' GhcDriverMessage (\case+  GhcDriverMessage driverMsg -> Just driverMsg+  _ -> Nothing)++-- | Some 'TcRnMessage's are nested in other constructors for additional context.+-- For example, 'TcRnWithHsDocContext' and 'TcRnMessageWithInfo'.+-- However, in some occasions you don't need the additional context and you just want+-- the error message. @'stripTcRnMessageContext'@ recursively unwraps these constructors,+-- until there are no more constructors with additional context.+--+stripTcRnMessageContext :: TcRnMessage -> TcRnMessage+stripTcRnMessageContext = \case+#if MIN_VERSION_ghc(9, 6, 1)+  TcRnWithHsDocContext _ tcMsg -> stripTcRnMessageContext tcMsg+#endif+  TcRnMessageWithInfo _ (TcRnMessageDetailed _ tcMsg) -> stripTcRnMessageContext tcMsg+  msg -> msg++msgEnvelopeErrorL :: Lens' (MsgEnvelope e) e+msgEnvelopeErrorL = lens errMsgDiagnostic (\envelope e -> envelope { errMsgDiagnostic = e } )
src/Development/IDE/GHC/Compat/Iface.hs view
@@ -9,25 +9,22 @@ import           Development.IDE.GHC.Compat.Env import           Development.IDE.GHC.Compat.Outputable import           GHC+import           GHC.Driver.Session                    (targetProfile) import qualified GHC.Iface.Load                        as Iface import           GHC.Unit.Finder.Types                 (FindResult)  -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if MIN_VERSION_ghc(9,3,0)-import           GHC.Driver.Session                    (targetProfile)-#endif- #if MIN_VERSION_ghc(9,7,0) import           GHC.Iface.Errors.Ppr                  (missingInterfaceErrorDiagnostic) import           GHC.Iface.Errors.Types                (IfaceMessage) #endif  writeIfaceFile :: HscEnv -> FilePath -> ModIface -> IO ()-#if MIN_VERSION_ghc(9,3,0)+#if MIN_VERSION_ghc(9,11,0)+writeIfaceFile env fp iface = Iface.writeIface (hsc_logger env) (targetProfile $ hsc_dflags env) (Iface.flagsToIfCompression $ hsc_dflags env) fp iface+#elif MIN_VERSION_ghc(9,3,0) writeIfaceFile env fp iface = Iface.writeIface (hsc_logger env) (targetProfile $ hsc_dflags env) fp iface-#else-writeIfaceFile env fp iface = Iface.writeIface (hsc_logger env) (hsc_dflags env) fp iface #endif  cannotFindModule :: HscEnv -> ModuleName -> FindResult -> SDoc
src/Development/IDE/GHC/Compat/Logger.hs view
@@ -14,20 +14,14 @@ import           Development.IDE.GHC.Compat.Outputable  +import           GHC.Types.Error import           GHC.Utils.Logger                      as Logger import           GHC.Utils.Outputable --- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Types.Error-#endif- putLogHook :: Logger -> HscEnv -> HscEnv putLogHook logger env =   env { hsc_logger = logger } -#if MIN_VERSION_ghc(9,3,0) type LogActionCompat = LogFlags -> Maybe DiagnosticReason -> Maybe Severity -> SrcSpan -> PrintUnqualified -> SDoc -> IO ()  -- alwaysQualify seems to still do the right thing here, according to the "unqualified warnings" test.@@ -41,11 +35,3 @@ #endif logActionCompat logAction logFlags _cls loc = logAction logFlags Nothing Nothing loc alwaysQualify -#else-type LogActionCompat = DynFlags -> WarnReason -> Severity -> SrcSpan -> PrintUnqualified -> SDoc -> IO ()---- alwaysQualify seems to still do the right thing here, according to the "unqualified warnings" test.-logActionCompat :: LogActionCompat -> LogAction-logActionCompat logAction dynFlags wr severity loc = logAction dynFlags wr severity loc alwaysQualify--#endif
src/Development/IDE/GHC/Compat/Outputable.hs view
@@ -24,7 +24,6 @@     initDiagOpts,     pprMessages, #endif-#if MIN_VERSION_ghc(9,3,0)     DiagnosticReason(..),     renderDiagnosticMessageWithHints,     pprMsgEnvelopeBagWithLoc,@@ -34,10 +33,6 @@     errMsgDiagnostic,     unDecorated,     diagnosticMessage,-#else-    pprWarning,-    pprError,-#endif     -- * Error infrastructure     DecoratedSDoc,     MsgEnvelope,@@ -53,33 +48,24 @@     textDoc,     ) where +import           Data.Maybe+import           GHC.Driver.Config.Diagnostic import           GHC.Driver.Env import           GHC.Driver.Ppr import           GHC.Driver.Session+import           GHC.Parser.Errors.Types import qualified GHC.Types.Error              as Error import           GHC.Types.Name.Ppr import           GHC.Types.Name.Reader import           GHC.Types.SourceError import           GHC.Types.SrcLoc import           GHC.Unit.State+import           GHC.Utils.Error import           GHC.Utils.Outputable         as Out import           GHC.Utils.Panic  -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Parser.Errors-import qualified GHC.Parser.Errors.Ppr        as Ppr-import           GHC.Utils.Error              hiding (mkWarnMsg)-#endif--#if MIN_VERSION_ghc(9,3,0)-import           Data.Maybe-import           GHC.Driver.Config.Diagnostic-import           GHC.Parser.Errors.Types-import           GHC.Utils.Error-#endif- #if MIN_VERSION_ghc(9,5,0) import           GHC.Driver.Errors.Types      (DriverMessage, GhcMessage) #endif@@ -114,41 +100,29 @@     doc' = pprWithUnitState emptyUnitState doc  -#if !MIN_VERSION_ghc(9,3,0)-pprWarning :: PsWarning -> MsgEnvelope DecoratedSDoc-pprWarning =-  Ppr.pprWarning -pprError :: PsError -> MsgEnvelope DecoratedSDoc-pprError =-  Ppr.pprError-#endif- formatErrorWithQual :: DynFlags -> MsgEnvelope DecoratedSDoc -> String formatErrorWithQual dflags e =   showSDoc dflags (pprNoLocMsgEnvelope e) -#if MIN_VERSION_ghc(9,3,0) pprNoLocMsgEnvelope :: MsgEnvelope DecoratedSDoc -> SDoc-#else-pprNoLocMsgEnvelope :: Error.RenderableDiagnostic e => MsgEnvelope e -> SDoc-#endif pprNoLocMsgEnvelope (MsgEnvelope { errMsgDiagnostic = e                                  , errMsgContext   = unqual })   = sdocWithContext $ \_ctx ->     withErrStyle unqual $ #if MIN_VERSION_ghc(9,7,0)       formatBulleted e-#elif MIN_VERSION_ghc(9,3,0)-      formatBulleted _ctx $ e #else-      formatBulleted _ctx $ Error.renderDiagnostic e+      formatBulleted _ctx e #endif   +#if MIN_VERSION_ghc(9,5,0)+type ErrMsg  = MsgEnvelope GhcMessage+type WarnMsg  = MsgEnvelope GhcMessage+#else type ErrMsg  = MsgEnvelope DecoratedSDoc-#if MIN_VERSION_ghc(9,3,0) type WarnMsg  = MsgEnvelope DecoratedSDoc #endif @@ -165,7 +139,6 @@   mkPrintUnqualified (hsc_unit_env env) #endif -#if MIN_VERSION_ghc(9,3,0) renderDiagnosticMessageWithHints :: forall a. Diagnostic a => a -> DecoratedSDoc renderDiagnosticMessageWithHints a = Error.unionDecoratedSDoc   (diagnosticMessage@@ -173,16 +146,9 @@     (defaultDiagnosticOpts @a) #endif     a) (mkDecorated $ map ppr $ diagnosticHints a)-#endif -#if MIN_VERSION_ghc(9,3,0) mkWarnMsg :: DynFlags -> Maybe DiagnosticReason -> b -> SrcSpan -> PrintUnqualified -> SDoc -> MsgEnvelope DecoratedSDoc mkWarnMsg df reason _logFlags l st doc = fmap renderDiagnosticMessageWithHints $ mkMsgEnvelope (initDiagOpts df) l st (mkPlainDiagnostic (fromMaybe WarningWithoutFlag reason) [] doc)-#else-mkWarnMsg :: a -> b -> DynFlags -> SrcSpan -> PrintUnqualified -> SDoc -> MsgEnvelope DecoratedSDoc-mkWarnMsg _ _ =-  const Error.mkWarnMsg-#endif  textDoc :: String -> SDoc textDoc = text
src/Development/IDE/GHC/Compat/Parser.hs view
@@ -5,22 +5,20 @@ module Development.IDE.GHC.Compat.Parser (     initParserOpts,     initParserState,-    ApiAnns,     PsSpan(..),     pattern HsParsedModule,     type GHC.HsParsedModule,     Development.IDE.GHC.Compat.Parser.hpm_module,     Development.IDE.GHC.Compat.Parser.hpm_src_files,-    Development.IDE.GHC.Compat.Parser.hpm_annotations,     pattern ParsedModule,     Development.IDE.GHC.Compat.Parser.pm_parsed_source,     type GHC.ParsedModule,     Development.IDE.GHC.Compat.Parser.pm_mod_summary,     Development.IDE.GHC.Compat.Parser.pm_extra_src_files,-    Development.IDE.GHC.Compat.Parser.pm_annotations,-    mkApiAnns,     -- * API Annotations+#if !MIN_VERSION_ghc(9,11,0)     Anno.AnnKeywordId(..),+#endif     pattern EpaLineComment,     pattern EpaBlockComment     ) where@@ -38,17 +36,8 @@                                                   pm_mod_summary,                                                   pm_parsed_source) import qualified GHC-import           GHC.Hs                          (hpm_module, hpm_src_files)---- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if !MIN_VERSION_ghc(9,3,0)-import qualified GHC.Driver.Config               as Config-#endif--#if MIN_VERSION_ghc(9,3,0) import qualified GHC.Driver.Config.Parser        as Config-#endif+import           GHC.Hs                          (hpm_module, hpm_src_files)   @@ -60,34 +49,28 @@ initParserState =   Lexer.initParserState --- GHC 9.2 does not have ApiAnns anymore packaged in ParsedModule. Now the--- annotations are found in the ast.-type ApiAnns = ()- #if MIN_VERSION_ghc(9,5,0)-pattern HsParsedModule :: Located (HsModule GhcPs) -> [FilePath] -> ApiAnns -> GHC.HsParsedModule+pattern HsParsedModule :: Located (HsModule GhcPs) -> [FilePath] -> GHC.HsParsedModule #else-pattern HsParsedModule :: Located HsModule -> [FilePath] -> ApiAnns -> GHC.HsParsedModule+pattern HsParsedModule :: Located HsModule -> [FilePath] -> GHC.HsParsedModule #endif pattern HsParsedModule     { hpm_module     , hpm_src_files-    , hpm_annotations-    } <- ( (,()) -> (GHC.HsParsedModule{..}, hpm_annotations))+    } <- GHC.HsParsedModule{..}     where-        HsParsedModule hpm_module hpm_src_files _hpm_annotations =+        HsParsedModule hpm_module hpm_src_files =             GHC.HsParsedModule hpm_module hpm_src_files  -pattern ParsedModule :: ModSummary -> ParsedSource -> [FilePath] -> ApiAnns -> GHC.ParsedModule+pattern ParsedModule :: ModSummary -> ParsedSource -> [FilePath] -> GHC.ParsedModule pattern ParsedModule     { pm_mod_summary     , pm_parsed_source     , pm_extra_src_files-    , pm_annotations-    } <- ( (,()) -> (GHC.ParsedModule{..}, pm_annotations))+    } <- GHC.ParsedModule{..}     where-        ParsedModule ms parsed extra_src_files _anns =+        ParsedModule ms parsed extra_src_files =             GHC.ParsedModule              { pm_mod_summary = ms              , pm_parsed_source = parsed@@ -95,6 +78,4 @@              } {-# COMPLETE ParsedModule :: GHC.ParsedModule #-} -mkApiAnns :: PState -> ApiAnns-mkApiAnns = const () 
src/Development/IDE/GHC/Compat/Plugins.hs view
@@ -7,8 +7,6 @@     defaultPlugin,     PluginWithArgs(..),     applyPluginsParsedResultAction,-    initializePlugins,-    initPlugins,      -- * Static plugins     StaticPlugin(..),@@ -20,79 +18,32 @@     ) where  import           Development.IDE.GHC.Compat.Core-import           Development.IDE.GHC.Compat.Env        (hscSetFlags, hsc_dflags)-import           Development.IDE.GHC.Compat.Parser     as Parser+import           Development.IDE.GHC.Compat.Parser as Parser -import qualified GHC.Driver.Env                        as Env-import           GHC.Driver.Plugins                    (Plugin (..),-                                                        PluginWithArgs (..),-                                                        StaticPlugin (..),-                                                        defaultPlugin,-                                                        withPlugins)-import qualified GHC.Runtime.Loader                    as Loader+import qualified GHC.Driver.Env                    as Env+import           GHC.Driver.Plugins                (ParsedResult (..),+                                                    Plugin (..),+                                                    PluginWithArgs (..),+                                                    PsMessages (..),+                                                    StaticPlugin (..),+                                                    defaultPlugin,+                                                    staticPlugins, withPlugins)+import qualified GHC.Parser.Lexer                  as Lexer --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           Data.Bifunctor                        (bimap)-import           Development.IDE.GHC.Compat.Outputable as Out-import           Development.IDE.GHC.Compat.Util       (Bag)-#endif--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Driver.Plugins                    (ParsedResult (..),-                                                        PsMessages (..),-                                                        staticPlugins)-import qualified GHC.Parser.Lexer                      as Lexer-#endif--#if !MIN_VERSION_ghc(9,3,0)-type PsMessages = (Bag WarnMsg, Bag ErrMsg)-#endif- getPsMessages :: PState -> PsMessages getPsMessages pst =-#if MIN_VERSION_ghc(9,3,0)   uncurry PsMessages $ Lexer.getPsMessages pst-#else-  bimap (fmap pprWarning) (fmap pprError) $ getMessages pst-#endif -applyPluginsParsedResultAction :: HscEnv -> ModSummary -> Parser.ApiAnns -> ParsedSource -> PsMessages -> IO (ParsedSource, PsMessages)-applyPluginsParsedResultAction env ms hpm_annotations parsed msgs = do+applyPluginsParsedResultAction :: HscEnv -> ModSummary -> ParsedSource -> PsMessages -> IO (ParsedSource, PsMessages)+applyPluginsParsedResultAction env ms parsed msgs = do   -- Apply parsedResultAction of plugins   let applyPluginAction p opts = parsedResultAction p opts ms-#if MIN_VERSION_ghc(9,3,0)-  fmap (\result -> (hpm_module (parsedResultModule result), (parsedResultMessages result))) $ runHsc env $ withPlugins-#else-  fmap (\parsed_module -> (hpm_module parsed_module, msgs)) $ runHsc env $ withPlugins-#endif-#if MIN_VERSION_ghc(9,3,0)+  fmap (\result -> (hpm_module (parsedResultModule result), parsedResultMessages result)) $ runHsc env $ withPlugins       (Env.hsc_plugins env)-#else-      env-#endif       applyPluginAction-#if MIN_VERSION_ghc(9,3,0)-      (ParsedResult (HsParsedModule parsed [] hpm_annotations) msgs)-#else-      (HsParsedModule parsed [] hpm_annotations)-#endif+      (ParsedResult (HsParsedModule parsed []) msgs) -initializePlugins :: HscEnv -> IO HscEnv-initializePlugins env = do-    Loader.initializePlugins env --- | Plugins aren't stored in ModSummary anymore since GHC 9.2, but this--- function still returns it for compatibility with 8.10-initPlugins :: HscEnv -> ModSummary -> IO (ModSummary, HscEnv)-initPlugins session modSummary = do-    session1 <- initializePlugins (hscSetFlags (ms_hspp_opts modSummary) session)-    return (modSummary{ms_hspp_opts = hsc_dflags session1}, session1)- hsc_static_plugins :: HscEnv -> [StaticPlugin]-#if MIN_VERSION_ghc(9,3,0) hsc_static_plugins = staticPlugins . Env.hsc_plugins-#else-hsc_static_plugins = Env.hsc_static_plugins-#endif
src/Development/IDE/GHC/Compat/Units.hs view
@@ -5,7 +5,6 @@     -- * UnitState     UnitState,     initUnits,-    oldInitUnits,     unitState,     getUnitName,     explicitUnits,@@ -53,10 +52,17 @@ import           Development.IDE.GHC.Compat.Outputable import           Prelude                               hiding (mod) +import           Control.Monad+import qualified Data.List.NonEmpty                    as NE+import qualified Data.Map.Strict                       as Map+import qualified GHC import qualified GHC.Data.ShortText                    as ST+import qualified GHC.Driver.Session                    as DynFlags+import           GHC.Types.PkgQual                     (PkgQual (NoPkgQual)) import           GHC.Types.Unique.Set import           GHC.Unit.External import qualified GHC.Unit.Finder                       as GHC+import           GHC.Unit.Home.ModInfo import qualified GHC.Unit.Info                         as UnitInfo import           GHC.Unit.State                        (LookupResult, UnitInfo,                                                         UnitInfoMap,@@ -69,40 +75,19 @@ import qualified GHC.Unit.State                        as State import           GHC.Unit.Types --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Data.FastString-import           GHC.Unit.Env-import           GHC.Unit.Finder                       hiding-                                                       (findImportedModule)-import qualified GHC.Unit.Types                        as Unit-#endif--#if MIN_VERSION_ghc(9,3,0)-import           Control.Monad-import qualified Data.List.NonEmpty                    as NE-import qualified Data.Map.Strict                       as Map-import qualified GHC-import qualified GHC.Driver.Session                    as DynFlags-import           GHC.Types.PkgQual                     (PkgQual (NoPkgQual))-import           GHC.Unit.Home.ModInfo-#endif-- type PreloadUnitClosure = UniqSet UnitId  unitState :: HscEnv -> UnitState unitState = ue_units . hsc_unit_env -#if MIN_VERSION_ghc(9,3,0) createUnitEnvFromFlags :: NE.NonEmpty DynFlags -> HomeUnitGraph createUnitEnvFromFlags unitDflags =   let     newInternalUnitEnv dflags = mkHomeUnitEnv dflags emptyHomePackageTable Nothing     unitEnvList = NE.map (\dflags -> (homeUnitId_ dflags, newInternalUnitEnv dflags)) unitDflags   in-    unitEnv_new (Map.fromList (NE.toList (unitEnvList)))+    unitEnv_new (Map.fromList (NE.toList unitEnvList))  initUnits :: [DynFlags] -> HscEnv -> IO HscEnv initUnits unitDflags env = do@@ -135,25 +120,11 @@         , ue_eps             = ue_eps (hsc_unit_env env)         }   pure $ hscSetFlags dflags1 $ hscSetUnitEnv unit_env env-#else-initUnits :: [DynFlags] -> HscEnv -> IO HscEnv-initUnits _df env = pure env -- Can't do anything here, oldInitUnits should already be called-#endif  --- | oldInitUnits only needs to modify DynFlags for GHC <9.2--- For GHC >= 9.2, we need to set the hsc_unit_env also, that is--- done later by initUnits-oldInitUnits :: DynFlags -> IO DynFlags-oldInitUnits = pure- explicitUnits :: UnitState -> [Unit] explicitUnits ue =-#if MIN_VERSION_ghc(9,3,0)   map fst $ State.explicitUnits ue-#else-  State.explicitUnits ue-#endif  listVisibleModuleNames :: HscEnv -> [ModuleName] listVisibleModuleNames env =@@ -166,11 +137,7 @@ lookupModuleWithSuggestions   :: HscEnv   -> ModuleName-#if MIN_VERSION_ghc(9,3,0)   -> GHC.PkgQual-#else-  -> Maybe FastString-#endif   -> LookupResult lookupModuleWithSuggestions env modname mpkg =   State.lookupModuleWithSuggestions (unitState env) modname mpkg@@ -204,10 +171,6 @@ installedModule :: unit -> ModuleName -> GenModule unit installedModule        = Module -#if !MIN_VERSION_ghc(9,3,0)-moduleUnitId :: Module -> UnitId-moduleUnitId = Unit.toUnitId . Unit.moduleUnit-#endif  filterInplaceUnits :: [UnitId] -> [PackageFlag] -> ([UnitId], [PackageFlag]) filterInplaceUnits us packageFlags =@@ -225,11 +188,7 @@  findImportedModule :: HscEnv -> ModuleName -> IO (Maybe Module) findImportedModule env mn = do-#if MIN_VERSION_ghc(9,3,0)     res <- GHC.findImportedModule env mn NoPkgQual-#else-    res <- GHC.findImportedModule env mn Nothing-#endif     case res of         Found _ mod -> pure . pure $ mod         _           -> pure Nothing
src/Development/IDE/GHC/Compat/Util.hs view
@@ -68,6 +68,7 @@  import           Control.Exception.Safe  (MonadCatch, catch, try) import           GHC.Data.Bag+import           GHC.Data.Bool import           GHC.Data.BooleanFormula import           GHC.Data.EnumSet import           GHC.Data.FastString@@ -79,13 +80,3 @@ import           GHC.Utils.Fingerprint import           GHC.Utils.Outputable    (pprHsString) import           GHC.Utils.Panic         hiding (try)---- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Utils.Misc-#endif--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Data.Bool-#endif
src/Development/IDE/GHC/CoreFile.hs view
@@ -26,6 +26,9 @@ import           GHC.Fingerprint import           GHC.Iface.Binary import           GHC.Iface.Env+#if MIN_VERSION_ghc(9,11,0)+import qualified GHC.Iface.Load                  as Iface+#endif import           GHC.Iface.Recomp.Binary         (fingerprintBinMem) import           GHC.IfaceToCore import           GHC.Types.Id.Make@@ -87,14 +90,20 @@     return (file, fp)  -- | Write a core file-writeBinCoreFile :: FilePath -> CoreFile -> IO Fingerprint-writeBinCoreFile core_path fat_iface = do+writeBinCoreFile :: DynFlags -> FilePath -> CoreFile -> IO Fingerprint+writeBinCoreFile _dflags core_path fat_iface = do     bh <- openBinMem initBinMemSize      let quietTrace =           QuietBinIFace -    putWithUserData quietTrace bh fat_iface+    putWithUserData+      quietTrace+#if MIN_VERSION_ghc(9,11,0)+      (Iface.flagsToIfCompression _dflags)+#endif+      bh+      fat_iface      -- And send the result to the file     writeBinMem bh core_path@@ -141,7 +150,11 @@     | (op, val_index) <- classAllSelIds cls `zip` [0..] ]  get_defn :: Id -> CoreBind-get_defn identifier = NonRec identifier (unfoldingTemplate (realIdUnfolding identifier))+get_defn identifier = NonRec identifier templ+  where+    templ = case maybeUnfoldingTemplate (realIdUnfolding identifier) of+              Nothing -> error "get_dfn: no unfolding template"+              Just x  -> x  toIfaceTopBndr1 :: Module -> Id -> IfaceId toIfaceTopBndr1 mod identifier@@ -197,7 +210,7 @@         name' <- newIfaceName (mkVarOcc $ getOccString name)         pure $ ifid{ ifName = name' }       | otherwise = pure ifid-    unmangle_decl_name _ifid = error $ "tcIfaceId: got non IfaceId: "+    unmangle_decl_name _ifid = error "tcIfaceId: got non IfaceId: "     -- invariant: 'IfaceId' is always a 'IfaceId' constructor     getIfaceId (AnId identifier) = identifier     getIfaceId _                 = error "tcIfaceId: got non Id"
src/Development/IDE/GHC/Error.hs view
@@ -1,11 +1,15 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP                      #-}+{-# LANGUAGE DisambiguateRecordFields #-} -- Copyright (c) 2019 The DAML Authors. All rights reserved. -- SPDX-License-Identifier: Apache-2.0 module Development.IDE.GHC.Error   (     -- * Producing Diagnostic values-    diagFromErrMsgs+    diagFromGhcErrorMessages+  , diagFromErrMsgs   , diagFromErrMsg+  , diagFromSDocErrMsgs+  , diagFromSDocErrMsg   , diagFromString   , diagFromStrings   , diagFromGhcException@@ -33,10 +37,13 @@   , toDSeverity   ) where +import           Control.Lens import           Data.Maybe import           Data.String                       (fromString) import qualified Data.Text                         as T-import           Development.IDE.GHC.Compat        (DecoratedSDoc, MsgEnvelope,+import           Data.Tuple.Extra                  (uncurry3)+import           Development.IDE.GHC.Compat        (GhcMessage, MsgEnvelope,+                                                    errMsgDiagnostic,                                                     errMsgSeverity, errMsgSpan,                                                     formatErrorWithQual,                                                     srcErrorMessages)@@ -51,30 +58,51 @@                                                     CodePointRange (CodePointRange))  -diagFromText :: T.Text -> D.DiagnosticSeverity -> SrcSpan -> T.Text -> FileDiagnostic-diagFromText diagSource sev loc msg = (toNormalizedFilePath' $ fromMaybe noFilePath $ srcSpanToFilename loc,ShowDiag,)-    Diagnostic-    { _range    = fromMaybe noRange $ srcSpanToRange loc-    , _severity = Just sev-    , _source   = Just diagSource -- not shown in the IDE, but useful for ghcide developers-    , _message  = msg-    , _code     = Nothing-    , _relatedInformation = Nothing-    , _tags     = Nothing-    , _codeDescription = Nothing-    , _data_   = Nothing-    }+diagFromText :: T.Text -> D.DiagnosticSeverity -> SrcSpan -> T.Text -> Maybe (MsgEnvelope GhcMessage) -> FileDiagnostic+diagFromText diagSource sev loc msg origMsg =+  D.ideErrorWithSource+    (Just diagSource) (Just sev)+    (toNormalizedFilePath' $ fromMaybe noFilePath $ srcSpanToFilename loc)+    msg origMsg+    & fdLspDiagnosticL %~ \diag -> diag { D._range = fromMaybe noRange $ srcSpanToRange loc }  -- | Produce a GHC-style error from a source span and a message.-diagFromErrMsg :: T.Text -> DynFlags -> MsgEnvelope DecoratedSDoc -> [FileDiagnostic]-diagFromErrMsg diagSource dflags e =-    [ diagFromText diagSource sev (errMsgSpan e)-      $ T.pack $ formatErrorWithQual dflags e-    | Just sev <- [toDSeverity $ errMsgSeverity e]]+diagFromErrMsg :: T.Text -> DynFlags -> MsgEnvelope GhcMessage -> [FileDiagnostic]+diagFromErrMsg diagSource dflags origErr =+    let err = fmap (\e -> (Compat.renderDiagnosticMessageWithHints e, Just origErr)) origErr+    in+    diagFromSDocWithOptionalOrigMsg diagSource dflags err -diagFromErrMsgs :: T.Text -> DynFlags -> Compat.Bag (MsgEnvelope DecoratedSDoc) -> [FileDiagnostic]+-- | Compatibility function for creating '[FileDiagnostic]' from+-- a 'Compat.Bag' of GHC error messages.+-- The function signature changes based on the GHC version.+-- While this is not desirable, it avoids more CPP statements in code+-- that implements actual logic.+#if MIN_VERSION_ghc(9,5,0)+diagFromGhcErrorMessages :: T.Text -> DynFlags -> Compat.Bag (MsgEnvelope GhcMessage) -> [FileDiagnostic]+diagFromGhcErrorMessages sourceParser dflags errs =+    diagFromErrMsgs sourceParser dflags errs+#else+diagFromGhcErrorMessages :: T.Text -> DynFlags -> Compat.Bag (MsgEnvelope Compat.DecoratedSDoc) -> [FileDiagnostic]+diagFromGhcErrorMessages sourceParser dflags errs =+    diagFromSDocErrMsgs sourceParser dflags errs+#endif++diagFromErrMsgs :: T.Text -> DynFlags -> Compat.Bag (MsgEnvelope GhcMessage) -> [FileDiagnostic] diagFromErrMsgs diagSource dflags = concatMap (diagFromErrMsg diagSource dflags) . Compat.bagToList +diagFromSDocErrMsg :: T.Text -> DynFlags -> MsgEnvelope Compat.DecoratedSDoc -> [FileDiagnostic]+diagFromSDocErrMsg diagSource dflags err =+    diagFromSDocWithOptionalOrigMsg diagSource dflags (fmap (,Nothing) err)++diagFromSDocErrMsgs :: T.Text -> DynFlags -> Compat.Bag (MsgEnvelope Compat.DecoratedSDoc) -> [FileDiagnostic]+diagFromSDocErrMsgs diagSource dflags = concatMap (diagFromSDocErrMsg diagSource dflags) . Compat.bagToList++diagFromSDocWithOptionalOrigMsg :: T.Text -> DynFlags -> MsgEnvelope (Compat.DecoratedSDoc, Maybe (MsgEnvelope GhcMessage)) -> [FileDiagnostic]+diagFromSDocWithOptionalOrigMsg diagSource dflags err =+    [ diagFromText diagSource sev (errMsgSpan err) (T.pack (formatErrorWithQual dflags (fmap fst err))) (snd (errMsgDiagnostic err))+    | Just sev <- [toDSeverity $ errMsgSeverity err]]+ -- | Convert a GHC SrcSpan to a DAML compiler Range srcSpanToRange :: SrcSpan -> Maybe Range srcSpanToRange (UnhelpfulSpan _)           = Nothing@@ -157,27 +185,19 @@ -- | Convert a GHC severity to a DAML compiler Severity. Severities below -- "Warning" level are dropped (returning Nothing). toDSeverity :: GHC.Severity -> Maybe D.DiagnosticSeverity-#if !MIN_VERSION_ghc(9,3,0)-toDSeverity SevOutput      = Nothing-toDSeverity SevInteractive = Nothing-toDSeverity SevDump        = Nothing-toDSeverity SevInfo        = Just DiagnosticSeverity_Information-toDSeverity SevFatal       = Just DiagnosticSeverity_Error-#else-toDSeverity SevIgnore      = Nothing-#endif-toDSeverity SevWarning     = Just DiagnosticSeverity_Warning-toDSeverity SevError       = Just DiagnosticSeverity_Error+toDSeverity SevIgnore  = Nothing+toDSeverity SevWarning = Just DiagnosticSeverity_Warning+toDSeverity SevError   = Just DiagnosticSeverity_Error   -- | Produce a bag of GHC-style errors (@ErrorMessages@) from the given --   (optional) locations and message strings.-diagFromStrings :: T.Text -> D.DiagnosticSeverity -> [(SrcSpan, String)] -> [FileDiagnostic]-diagFromStrings diagSource sev = concatMap (uncurry (diagFromString diagSource sev))+diagFromStrings :: T.Text -> D.DiagnosticSeverity -> [(SrcSpan, String, Maybe (MsgEnvelope GhcMessage))] -> [FileDiagnostic]+diagFromStrings diagSource sev = concatMap (uncurry3 (diagFromString diagSource sev))  -- | Produce a GHC-style error from a source span and a message.-diagFromString :: T.Text -> D.DiagnosticSeverity -> SrcSpan -> String -> [FileDiagnostic]-diagFromString diagSource sev sp x = [diagFromText diagSource sev sp $ T.pack x]+diagFromString :: T.Text -> D.DiagnosticSeverity -> SrcSpan -> String -> Maybe (MsgEnvelope GhcMessage) -> [FileDiagnostic]+diagFromString diagSource sev sp x origMsg = [diagFromText diagSource sev sp (T.pack x) origMsg]   -- | Produces an "unhelpful" source span with the given string.@@ -207,15 +227,11 @@       Right <$> ghcM     where         ghcExceptionToDiagnostics = return . Left . diagFromGhcException fromWhere dflags-        sourceErrorToDiagnostics = return . Left . diagFromErrMsgs fromWhere dflags-#if MIN_VERSION_ghc(9,3,0)-                                        . fmap (fmap Compat.renderDiagnosticMessageWithHints) . Compat.getMessages-#endif-                                        . srcErrorMessages-+        sourceErrorToDiagnostics diag = pure $ Left $+          diagFromErrMsgs fromWhere dflags (Compat.getMessages (srcErrorMessages diag))  diagFromGhcException :: T.Text -> DynFlags -> GhcException -> [FileDiagnostic]-diagFromGhcException diagSource dflags exc = diagFromString diagSource DiagnosticSeverity_Error (noSpan "<Internal>") (showGHCE dflags exc)+diagFromGhcException diagSource dflags exc = diagFromString diagSource DiagnosticSeverity_Error (noSpan "<Internal>") (showGHCE dflags exc) Nothing  showGHCE :: DynFlags -> GhcException -> String showGHCE dflags exc = case exc of
src/Development/IDE/GHC/Orphans.hs view
@@ -7,7 +7,9 @@ -- | Orphan instances for GHC. --   Note that the 'NFData' instances may not be law abiding. module Development.IDE.GHC.Orphans() where-import           Development.IDE.GHC.Compat+import           Development.IDE.GHC.Compat        hiding+                                                   (DuplicateRecordFields,+                                                    FieldSelectors) import           Development.IDE.GHC.Util  import           Control.DeepSeq@@ -17,26 +19,18 @@ import           Data.String                       (IsString (fromString)) import           Data.Text                         (unpack) +import           Data.Bifunctor                    (Bifunctor (..)) import           GHC.ByteCode.Types import           GHC.Data.Bag import           GHC.Data.FastString import qualified GHC.Data.StringBuffer             as SB-import           GHC.Types.SrcLoc---- See Note [Guidelines For Using CPP In GHCIDE Import Statements]--#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Types.Unique                  (getKey)-import           GHC.Unit.Module.Graph             (ModuleGraph)-#endif--import           Data.Bifunctor                    (Bifunctor (..)) import           GHC.Parser.Annotation--#if MIN_VERSION_ghc(9,3,0)+import           GHC.Types.FieldLabel              (DuplicateRecordFields (DuplicateRecordFields, NoDuplicateRecordFields),+                                                    FieldSelectors (FieldSelectors, NoFieldSelectors)) import           GHC.Types.PkgQual+import           GHC.Types.SrcLoc -#endif+-- See Note [Guidelines For Using CPP In GHCIDE Import Statements]  #if MIN_VERSION_ghc(9,5,0) import           GHC.Unit.Home.ModInfo@@ -57,6 +51,17 @@ instance NFData ModDetails where rnf = rwhnf instance NFData SafeHaskellMode where rnf = rwhnf instance Show Linkable where show = unpack . printOutputable+#if MIN_VERSION_ghc(9,11,0)+instance NFData Linkable where rnf (Linkable a b c) = rnf a `seq` rnf b `seq` rnf c+instance NFData LinkableObjectSort where rnf = rwhnf+instance NFData LinkablePart where+  rnf (DotO a b)         = rnf a `seq` rnf b+  rnf (DotA f)           = rnf f+  rnf (DotDLL f)         = rnf f+  rnf (BCOs a)           = seqCompiledByteCode a+  rnf (CoreBindings wcb) = rnf wcb+  rnf (LazyBCOs a b)     = seqCompiledByteCode a `seq` rnf b+#else instance NFData Linkable where rnf (LM a b c) = rnf a `seq` rnf b `seq` rnf c instance NFData Unlinked where   rnf (DotO f)           = rnf f@@ -66,14 +71,24 @@ #if MIN_VERSION_ghc(9,5,0)   rnf (CoreBindings wcb) = rnf wcb   rnf (LoadedBCOs us)    = rnf us+#endif+#endif +#if MIN_VERSION_ghc(9,5,0) instance NFData WholeCoreBindings where+#if MIN_VERSION_ghc(9,11,0)+  rnf (WholeCoreBindings bs m ml f) = rnf bs `seq` rnf m `seq` rnf ml `seq` rnf f+#else   rnf (WholeCoreBindings bs m ml) = rnf bs `seq` rnf m `seq` rnf ml+#endif  instance NFData ModLocation where+#if MIN_VERSION_ghc(9,11,0)+    rnf (OsPathModLocation mf f1 f2 f3 f4 f5) = rnf mf `seq` rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5+#else     rnf (ModLocation mf f1 f2 f3 f4 f5) = rnf mf `seq` rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5- #endif+#endif  instance Show PackageFlag where show = unpack . printOutputable instance Show InteractiveImport where show = unpack . printOutputable@@ -88,9 +103,6 @@ instance Show Module where     show = moduleNameString . moduleName -#if !MIN_VERSION_ghc(9,3,0)-instance Outputable a => Show (GenLocated SrcSpan a) where show = unpack . printOutputable-#endif  #if !MIN_VERSION_ghc(9,5,0) instance (NFData l, NFData e) => NFData (GenLocated l e) where@@ -131,12 +143,6 @@ instance NFData HieFile where     rnf = rwhnf -#if !MIN_VERSION_ghc(9,3,0)-deriving instance Eq SourceModified-deriving instance Show SourceModified-instance NFData SourceModified where-    rnf = rwhnf-#endif  instance Hashable ModuleName where     hashWithSalt salt = hashWithSalt salt . show@@ -222,7 +228,6 @@ instance NFData HomeModInfo where   rnf (HomeModInfo iface dets link) = rwhnf iface `seq` rnf dets `seq` rnf link -#if MIN_VERSION_ghc(9,3,0) instance NFData PkgQual where   rnf NoPkgQual      = ()   rnf (ThisPkg uid)  = rnf uid@@ -233,7 +238,6 @@  instance NFData NodeKey where   rnf = rwhnf-#endif  #if MIN_VERSION_ghc(9,5,0) instance NFData HomeModLinkable where@@ -246,8 +250,27 @@ instance NFData (Pat (GhcPass Renamed)) where     rnf = rwhnf +instance NFData (HsExpr (GhcPass Typechecked)) where+    rnf = rwhnf++instance NFData (Pat (GhcPass Typechecked)) where+    rnf = rwhnf+ instance NFData Extension where   rnf = rwhnf  instance NFData (UniqFM Name [Name]) where   rnf (ufmToIntMap -> m) = rnf m++#if !MIN_VERSION_ghc(9,5,0)+instance NFData DuplicateRecordFields where+  rnf DuplicateRecordFields   = ()+  rnf NoDuplicateRecordFields = ()++instance NFData FieldSelectors where+  rnf FieldSelectors   = ()+  rnf NoFieldSelectors = ()++instance NFData FieldLabel where+  rnf (FieldLabel a b c d) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d+#endif
src/Development/IDE/GHC/Util.hs view
@@ -255,7 +255,6 @@ -- Tracing exactprint terms  -- | Print a GHC value in `defaultUserStyle` without unique symbols.--- It uses `showSDocUnsafe` with `unsafeGlobalDynFlags` internally. -- -- This is the most common print utility. -- It will do something additionally compared to what the 'Outputable' instance does.
src/Development/IDE/GHC/Warnings.hs view
@@ -6,15 +6,37 @@ module Development.IDE.GHC.Warnings(withWarnings) where  import           Control.Concurrent.Strict-import           Data.List+import           Control.Lens                      (over) import qualified Data.Text                         as T  import           Development.IDE.GHC.Compat import           Development.IDE.GHC.Error import           Development.IDE.Types.Diagnostics-import           Language.LSP.Protocol.Types       (type (|?) (..)) +{-+ Note [withWarnings and its dangers]+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+    withWarnings collects warnings by registering a custom logger which extracts+    the SDocs of those warnings. If you receive warnings this way, you will not+    get them in a structured form. In the medium term we'd like to remove all+    uses of withWarnings to get structured messages everywhere we can. +    For the time being, withWarnings is no longer used for anything in the main+    typecheckModule codepath, but it is still used for bytecode/object code+    generation, as well as a few other places.++    I suspect some of these functions (e.g. codegen) will need deeper changes to+    be able to get diagnostics as a list, though I don't have great evidence for+    that atm. I haven't taken a look to see if those functions that are wrapped+    with this could produce diagnostics another way.++    It would be good for someone to take a look. What we've done so far gives us+    diagnostics for renaming and typechecking, and doesn't require us to copy+    too much code from GHC or make any deeper changes, and lets us get started+    with the bulk of the useful plugin work, but it would be good to have all+    diagnostics with structure be collected that way.+-}+ -- | Take a GHC monadic action (e.g. @typecheckModule pm@ for some -- parsed module 'pm@') and produce a "decorated" action that will -- harvest any warnings encountered executing the action. The 'phase'@@ -24,42 +46,16 @@ --   https://github.com/ghc/ghc/blob/5f1d949ab9e09b8d95319633854b7959df06eb58/compiler/main/GHC.hs#L623-L640 --   which basically says that log_action is taken from the ModSummary when GHC feels like it. --   The given argument lets you refresh a ModSummary log_action-#if MIN_VERSION_ghc(9,3,0)+--+-- Also, See Note [withWarnings and its dangers] for some commentary on this function. withWarnings :: T.Text -> ((HscEnv -> HscEnv) -> IO a) -> IO ([(Maybe DiagnosticReason, FileDiagnostic)], a)-#else-withWarnings :: T.Text -> ((HscEnv -> HscEnv) -> IO a) -> IO ([(WarnReason, FileDiagnostic)], a)-#endif withWarnings diagSource action = do   warnings <- newVar []   let newAction :: DynFlags -> LogActionCompat       newAction dynFlags logFlags wr _ loc prUnqual msg = do-        let wr_d = map ((wr,) . third3 (attachReason wr)) $ diagFromErrMsg diagSource dynFlags $ mkWarnMsg dynFlags wr logFlags loc prUnqual msg+        let wr_d = map ((wr,) . over fdLspDiagnosticL (attachReason wr)) $ diagFromSDocErrMsg diagSource dynFlags (mkWarnMsg dynFlags wr logFlags loc prUnqual msg)         modifyVar_ warnings $ return . (wr_d:)       newLogger env = pushLogHook (const (logActionCompat (newAction (hsc_dflags env)))) (hsc_logger env)   res <- action $ \env -> putLogHook (newLogger env) env   warns <- readVar warnings   return (reverse $ concat warns, res)-  where-    third3 :: (c -> d) -> (a, b, c) -> (a, b, d)-    third3 f (a, b, c) = (a, b, f c)--#if MIN_VERSION_ghc(9,3,0)-attachReason :: Maybe DiagnosticReason -> Diagnostic -> Diagnostic-attachReason Nothing d = d-attachReason (Just wr) d = d{_code = InR <$> showReason wr}- where-  showReason = \case-    WarningWithFlag flag -> showFlag flag-    _                    -> Nothing-#else-attachReason :: WarnReason -> Diagnostic -> Diagnostic-attachReason wr d = d{_code = InR <$> showReason wr}- where-  showReason = \case-    NoReason       -> Nothing-    Reason flag    -> showFlag flag-    ErrReason flag -> showFlag =<< flag-#endif--showFlag :: WarningFlag -> Maybe T.Text-showFlag flag = ("-W" <>) . T.pack . flagSpecName <$> find ((== flag) . flagSpecFlag) wWarningFlags
src/Development/IDE/Import/DependencyInformation.hs view
@@ -20,6 +20,7 @@   , insertImport   , pathToId   , idToPath+  , idToModLocation   , reachableModules   , processDependencyInformation   , transitiveDeps@@ -47,21 +48,14 @@ import qualified Data.List.NonEmpty                 as NonEmpty import           Data.Maybe import           Data.Tuple.Extra                   hiding (first, second)+import           Development.IDE.GHC.Compat import           Development.IDE.GHC.Orphans        ()-import           GHC.Generics                       (Generic)-import           Prelude                            hiding (mod)- import           Development.IDE.Import.FindImports (ArtifactsLocation (..)) import           Development.IDE.Types.Diagnostics import           Development.IDE.Types.Location--import           Development.IDE.GHC.Compat---- See Note [Guidelines For Using CPP In GHCIDE Import Statements]+import           GHC.Generics                       (Generic)+import           Prelude                            hiding (mod) -#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Unit.Module.Graph              (ModuleGraph)-#endif  -- | The imports for a given module. newtype ModuleImports = ModuleImports
src/Development/IDE/Import/FindImports.hs view
@@ -14,29 +14,23 @@   ) where  import           Control.DeepSeq-import           Development.IDE.GHC.Compat        as Compat-import           Development.IDE.GHC.Error         as ErrUtils-import           Development.IDE.GHC.Orphans       ()-import           Development.IDE.Types.Diagnostics-import           Development.IDE.Types.Location---- standard imports import           Control.Monad.Extra import           Control.Monad.IO.Class import           Data.List                         (find, isSuffixOf) import           Data.Maybe import qualified Data.Set                          as S+import           Development.IDE.GHC.Compat        as Compat+import           Development.IDE.GHC.Error         as ErrUtils+import           Development.IDE.GHC.Orphans       ()+import           Development.IDE.Types.Diagnostics+import           Development.IDE.Types.Location+import           GHC.Types.PkgQual+import           GHC.Unit.State import           System.FilePath --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           Development.IDE.GHC.Compat.Util-#endif--#if MIN_VERSION_ghc(9,3,0)-import           GHC.Types.PkgQual-import           GHC.Unit.State+#if MIN_VERSION_ghc(9,11,0)+import           GHC.Driver.DynFlags #endif  data Import@@ -105,12 +99,11 @@ -- It only returns Just for unit-ids which are possible to import into the -- current module. In particular, it will return Nothing for 'main' components -- as they can never be imported into another package.-#if MIN_VERSION_ghc(9,3,0) mkImportDirs :: HscEnv -> (UnitId, DynFlags) -> Maybe (UnitId, ([FilePath], S.Set ModuleName))-mkImportDirs _env (i, flags) = Just (i, (importPaths flags, reexportedModules flags))+#if MIN_VERSION_ghc(9,11,0)+mkImportDirs _env (i, flags) = Just (i, (importPaths flags, S.fromList $ map reexportTo $ reexportedModules flags)) #else-mkImportDirs :: HscEnv -> (UnitId, DynFlags) -> Maybe (PackageName, (UnitId, [FilePath], S.Set ModuleName))-mkImportDirs env (i, flags) = (, (i, importPaths flags, S.empty)) <$> getUnitName env i+mkImportDirs _env (i, flags) = Just (i, (importPaths flags, reexportedModules flags)) #endif  -- | locate a module in either the file system or the package database. Where we go from *daml to@@ -122,42 +115,22 @@     -> [String]                        -- ^ File extensions     -> (ModuleName -> NormalizedFilePath -> m (Maybe NormalizedFilePath))  -- ^ does file exist predicate     -> Located ModuleName              -- ^ Module name-#if MIN_VERSION_ghc(9,3,0)     -> PkgQual                -- ^ Package name-#else-    -> Maybe FastString                -- ^ Package name-#endif     -> Bool                            -- ^ Is boot module     -> m (Either [FileDiagnostic] Import) locateModule env comp_info exts targetFor modName mbPkgName isSource = do   case mbPkgName of-#if MIN_VERSION_ghc(9,3,0)     -- 'ThisPkg' just means some home module, not the current unit     ThisPkg uid       | Just (dirs, reexports) <- lookup uid import_paths           -> lookupLocal uid dirs reexports       | otherwise -> return $ Left $ notFoundErr env modName $ LookupNotFound []-#else-    -- "this" means that we should only look in the current package-    Just "this" -> do-      lookupLocal (homeUnitId_ dflags) (importPaths dflags) S.empty-#endif     -- if a package name is given we only go look for a package-#if MIN_VERSION_ghc(9,3,0)     OtherPkg uid       | Just (dirs, reexports) <- lookup uid import_paths           -> lookupLocal uid dirs reexports-#else-    Just pkgName-      | Just (uid, dirs, reexports) <- lookup (PackageName pkgName) import_paths-          -> lookupLocal uid dirs reexports-#endif       | otherwise -> lookupInPackageDB-#if MIN_VERSION_ghc(9,3,0)     NoPkgQual -> do-#else-    Nothing -> do-#endif        -- Reexports for current unit have to be empty because they only apply to other units depending on the       -- current unit. If we set the reexports to be the actual reexports then we risk looping forever trying@@ -181,7 +154,11 @@       -- about which module unit a imports.       -- Without multi-component support it is hard to recontruct the dependency environment so       -- unit a will have both unit b and unit c in scope.+#if MIN_VERSION_ghc(9,11,0)+      map (\uid -> let this_df = homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue) in (uid, importPaths this_df, S.fromList $ map reexportTo $ reexportedModules this_df)) hpt_deps+#else       map (\uid -> let this_df = homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue) in (uid, importPaths this_df, reexportedModules this_df)) hpt_deps+#endif     ue = hsc_unit_env env     units = homeUnitEnv_units $ ue_findHomeUnitEnv (homeUnitId_ dflags) ue     hpt_deps :: [UnitId]@@ -196,11 +173,7 @@       -- This is particularly important for Paths_* modules which get generated for every component but unless you use it in       -- each component will end up being found in the wrong place and cause a multi-cradle match failure.     _import_paths' = -- import_paths' is only used in GHC < 9.4-#if MIN_VERSION_ghc(9,3,0)             import_paths-#else-            map snd import_paths-#endif      toModLocation uid file = liftIO $ do         loc <- mkHomeModLocation dflags (unLoc modName) (fromNormalizedFilePath file)@@ -226,7 +199,7 @@   mkError' $ ppr' $ cannotFindModule env modName0 $ lookupToFindResult reason   where     dfs = hsc_dflags env-    mkError' = diagFromString "not found" DiagnosticSeverity_Error (Compat.getLoc modName)+    mkError' doc = diagFromString "not found" DiagnosticSeverity_Error (Compat.getLoc modName) doc Nothing     modName0 = unLoc modName     ppr' = showSDoc dfs     -- We convert the lookup result to a find result to reuse GHC's cannotFindModule pretty printer.@@ -263,10 +236,5 @@   , fr_suggestions = []   } -#if MIN_VERSION_ghc(9,3,0) noPkgQual :: PkgQual noPkgQual = NoPkgQual-#else-noPkgQual :: Maybe a-noPkgQual = Nothing-#endif
src/Development/IDE/LSP/HoverDefinition.hs view
@@ -7,8 +7,10 @@     ( Log(..)     -- * For haskell-language-server     , hover+    , foundHover     , gotoDefinition     , gotoTypeDefinition+    , gotoImplementation     , documentHighlight     , references     , wsSymbols@@ -46,9 +48,11 @@ gotoDefinition     :: Recorder (WithPriority Log) -> IdeState -> TextDocumentPositionParams -> ExceptT PluginError (HandlerM c) (MessageResult Method_TextDocumentDefinition) hover              :: Recorder (WithPriority Log) -> IdeState -> TextDocumentPositionParams -> ExceptT PluginError (HandlerM c) (Hover |? Null) gotoTypeDefinition :: Recorder (WithPriority Log) -> IdeState -> TextDocumentPositionParams -> ExceptT PluginError (HandlerM c) (MessageResult Method_TextDocumentTypeDefinition)+gotoImplementation :: Recorder (WithPriority Log) -> IdeState -> TextDocumentPositionParams -> ExceptT PluginError (HandlerM c) (MessageResult Method_TextDocumentImplementation) documentHighlight  :: Recorder (WithPriority Log) -> IdeState -> TextDocumentPositionParams -> ExceptT PluginError (HandlerM c) ([DocumentHighlight] |? Null)-gotoDefinition = request "Definition" getDefinition (InR $ InR Null) (InL . Definition. InR)-gotoTypeDefinition = request "TypeDefinition" getTypeDefinition (InR $ InR Null) (InL . Definition. InR)+gotoDefinition = request "Definition" getDefinition (InR $ InR Null) (InL . Definition . InR . map fst)+gotoTypeDefinition = request "TypeDefinition" getTypeDefinition (InR $ InR Null) (InL . Definition . InR . map fst)+gotoImplementation = request "Implementation" getImplementationDefinition (InR $ InR Null) (InL . Definition . InR) hover          = request "Hover"      getAtPoint     (InR Null)     foundHover documentHighlight = request "DocumentHighlight" highlightAtPoint (InR Null) InL 
src/Development/IDE/LSP/Outline.hs view
@@ -19,22 +19,18 @@ import           Development.IDE.GHC.Compat import           Development.IDE.GHC.Error      (rangeToRealSrcSpan,                                                  realSrcSpanToRange)-import           Development.IDE.Types.Location import           Development.IDE.GHC.Util       (printOutputable)+import           Development.IDE.Types.Location import           Ide.Types-import           Language.LSP.Protocol.Types             (DocumentSymbol (..),+import           Language.LSP.Protocol.Message+import           Language.LSP.Protocol.Types    (DocumentSymbol (..),                                                  DocumentSymbolParams (DocumentSymbolParams, _textDocument),                                                  SymbolKind (..),                                                  TextDocumentIdentifier (TextDocumentIdentifier),-                                                 type (|?) (InL, InR), uriToFilePath)-import          Language.LSP.Protocol.Message+                                                 type (|?) (InL, InR),+                                                 uriToFilePath) --- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import qualified Data.Text                      as T-#endif- moduleOutline   :: PluginMethodHandler IdeState Method_TextDocumentDocumentSymbol moduleOutline ideState _ DocumentSymbolParams{ _textDocument = TextDocumentIdentifier uri }@@ -118,21 +114,13 @@         , L (locA -> RealSrcSpan l' _) n <- cs         , let l'' = case con of                 L (locA -> RealSrcSpan l''' _) _ -> l'''-                _ -> l'+                _                                -> l'         ]     }   where     cvtFld :: LFieldOcc GhcPs -> Maybe DocumentSymbol-#if MIN_VERSION_ghc(9,3,0)     cvtFld (L (locA -> RealSrcSpan l' _) n) = Just $ (defDocumentSymbol l' :: DocumentSymbol)-#else-    cvtFld (L (RealSrcSpan l' _) n) = Just $ (defDocumentSymbol l' :: DocumentSymbol)-#endif-#if MIN_VERSION_ghc(9,3,0)                 { _name = printOutputable (unLoc (foLabel n))-#else-                { _name = printOutputable (unLoc (rdrNameFieldOcc n))-#endif                 , _kind = SymbolKind_Field                 }     cvtFld _  = Nothing@@ -148,23 +136,13 @@ documentSymbolForDecl (L (locA -> (RealSrcSpan l _)) (InstD _ DataFamInstD { dfid_inst = DataFamInstDecl FamEqn { feqn_tycon, feqn_pats } }))   = Just (defDocumentSymbol l :: DocumentSymbol)     { _name =-#if MIN_VERSION_ghc(9,3,0)-        printOutputable $ pprHsArgsApp (unLoc feqn_tycon) Prefix (feqn_pats)-#else-        printOutputable (unLoc feqn_tycon) <> " " <> T.unwords-                (map printOutputable feqn_pats)-#endif+        printOutputable $ pprHsArgsApp (unLoc feqn_tycon) Prefix feqn_pats     , _kind = SymbolKind_Interface     } documentSymbolForDecl (L (locA -> (RealSrcSpan l _)) (InstD _ TyFamInstD { tfid_inst = TyFamInstDecl _ FamEqn { feqn_tycon, feqn_pats } }))   = Just (defDocumentSymbol l :: DocumentSymbol)     { _name =-#if MIN_VERSION_ghc(9,3,0)-        printOutputable $ pprHsArgsApp (unLoc feqn_tycon) Prefix (feqn_pats)-#else-        printOutputable (unLoc feqn_tycon) <> " " <> T.unwords-                (map printOutputable feqn_pats)-#endif+        printOutputable $ pprHsArgsApp (unLoc feqn_tycon) Prefix feqn_pats     , _kind = SymbolKind_Interface     } documentSymbolForDecl (L (locA -> (RealSrcSpan l _)) (DerivD _ DerivDecl { deriv_type })) =@@ -267,18 +245,16 @@     get_flds_h98 :: HsConDeclH98Details GhcPs                  -> [LFieldOcc GhcPs]     get_flds_h98 (RecCon flds) = get_flds (reLoc flds)-    get_flds_h98 _ = []+    get_flds_h98 _             = []      get_flds_gadt :: HsConDeclGADTDetails GhcPs                   -> [LFieldOcc GhcPs] #if MIN_VERSION_ghc(9,9,0)     get_flds_gadt (RecConGADT _ flds) = get_flds (reLoc flds)-#elif MIN_VERSION_ghc(9,3,0)-    get_flds_gadt (RecConGADT flds _) = get_flds (reLoc flds) #else-    get_flds_gadt (RecConGADT flds) = get_flds (reLoc flds)+    get_flds_gadt (RecConGADT flds _) = get_flds (reLoc flds) #endif-    get_flds_gadt _ = []+    get_flds_gadt _                   = []      get_flds :: Located [LConDeclField GhcPs]              -> [LFieldOcc GhcPs]
src/Development/IDE/LSP/Server.hs view
@@ -41,7 +41,7 @@       trace x = otTracedHandler "Request" (show _method) $ \sp -> do         traceWithSpan sp _params         x-  writeChan chan $ ReactorRequest (_id) (trace $ LSP.runLspT env $ resp' =<< k ide _params) (LSP.runLspT env . resp' . Left)+  writeChan chan $ ReactorRequest _id (trace $ LSP.runLspT env $ resp' =<< k ide _params) (LSP.runLspT env . resp' . Left)  notificationHandler   :: forall m c. PluginMethod Notification m =>
src/Development/IDE/Main.hs view
@@ -16,7 +16,6 @@                                                            putMVar, tryReadMVar) import           Control.Concurrent.STM.Stats             (dumpSTMStats) import           Control.Exception.Safe                   (SomeException,-                                                           catchAny,                                                            displayException) import           Control.Monad.Extra                      (concatMapM, unless,                                                            when)@@ -32,7 +31,7 @@ import           Data.Maybe                               (catMaybes, isJust) import qualified Data.Text                                as T import           Development.IDE                          (Action,-                                                           Priority (Debug, Error),+                                                           Priority (Debug),                                                            Rules, hDuplicateTo') import           Development.IDE.Core.Debouncer           (Debouncer,                                                            newAsyncDebouncer)@@ -72,9 +71,9 @@ import qualified Development.IDE.Plugin.Test              as Test import           Development.IDE.Session                  (SessionLoadingOptions,                                                            getHieDbLoc,+                                                           getInitialGhcLibDirDefault,                                                            loadSessionWithOptions,-                                                           retryOnSqliteBusy,-                                                           setInitialDynFlags)+                                                           retryOnSqliteBusy) import qualified Development.IDE.Session                  as Session import           Development.IDE.Types.Location           (NormalizedUri,                                                            toNormalizedFilePath')@@ -136,7 +135,6 @@   | LogLspStart [PluginId]   | LogLspStartDuration !Seconds   | LogShouldRunSubset !Bool-  | LogSetInitialDynFlagsException !SomeException   | LogConfigurationChange T.Text   | LogService Service.Log   | LogShake Shake.Log@@ -160,8 +158,6 @@       "Started LSP server in" <+> pretty (showDuration duration)     LogShouldRunSubset shouldRunSubset ->       "shouldRunSubset:" <+> pretty shouldRunSubset-    LogSetInitialDynFlagsException e ->-      "setInitialDynFlags:" <+> pretty (displayException e)     LogConfigurationChange msg -> "Configuration changed:" <+> pretty msg     LogService msg -> pretty msg     LogShake msg -> pretty msg@@ -329,13 +325,6 @@                 getIdeState env rootPath withHieDb threadQueue = do                   t <- ioT                   logWith recorder Info $ LogLspStartDuration t-                  -- We want to set the global DynFlags right now, so that we can use-                  -- `unsafeGlobalDynFlags` even before the project is configured-                  _mlibdir <--                      setInitialDynFlags (cmapWithPrio LogSession recorder) rootPath argsSessionLoadingOptions-                          -- TODO: should probably catch/log/rethrow at top level instead-                          `catchAny` (\e -> logWith recorder Error (LogSetInitialDynFlagsException e) >> pure Nothing)-                   sessionLoader <- loadSessionWithOptions (cmapWithPrio LogSession recorder) argsSessionLoadingOptions rootPath (tLoaderQueue threadQueue)                   config <- LSP.runLspT env LSP.getConfig                   let def_options = argsIdeOptions config sessionLoader@@ -435,7 +424,7 @@             let root = argsProjectRoot             dbLoc <- getHieDbLoc root             hPutStrLn stderr $ "Using hiedb at: " ++ dbLoc-            mlibdir <- setInitialDynFlags (cmapWithPrio LogSession recorder) root def+            mlibdir <- getInitialGhcLibDirDefault (cmapWithPrio LogSession recorder) root             rng <- newStdGen             case mlibdir of                 Nothing     -> exitWith $ ExitFailure 1
src/Development/IDE/Plugin/Completions.hs view
@@ -19,6 +19,7 @@ import           Data.Maybe import qualified Data.Text                                as T import           Development.IDE.Core.Compile+import           Development.IDE.Core.FileStore           (getUriContents) import           Development.IDE.Core.PluginUtils import           Development.IDE.Core.PositionMapping import           Development.IDE.Core.RuleTypes@@ -133,11 +134,7 @@                   $ runIdeActionE "CompletionResolve.GhcSessionDeps" (shakeExtras ide)                   $ useWithStaleFastE GhcSessionDeps file     let nc = ideNc $ shakeExtras ide-#if MIN_VERSION_ghc(9,3,0)     name <- liftIO $ lookupNameCache nc mod occ-#else-    name <- liftIO $ upNameCache nc (lookupNameCache mod occ)-#endif     mdkm <- liftIO $ runIdeAction "CompletionResolve.GetDocMap" (shakeExtras ide) $ useWithStaleFast GetDocMap file     let (dm,km) = case mdkm of           Just (DKMap docMap tyThingMap, _) -> (docMap,tyThingMap)@@ -169,8 +166,9 @@   CompletionParams{_textDocument=TextDocumentIdentifier uri                   ,_position=position                   ,_context=completionContext} = ExceptT $ do-    contents <- pluginGetVirtualFile $ toNormalizedUri uri-    fmap Right $ case (contents, uriToFilePath' uri) of+    contentsMaybe <-+      liftIO $ runAction "Completion" ide $ getUriContents $ toNormalizedUri uri+    fmap Right $ case (contentsMaybe, uriToFilePath' uri) of       (Just cnts, Just path) -> do         let npath = toNormalizedFilePath' path         (ideOpts, compls, moduleExports, astres) <- liftIO $ runIdeAction "Completion" (shakeExtras ide) $ do@@ -204,7 +202,7 @@             pure (opts, fmap (,pm,binds) compls, moduleExports, astres)         case compls of           Just (cci', parsedMod, bindMap) -> do-            let pfix = getCompletionPrefix position cnts+            let pfix = getCompletionPrefixFromRope position cnts             case (pfix, completionContext) of               (PosPrefixInfo _ "" _ _, Just CompletionContext { _triggerCharacter = Just "."})                 -> return (InL [])
src/Development/IDE/Plugin/Completions/Logic.hs view
@@ -74,11 +74,6 @@  -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] -#if !MIN_VERSION_ghc(9,3,0)-import           GHC.Plugins                              (defaultSDocContext,-                                                           renderWithContext)-#endif- #if MIN_VERSION_ghc(9,5,0) import           Language.Haskell.Syntax.Basic #endif@@ -514,13 +509,8 @@             --             -- is encoded as @[[arg1, arg2], [arg3], [arg4]]@             -- Hence, we must concat nested arguments into one to get all the fields.-#if MIN_VERSION_ghc(9,3,0)         extract ConDeclField{..}             = map (foLabel . unLoc) cd_fld_names-#else-        extract ConDeclField{..}-            = map (rdrNameFieldOcc . unLoc) cd_fld_names-#endif         -- XConDeclField         extract _ = [] findRecordCompl _ _ _ = []
src/Development/IDE/Plugin/Completions/Types.hs view
@@ -16,7 +16,6 @@ import           Data.Aeson.Types import           Data.Hashable                (Hashable) import           Data.Text                    (Text)-import           Data.Typeable                (Typeable) import           Development.IDE.GHC.Compat import           Development.IDE.Graph        (RuleResult) import           Development.IDE.Spans.Common ()@@ -31,12 +30,12 @@ type instance RuleResult NonLocalCompletions = CachedCompletions  data LocalCompletions = LocalCompletions-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable LocalCompletions instance NFData   LocalCompletions  data NonLocalCompletions = NonLocalCompletions-    deriving (Eq, Show, Typeable, Generic)+    deriving (Eq, Show, Generic) instance Hashable NonLocalCompletions instance NFData   NonLocalCompletions 
src/Development/IDE/Plugin/HLS.hs view
@@ -10,7 +10,10 @@     ) where  import           Control.Exception             (SomeException)+import           Control.Lens                  ((^.)) import           Control.Monad+import qualified Control.Monad.Extra           as Extra+import           Control.Monad.IO.Class        (MonadIO) import           Control.Monad.Trans.Except    (runExceptT) import qualified Data.Aeson                    as A import           Data.Bifunctor                (first)@@ -22,7 +25,7 @@ import           Data.List.NonEmpty            (NonEmpty, nonEmpty, toList) import qualified Data.List.NonEmpty            as NE import qualified Data.Map                      as Map-import           Data.Maybe                    (mapMaybe)+import           Data.Maybe                    (isNothing, mapMaybe) import           Data.Some import           Data.String import           Data.Text                     (Text)@@ -39,6 +42,7 @@ import           Ide.Plugin.HandleRequestTypes import           Ide.PluginUtils               (getClientConfig) import           Ide.Types                     as HLS+import qualified Language.LSP.Protocol.Lens    as JL import           Language.LSP.Protocol.Message import           Language.LSP.Protocol.Types import qualified Language.LSP.Server           as LSP@@ -58,6 +62,7 @@     | LogNoPluginForMethod (Some SMethod)     | LogInvalidCommandIdentifier     | ExceptionInPlugin PluginId (Some SMethod) SomeException+    | LogResolveDefaultHandler (Some SMethod)  instance Pretty Log where   pretty = \case@@ -71,6 +76,8 @@     ExceptionInPlugin plId (Some method) exception ->         "Exception in plugin " <> viaShow plId <> " while processing "           <> pretty method <> ": " <> viaShow exception+    LogResolveDefaultHandler (Some method) ->+        "No plugin can handle" <+> pretty method <+> "request. Return object unchanged." instance Show Log where show = renderString . layoutCompact . pretty  noPluginHandles :: Recorder (WithPriority Log) -> SMethod m -> [(PluginId, HandleRequestResult)] -> IO (Either (TResponseError m) c)@@ -250,8 +257,16 @@         let (fs, dfs) = List.partition (\(_, desc, _) -> handlesRequest m params desc config == HandlesRequest) fs'         let disabledPluginsReason = (\(x, desc, _) -> (x, handlesRequest m params desc config)) <$> dfs         -- Clients generally don't display ResponseErrors so instead we log any that we come across+        -- However, some clients do display ResponseErrors! See for example the issues:+        -- https://github.com/haskell/haskell-language-server/issues/4467+        -- https://github.com/haskell/haskell-language-server/issues/4451         case nonEmpty fs of-          Nothing -> liftIO $ noPluginHandles recorder m disabledPluginsReason+          Nothing -> do+            liftIO (fallbackResolveHandler recorder m params) >>= \case+              Nothing ->+                liftIO $ noPluginHandles recorder m disabledPluginsReason+              Just result ->+                pure $ Right result           Just neFs -> do             let  plidsAndHandlers = fmap (\(plid,_,handler) -> (plid,handler)) neFs             es <- runHandlerM $ runConcurrently exceptionInPlugin m plidsAndHandlers ide params@@ -272,6 +287,72 @@               Just xs -> do                 pure $ Right $ combineResponses m config caps params xs +-- | Fallback Handler for resolve requests.+-- For all kinds of `*/resolve` requests, if they don't have a 'data_' value,+-- produce the original item, since no other plugin has any resolve data.+--+-- This is an internal handler, so it cannot be turned off and should be opaque+-- to the end-user.+-- This function does not take the ServerCapabilities into account, and assumes+-- clients will only send these requests, if and only if the Language Server+-- advertised support for it.+--+-- See Note [Fallback Handler for LSP resolve requests] for justification and reasoning.+fallbackResolveHandler :: MonadIO m => Recorder (WithPriority Log) -> SMethod s -> MessageParams s -> m (Maybe (MessageResult s))+fallbackResolveHandler recorder m params = do+    let result = case m of+          SMethod_InlayHintResolve+              | noResolveData params -> Just params+          SMethod_CompletionItemResolve+              | noResolveData params -> Just params+          SMethod_CodeActionResolve+              | noResolveData params -> Just params+          SMethod_WorkspaceSymbolResolve+              | noResolveData params -> Just params+          SMethod_CodeLensResolve+              | noResolveData params -> Just params+          SMethod_DocumentLinkResolve+              | noResolveData params -> Just params+          _ -> Nothing+    logResolveHandling result+    pure result+    where+        noResolveData :: JL.HasData_ p (Maybe a) => p -> Bool+        noResolveData p = isNothing $ p ^. JL.data_++        -- We only log if we are handling the request.+        -- If we don't handle this request, this should be logged+        -- on call-site.+        logResolveHandling p = Extra.whenJust p $ \_ -> do+          logWith recorder Debug $ LogResolveDefaultHandler (Some m)++{- Note [Fallback Handler for LSP resolve requests]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++We have a special fallback for `*/resolve` requests.++We had multiple reports, where `resolve` requests (such as+`completion/resolve` and `codeAction/resolve`) are rejected+by HLS since the `_data_` field of the respective LSP feature has not been+populated by HLS.+This makes sense, as we only support `resolve` for certain kinds of+`CodeAction`/`Completions`, when they contain particularly expensive+properties, such as documentation or non-local type signatures.++So what to do? We can see two options:++1. Be dumb and permissive: if no plugin wants to resolve a request, then+   just respond positively with the original item! Potentially this masks+   real issues, but may not be too bad. If a plugin thinks it can+   handle the request but it then fails to resolve it, we should still return a failure.+2. Try and be smart: we try to figure out requests that we're "supposed" to+   resolve (e.g. those with a data field), and fail if no plugin wants to handle those.+   This is possible since we set data.+   So as long as we maintain the invariant that only things which need resolving get+   data, then it could be okay.++In 'fallbackResolveHandler', we implement the option (2).+-}  -- --------------------------------------------------------------------- 
src/Development/IDE/Plugin/HLS/GhcIde.hs view
@@ -51,6 +51,8 @@                       Hover.gotoDefinition recorder ide TextDocumentPositionParams{..})                   <> mkPluginHandler SMethod_TextDocumentTypeDefinition (\ide _ TypeDefinitionParams{..} ->                       Hover.gotoTypeDefinition recorder ide TextDocumentPositionParams{..})+                  <> mkPluginHandler SMethod_TextDocumentImplementation (\ide _ ImplementationParams{..} ->+                      Hover.gotoImplementation recorder ide TextDocumentPositionParams{..})                   <> mkPluginHandler SMethod_TextDocumentDocumentHighlight (\ide _ DocumentHighlightParams{..} ->                       Hover.documentHighlight recorder ide TextDocumentPositionParams{..})                   <> mkPluginHandler SMethod_TextDocumentReferences (Hover.references recorder)
src/Development/IDE/Plugin/TypeLenses.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP              #-} {-# LANGUAGE DeriveAnyClass   #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE TypeFamilies     #-}@@ -26,7 +27,8 @@ import qualified Data.Map                             as Map import           Data.Maybe                           (catMaybes, maybeToList) import qualified Data.Text                            as T-import           Development.IDE                      (GhcSession (..),+import           Development.IDE                      (FileDiagnostic (..),+                                                       GhcSession (..),                                                        HscEnvEq (hscEnv),                                                        RuleResult, Rules, Uri,                                                        define, srcSpanToRange,@@ -126,9 +128,10 @@           -- We don't actually pass any data to resolve, however we need this           -- dummy type to make sure HLS resolves our lens           [ CodeLens _range Nothing (Just $ toJSON TypeLensesResolve)-            | (dFile, _, diag@Diagnostic{_range}) <- diags-            , dFile == nfp-            , isGlobalDiagnostic diag]+            | diag <- diags+            , let lspDiag@Diagnostic {_range} = fdLspDiagnostic diag+            , fdFilePath diag == nfp+            , isGlobalDiagnostic lspDiag]         -- The second option is to generate lenses from the GlobalBindingTypeSig         -- rule. This is the only type that needs to have the range adjusted         -- with PositionMapping.@@ -319,7 +322,11 @@         let name = idName identifier         hasSig name $ do           env <- tcInitTidyEnv+#if MIN_VERSION_ghc(9,11,0)+          let ty = tidyOpenType env (idType identifier)+#else           let (_, ty) = tidyOpenType env (idType identifier)+#endif           pure $ GlobalBindingTypeSig name (printName name <> " :: " <> showDoc (pprSigmaType ty)) (name `elemNameSet` exports)       patToSig p = do         let name = patSynName p
src/Development/IDE/Spans/AtPoint.hs view
@@ -10,6 +10,7 @@     atPoint   , gotoDefinition   , gotoTypeDefinition+  , gotoImplementation   , documentHighlight   , pointCommand   , referencesAtPoint@@ -23,6 +24,10 @@   , LookupModule   ) where ++import           GHC.Data.FastString                  (lengthFS)+import qualified GHC.Utils.Outputable                 as O+ import           Development.IDE.GHC.Error import           Development.IDE.GHC.Orphans          () import           Development.IDE.Types.Location@@ -31,6 +36,7 @@ import           Prelude                              hiding (mod)  -- compiler and infrastructure+import           Development.IDE.Core.Compile         (setNonHomeFCHook) import           Development.IDE.Core.PositionMapping import           Development.IDE.Core.RuleTypes import           Development.IDE.GHC.Compat@@ -52,9 +58,13 @@  import qualified Data.Array                           as A import           Data.Either-import           Data.List                            (isSuffixOf) import           Data.List.Extra                      (dropEnd1, nubOrd) ++import           Data.Either.Extra                    (eitherToMaybe)+import           Data.List                            (isSuffixOf, sortOn)+import           Data.Tree+import qualified Data.Tree                            as T import           Data.Version                         (showVersion) import           Development.IDE.Types.Shake          (WithHieDb) import           HieDb                                hiding (pointCommand,@@ -171,14 +181,19 @@     highlights = do       n <- ns       ref <- fromMaybe [] (M.lookup (Right n) rf)-      pure $ makeHighlight ref-    makeHighlight (sp,dets) =-      DocumentHighlight (realSrcSpanToRange sp) (Just $ highlightType $ identInfo dets)+      maybeToList (makeHighlight n ref)+    makeHighlight n (sp,dets)+      | isTvNameSpace (nameNameSpace n) && isBadSpan n sp = Nothing+      | otherwise = Just $ DocumentHighlight (realSrcSpanToRange sp) (Just $ highlightType $ identInfo dets)     highlightType s =       if any (isJust . getScopeFromContext) s         then DocumentHighlightKind_Write         else DocumentHighlightKind_Read +    isBadSpan :: Name -> RealSrcSpan -> Bool+    isBadSpan n sp = srcSpanStartLine sp /= srcSpanEndLine sp || (srcSpanEndCol sp - srcSpanStartCol sp > lengthFS (occNameFS $ nameOccName n))++-- | Locate the type definition of the name at a given position. gotoTypeDefinition   :: MonadIO m   => WithHieDb@@ -186,7 +201,7 @@   -> IdeOptions   -> HieAstResult   -> Position-  -> MaybeT m [Location]+  -> MaybeT m [(Location, Identifier)] gotoTypeDefinition withHieDb lookupModule ideOpts srcSpans pos   = lift $ typeLocationsAtPoint withHieDb lookupModule ideOpts pos srcSpans @@ -197,12 +212,25 @@   -> LookupModule m   -> IdeOptions   -> M.Map ModuleName NormalizedFilePath-  -> HieASTs a+  -> HieAstResult   -> Position-  -> MaybeT m [Location]+  -> MaybeT m [(Location, Identifier)] gotoDefinition withHieDb getHieFile ideOpts imports srcSpans pos   = lift $ locationsAtPoint withHieDb getHieFile ideOpts imports pos srcSpans +-- | Locate the implementation definition of the name at a given position.+-- Goto Implementation for an overloaded function.+gotoImplementation+  :: MonadIO m+  => WithHieDb+  -> LookupModule m+  -> IdeOptions+  -> HieAstResult+  -> Position+  -> MaybeT m [Location]+gotoImplementation withHieDb getHieFile ideOpts srcSpans pos+  = lift $ instanceLocationsAtPoint withHieDb getHieFile ideOpts pos srcSpans+ -- | Synopsis for the name at a given position. atPoint   :: IdeOptions@@ -211,13 +239,13 @@   -> HscEnv   -> Position   -> IO (Maybe (Maybe Range, [T.Text]))-atPoint IdeOptions{} (HAR _ hf _ _ (kind :: HieKind hietype)) (DKMap dm km) env pos =+atPoint IdeOptions{} (HAR _ (hf :: HieASTs a) rf _ (kind :: HieKind hietype)) (DKMap dm km) env pos =     listToMaybe <$> sequence (pointCommand hf pos hoverInfo)   where     -- Hover info for values/data     hoverInfo :: HieAST hietype -> IO (Maybe Range, [T.Text])     hoverInfo ast = do-        prettyNames <- mapM prettyName filteredNames+        prettyNames <- mapM prettyName names         pure (Just range, prettyNames ++ pTypes)       where         pTypes :: [T.Text]@@ -234,24 +262,34 @@         info :: NodeInfo hietype         info = nodeInfoH kind ast +        -- We want evidence variables to be displayed last.+        -- Evidence trees contain information of secondary relevance.         names :: [(Identifier, IdentifierDetails hietype)]-        names = M.assocs $ nodeIdentifiers info--        -- Check for evidence bindings-        isInternal :: (Identifier, IdentifierDetails a) -> Bool-        isInternal (Right _, dets) =-          any isEvidenceContext $ identInfo dets-        isInternal (Left _, _) = False--        filteredNames :: [(Identifier, IdentifierDetails hietype)]-        filteredNames = filter (not . isInternal) names+        names = sortOn (any isEvidenceUse . identInfo . snd) $ M.assocs $ nodeIdentifiers info          prettyName :: (Either ModuleName Name, IdentifierDetails hietype) -> IO T.Text-        prettyName (Right n, dets) = pure $ T.unlines $-          wrapHaskell (printOutputable n <> maybe "" (" :: " <>) ((prettyType <$> identType dets) <|> maybeKind))-          : maybeToList (pretty (definedAt n) (prettyPackageName n))-          ++ catMaybes [ T.unlines . spanDocToMarkdown <$> lookupNameEnv dm n-                       ]+        prettyName (Right n, dets)+          -- We want to print evidence variable using a readable tree structure.+          -- Evidence variables contain information why a particular instance or+          -- type equality was chosen, paired with location information.+          | any isEvidenceUse (identInfo dets) =+            let+              -- The evidence tree may not be present for some reason, e.g., the 'Name' is not+              -- present in the tree.+              -- Thus, we need to handle it here, but in practice, this should never be 'Nothing'.+              evidenceTree = maybe "" (printOutputable . renderEvidenceTree) (getEvidenceTree rf n)+            in+              pure $ evidenceTree <> "\n"+          -- Identifier details that are not evidence variables are used to display type information and+          -- documentation of that name.+          | otherwise =+            let+              typeSig = wrapHaskell (printOutputable n <> maybe "" (" :: " <>) ((prettyType <$> identType dets) <|> maybeKind))+              definitionLoc = maybeToList (pretty (definedAt n) (prettyPackageName n))+              docs = maybeToList (T.unlines . spanDocToMarkdown <$> lookupNameEnv dm n)+            in+              pure $ T.unlines $+                [typeSig] ++ definitionLoc ++ docs           where maybeKind = fmap printOutputable $ safeTyThingType =<< lookupNameEnv km n                 pretty Nothing Nothing = Nothing                 pretty (Just define) Nothing = Just $ define <> "\n"@@ -269,7 +307,7 @@         -- the package(with version) this `ModuleName` belongs to.         packageNameForImportStatement :: ModuleName -> IO T.Text         packageNameForImportStatement mod = do-          mpkg <- findImportedModule env mod :: IO (Maybe Module)+          mpkg <- findImportedModule (setNonHomeFCHook env) mod :: IO (Maybe Module)           let moduleName = printOutputable mod           case mpkg >>= packageNameWithVersion of             Nothing             -> pure moduleName@@ -285,7 +323,7 @@               version = T.pack $ showVersion (unitPackageVersion conf)           pure $ pkgName <> "-" <> version -        -- Type info for the current node, it may contains several symbols+        -- Type info for the current node, it may contain several symbols         -- for one range, like wildcard         types :: [hietype]         types = nodeType info@@ -294,10 +332,13 @@         prettyTypes = map (("_ :: "<>) . prettyType) types          prettyType :: hietype -> T.Text-        prettyType t = case kind of-          HieFresh -> printOutputable t-          HieFromDisk full_file -> printOutputable $ hieTypeToIface $ recoverFullType t (hie_types full_file)+        prettyType = printOutputable . expandType +        expandType :: a -> SDoc+        expandType t = case kind of+          HieFresh -> ppr t+          HieFromDisk full_file -> ppr $ hieTypeToIface $ recoverFullType t (hie_types full_file)+         definedAt :: Name -> Maybe T.Text         definedAt name =           -- do not show "at <no location info>" and similar messages@@ -306,6 +347,67 @@             UnhelpfulLoc {} | isInternalName name || isSystemName name -> Nothing             _ -> Just $ "*Defined " <> printOutputable (pprNameDefnLoc name) <> "*" +        -- We want to render the root constraint even if it is a let,+        -- but we don't want to render any subsequent lets+        renderEvidenceTree :: Tree (EvidenceInfo a) -> SDoc+        -- However, if the root constraint is simply a<n indirection (via let) to a single other constraint,+        -- we can still skip rendering it+        -- The evidence ghc generates is made up of a few primitives, like @WpLet@ (let bindings),+        -- @WpEvLam@ (lambda abstractions) and so on.+        -- The let binding refers to these lets.+        --+        -- For example, evidence for @Show ([Int], Bool)@ might look like:+        --+        -- @+        --   $dShow,[]IntBool = $fShow,[]IntBool+        --   -- indirection, we don't gain anything by printing this+        --   $fShow,[]IntBool = $dShow, $fShow[]Int $fShowBool+        --   -- This is the root "let" we render as a tree+        --   $fShow[]Int = $dShow[] $fShowInt+        --   -- second level let, collapse it into its parent $fShow,[]IntBool+        --   $fShowInt = base:Data.Int.$dShowInt+        --   -- indirection, remove it+        --   $fShowBool = base:Data.Bool.$dShowBool+        --   -- indirection, remove it+        --+        --   in $dShow,[]IntBool+        -- @+        --+        -- On doing this we end up with the tree @Show ([Int], Bool) -> (Show (,), Show [], Show Int, Show Bool)@+        --+        -- It is also quite helpful to look at the @.hie@ file directly to see how the+        -- evidence information is presented on disk. @hiedb dump <mod.hie>@+        renderEvidenceTree (T.Node (EvidenceInfo{evidenceDetails=Just (EvLetBind _,_,_)}) [x])+          = renderEvidenceTree x+        renderEvidenceTree (T.Node (EvidenceInfo{evidenceDetails=Just (EvLetBind _,_,_), ..}) xs)+          = hang (text "Evidence of constraint `" O.<> expandType evidenceType O.<> "`") 2 $+                 vcat $ text "constructed using:" : map renderEvidenceTree' xs+        renderEvidenceTree (T.Node (EvidenceInfo{..}) _)+          = hang (text "Evidence of constraint `" O.<> expandType evidenceType O.<> "`") 2 $+                 vcat $ printDets evidenceSpan evidenceDetails : map (text . T.unpack) (maybeToList $ definedAt evidenceVar)++        -- renderEvidenceTree' skips let bound evidence variables and prints the children directly+        renderEvidenceTree' (T.Node (EvidenceInfo{evidenceDetails=Just (EvLetBind _,_,_)}) xs)+          = vcat (map renderEvidenceTree' xs)+        renderEvidenceTree' (T.Node (EvidenceInfo{..}) _)+          = hang (text "- `" O.<> expandType evidenceType O.<> "`") 2 $+              vcat $+                printDets evidenceSpan evidenceDetails : map (text . T.unpack) (maybeToList $ definedAt evidenceVar)++        printDets :: RealSrcSpan -> Maybe (EvVarSource, Scope, Maybe Span) -> SDoc+        printDets _    Nothing = text "using an external instance"+        printDets ospn (Just (src,_,mspn)) = pprSrc+                                      $$ text "at" <+> text (T.unpack $ srcSpanToMdLink location)+          where+            location = realSrcSpanToLocation spn+            -- Use the bind span if we have one, else use the occurrence span+            spn = fromMaybe ospn mspn+            pprSrc = case src of+              -- Users don't know what HsWrappers are+              EvWrapperBind -> "bound by type signature or pattern"+              _             -> ppr src++-- | Find 'Location's of type definition at a specific point and return them along with their 'Identifier's. typeLocationsAtPoint   :: forall m    . MonadIO m@@ -314,14 +416,14 @@   -> IdeOptions   -> Position   -> HieAstResult-  -> m [Location]+  -> m [(Location, Identifier)] typeLocationsAtPoint withHieDb lookupModule _ideOptions pos (HAR _ ast _ _ hieKind) =   case hieKind of     HieFromDisk hf ->       let arr = hie_types hf           ts = concat $ pointCommand ast pos getts           unfold = map (arr A.!)-          getts x = nodeType ni  ++ (mapMaybe identType $ M.elems $ nodeIdentifiers ni)+          getts x = nodeType ni  ++ mapMaybe identType (M.elems $ nodeIdentifiers ni)             where ni = nodeInfo' x           getTypes' ts' = flip concatMap (unfold ts') $ \case             HTyVarTy n -> [n]@@ -332,12 +434,12 @@             HQualTy a b -> getTypes' [a,b]             HCastTy a -> getTypes' [a]             _ -> []-        in fmap nubOrd $ concatMapM (fmap (fromMaybe []) . nameToLocation withHieDb lookupModule) (getTypes' ts)+        in fmap nubOrd $ concatMapM (\n -> fmap (maybe [] (fmap (,Right n))) (nameToLocation withHieDb lookupModule n)) (getTypes' ts)     HieFresh ->       let ts = concat $ pointCommand ast pos getts-          getts x = nodeType ni  ++ (mapMaybe identType $ M.elems $ nodeIdentifiers ni)+          getts x = nodeType ni  ++ mapMaybe identType (M.elems $ nodeIdentifiers ni)             where ni = nodeInfo x-        in fmap nubOrd $ concatMapM (fmap (fromMaybe []) . nameToLocation withHieDb lookupModule) (getTypes ts)+        in fmap nubOrd $ concatMapM (\n -> fmap (maybe [] (fmap (,Right n))) (nameToLocation withHieDb lookupModule n)) (getTypes ts)  namesInType :: Type -> [Name] namesInType (TyVarTy n)      = [varName n]@@ -350,24 +452,46 @@ namesInType _                = []  getTypes :: [Type] -> [Name]-getTypes ts = concatMap namesInType ts+getTypes = concatMap namesInType +-- | Find 'Location's of definition at a specific point and return them along with their 'Identifier's. locationsAtPoint-  :: forall m a+  :: forall m    . MonadIO m   => WithHieDb   -> LookupModule m   -> IdeOptions   -> M.Map ModuleName NormalizedFilePath   -> Position-  -> HieASTs a-  -> m [Location]-locationsAtPoint withHieDb lookupModule _ideOptions imports pos ast =+  -> HieAstResult+  -> m [(Location, Identifier)]+locationsAtPoint withHieDb lookupModule _ideOptions imports pos (HAR _ ast _rm _ _) =   let ns = concat $ pointCommand ast pos (M.keys . getNodeIds)       zeroPos = Position 0 0       zeroRange = Range zeroPos zeroPos-      modToLocation m = fmap (\fs -> pure $ Location (fromNormalizedUri $ filePathToUri' fs) zeroRange) $ M.lookup m imports-    in fmap (nubOrd . concat) $ mapMaybeM (either (pure . modToLocation) $ nameToLocation withHieDb lookupModule) ns+      modToLocation m = fmap (\fs -> pure (Location (fromNormalizedUri $ filePathToUri' fs) zeroRange)) $ M.lookup m imports+   in fmap (nubOrd . concat) $ mapMaybeM+        (either (\m -> pure ((fmap $ fmap (,Left m)) (modToLocation m)))+                (\n -> fmap (fmap $ fmap (,Right n)) (nameToLocation withHieDb lookupModule n)))+        ns++-- | Find 'Location's of a implementation definition at a specific point.+instanceLocationsAtPoint+  :: forall m+   . MonadIO m+  => WithHieDb+  -> LookupModule m+  -> IdeOptions+  -> Position+  -> HieAstResult+  -> m [Location]+instanceLocationsAtPoint withHieDb lookupModule _ideOptions pos (HAR _ ast _rm _ _) =+  let ns = concat $ pointCommand ast pos (M.keys . getNodeIds)+      evTrees = mapMaybe (eitherToMaybe >=> getEvidenceTree _rm) ns+      evNs = concatMap (map (evidenceVar) . T.flatten) evTrees+   in fmap (nubOrd . concat) $ mapMaybeM+        (nameToLocation withHieDb lookupModule)+        evNs  -- | Given a 'Name' attempt to find the location where it is defined. nameToLocation :: MonadIO m => WithHieDb -> LookupModule m -> Name -> m (Maybe [Location])
src/Development/IDE/Spans/Common.hs view
@@ -13,22 +13,26 @@ , spanDocToMarkdownForTest , DocMap , TyThingMap+, srcSpanToMdLink ) where  import           Control.DeepSeq+import           Data.Bifunctor               (second) import           Data.List.Extra import           Data.Maybe import qualified Data.Text                    as T-import           GHC.Generics-+import           Development.IDE.GHC.Util+import qualified Documentation.Haddock.Parser as H+import qualified Documentation.Haddock.Types  as H import           GHC+import           GHC.Generics+import           System.FilePath -import           Data.Bifunctor               (second)+import           Control.Lens import           Development.IDE.GHC.Compat import           Development.IDE.GHC.Orphans  ()-import           Development.IDE.GHC.Util-import qualified Documentation.Haddock.Parser as H-import qualified Documentation.Haddock.Types  as H+import qualified Language.LSP.Protocol.Lens   as JL+import           Language.LSP.Protocol.Types  type DocMap = NameEnv SpanDoc type TyThingMap = NameEnv TyThing@@ -54,13 +58,8 @@ safeTyThingId _                                = Nothing  -- Possible documentation for an element in the code-#if MIN_VERSION_ghc(9,3,0) data SpanDoc   = SpanDocString [HsDocString] SpanDocUris-#else-data SpanDoc-  = SpanDocString HsDocString SpanDocUris-#endif   | SpanDocText   [T.Text] SpanDocUris   deriving stock (Eq, Show, Generic)   deriving anyclass NFData@@ -97,11 +96,7 @@ spanDocToMarkdown = \case     (SpanDocString docs uris) ->         let doc = T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $-#if MIN_VERSION_ghc(9,3,0)                       renderHsDocStrings docs-#else-                      unpackHDS docs-#endif         in  go [doc] uris     (SpanDocText txt uris) -> go txt uris   where@@ -118,8 +113,14 @@   [ linkify "Documentation" <$> mdoc   , linkify "Source" <$> msrc   ]-  where linkify title uri = "[" <> title <> "](" <> uri <> ")" +-- | Generate a markdown link.+--+-- >>> linkify "Title" "uri"+-- "[Title](Uri)"+linkify :: T.Text -> T.Text -> T.Text+linkify title uri = "[" <> title <> "](" <> uri <> ")"+ spanDocToMarkdownForTest :: String -> String spanDocToMarkdownForTest   = haddockToMarkdown . H.toRegular . H._doc . H.parseParas Nothing@@ -224,3 +225,35 @@   = case lines s of       []           -> ""       (first:rest) -> unlines $ first : map (("  " ++) . trimStart) rest++-- | Generate a source link for the 'Location' according to VSCode's supported form:+-- https://github.com/microsoft/vscode/blob/b3ec8181fc49f5462b5128f38e0723ae85e295c2/src/vs/platform/opener/common/opener.ts#L151-L160+--+srcSpanToMdLink :: Location -> T.Text+srcSpanToMdLink location =+  let+    uri = location ^. JL.uri+    range = location ^. JL.range+    -- LSP 'Range' starts at '0', but link locations start at '1'.+    intText n = T.pack $ show (n + 1)+    srcRangeText =+      T.concat+        [ "L"+        , intText (range ^. JL.start . JL.line)+        , ","+        , intText (range ^. JL.start . JL.character)+        , "-L"+        , intText (range ^. JL.end . JL.line)+        , ","+        , intText (range ^. JL.end . JL.character)+        ]++    -- If the 'Location' is a 'FilePath', display it in shortened form.+    -- This avoids some redundancy and better readability for the user.+    title = case uriToFilePath uri of+      Just fp -> T.pack (takeFileName fp) <> ":" <> intText (range ^. JL.start . JL.line)+      Nothing -> getUri uri++    srcLink = getUri uri <> "#" <> srcRangeText+  in+   linkify title srcLink
src/Development/IDE/Spans/Documentation.hs view
@@ -41,16 +41,8 @@   -> IO DocAndTyThingMap mkDocMap env rm this_mod =   do-#if MIN_VERSION_ghc(9,3,0)      (Just Docs{docs_decls = UniqMap this_docs}) <- extractDocs (hsc_dflags env) this_mod-#else-     (_ , DeclDocMap this_docs, _) <- extractDocs this_mod-#endif-#if MIN_VERSION_ghc(9,3,0)      d <- foldrM getDocs (fmap (\(_, x) -> (map hsDocString x) `SpanDocString` SpanDocUris Nothing Nothing) this_docs) names-#else-     d <- foldrM getDocs (mkNameEnv $ M.toList $ fmap (`SpanDocString` SpanDocUris Nothing Nothing) this_docs) names-#endif      k <- foldrM getType (tcg_type_env this_mod) names      pure $ DKMap d k   where@@ -84,11 +76,7 @@       Left _    -> return []       Right res -> zipWithM unwrap res names   where-#if MIN_VERSION_ghc(9,3,0)     unwrap (Right (Just docs, _)) n = SpanDocString (map hsDocString docs) <$> getUris n-#else-    unwrap (Right (Just docs, _)) n = SpanDocString docs <$> getUris n-#endif     unwrap _ n                      = mkSpanDocText n      mkSpanDocText name =
src/Development/IDE/Spans/Pragmas.hs view
@@ -15,6 +15,8 @@ import qualified Data.Maybe                      as Maybe import           Data.Text                       (Text, pack) import qualified Data.Text                       as Text+import           Data.Text.Utf16.Rope.Mixed      (Rope)+import qualified Data.Text.Utf16.Rope.Mixed      as Rope import           Development.IDE                 (srcSpanToRange, IdeState, NormalizedFilePath, GhcSession (..), getFileContents, hscEnv, runAction) import           Development.IDE.GHC.Compat import           Development.IDE.GHC.Compat.Util@@ -27,10 +29,10 @@ import           Development.IDE.Core.PluginUtils import qualified Language.LSP.Protocol.Lens     as L -getNextPragmaInfo :: DynFlags -> Maybe Text -> NextPragmaInfo-getNextPragmaInfo dynFlags mbSourceText =-  if | Just sourceText <- mbSourceText-     , let sourceStringBuffer = stringToStringBuffer (Text.unpack sourceText)+getNextPragmaInfo :: DynFlags -> Maybe Rope -> NextPragmaInfo+getNextPragmaInfo dynFlags mbSource =+  if | Just source <- mbSource+     , let sourceStringBuffer = stringToStringBuffer (Text.unpack (Rope.toText source))      , POk _ parserState <- parsePreDecl dynFlags sourceStringBuffer      -> case parserState of          ParserStateNotDone{ nextPragma } -> nextPragma@@ -56,7 +58,7 @@ getFirstPragma :: MonadIO m => PluginId -> IdeState -> NormalizedFilePath -> ExceptT PluginError m NextPragmaInfo getFirstPragma (PluginId pId) state nfp = do   (hscEnv -> hsc_dflags -> sessionDynFlags, _) <- runActionE (T.unpack pId <> ".GhcSession") state $ useWithStaleE GhcSession nfp-  (_, fileContents) <- liftIO $ runAction (T.unpack pId <> ".GetFileContents") state $ getFileContents nfp+  fileContents <- liftIO $ runAction (T.unpack pId <> ".GetFileContents") state $ getFileContents nfp   pure $ getNextPragmaInfo sessionDynFlags fileContents  -- Pre-declaration comments parser -----------------------------------------------------
src/Development/IDE/Types/Diagnostics.hs view
@@ -1,32 +1,69 @@ -- Copyright (c) 2019 The DAML Authors. All rights reserved. -- SPDX-License-Identifier: Apache-2.0 +{-# LANGUAGE CPP             #-}+{-# LANGUAGE DeriveGeneric   #-}+{-# LANGUAGE TemplateHaskell #-}  module Development.IDE.Types.Diagnostics (   LSP.Diagnostic(..),   ShowDiagnostic(..),-  FileDiagnostic,+  FileDiagnostic(..),+  fdFilePathL,+  fdLspDiagnosticL,+  fdShouldShowDiagnosticL,+  fdStructuredMessageL,+  StructuredMessage(..),+  _NoStructuredMessage,+  _SomeStructuredMessage,   IdeResult,   LSP.DiagnosticSeverity(..),   DiagnosticStore,   ideErrorText,   ideErrorWithSource,+  ideErrorFromLspDiag,   showDiagnostics,   showDiagnosticsColored,-  IdeResultNoDiagnosticsEarlyCutoff) where+#if MIN_VERSION_ghc(9,5,0)+  showGhcCode,+#endif+  IdeResultNoDiagnosticsEarlyCutoff,+  attachReason,+  attachedReason) where +import           Control.Applicative            ((<|>)) import           Control.DeepSeq+import           Control.Lens+import qualified Data.Aeson                     as JSON+import qualified Data.Aeson.Lens                as JSON import           Data.ByteString                (ByteString)+import           Data.Foldable import           Data.Maybe                     as Maybe import qualified Data.Text                      as T+import           Development.IDE.GHC.Compat     (GhcMessage, MsgEnvelope,+                                                 WarningFlag, flagSpecFlag,+                                                 flagSpecName, wWarningFlags) import           Development.IDE.Types.Location+import           GHC.Generics+#if MIN_VERSION_ghc(9,5,0)+import           GHC.Types.Error                (DiagnosticCode (..),+                                                 DiagnosticReason (..),+                                                 diagnosticCode,+                                                 diagnosticReason,+                                                 errMsgDiagnostic)+#else+import           GHC.Types.Error                (DiagnosticReason (..),+                                                 diagnosticReason,+                                                 errMsgDiagnostic)+#endif import           Language.LSP.Diagnostics-import           Language.LSP.Protocol.Types    as LSP (Diagnostic (..),-                                                        DiagnosticSeverity (..))+import           Language.LSP.Protocol.Lens     (data_)+import           Language.LSP.Protocol.Types    as LSP import           Prettyprinter import           Prettyprinter.Render.Terminal  (Color (..), color) import qualified Prettyprinter.Render.Terminal  as Terminal import           Prettyprinter.Render.Text+import           Text.Printf                    (printf)   -- | The result of an IDE operation. Warnings and errors are in the Diagnostic,@@ -44,26 +81,102 @@ -- | an IdeResult with a fingerprint type IdeResultNoDiagnosticsEarlyCutoff  v = (Maybe ByteString, Maybe v) +-- | Produce a 'FileDiagnostic' for the given 'NormalizedFilePath'+-- with an error message. ideErrorText :: NormalizedFilePath -> T.Text -> FileDiagnostic-ideErrorText = ideErrorWithSource (Just "compiler") (Just DiagnosticSeverity_Error)+ideErrorText nfp msg =+  ideErrorWithSource (Just "compiler") (Just DiagnosticSeverity_Error) nfp msg Nothing +-- | Create a 'FileDiagnostic' from an existing 'LSP.Diagnostic' for a+-- specific 'NormalizedFilePath'.+-- The optional 'MsgEnvelope GhcMessage' is the original error message+-- that was used for creating the 'LSP.Diagnostic'.+-- It is included here, to allow downstream consumers, such as HLS plugins,+-- to provide LSP features based on the structured error messages.+-- Additionally, if available, we insert the ghc error code into the+-- 'LSP.Diagnostic'. These error codes are used in https://errors.haskell.org/+-- to provide documentation and explanations for error messages.+ideErrorFromLspDiag+  :: LSP.Diagnostic+  -> NormalizedFilePath+  -> Maybe (MsgEnvelope GhcMessage)+  -> FileDiagnostic+ideErrorFromLspDiag lspDiag fdFilePath mbOrigMsg =+  let fdShouldShowDiagnostic = ShowDiag+      fdStructuredMessage =+        case mbOrigMsg of+          Nothing  -> NoStructuredMessage+          Just msg -> SomeStructuredMessage msg+      fdLspDiagnostic =+        lspDiag+          & attachReason (fmap (diagnosticReason . errMsgDiagnostic) mbOrigMsg)+          & setGhcCode mbOrigMsg+  in+  FileDiagnostic {..}++-- | Set the code of the 'LSP.Diagnostic' to the GHC diagnostic code which is linked+-- to https://errors.haskell.org/.+setGhcCode :: Maybe (MsgEnvelope GhcMessage) -> LSP.Diagnostic -> LSP.Diagnostic+#if MIN_VERSION_ghc(9,5,0)+setGhcCode mbOrigMsg diag =+  let mbGhcCode = do+          origMsg <- mbOrigMsg+          code <- diagnosticCode (errMsgDiagnostic origMsg)+          pure (InR (showGhcCode code))+  in+  diag { _code = mbGhcCode <|> _code diag }+#else+setGhcCode _ diag = diag+#endif++#if MIN_VERSION_ghc(9,9,0)+-- DiagnosticCode only got a show instance in 9.10.1+showGhcCode :: DiagnosticCode -> T.Text+showGhcCode = T.pack . show+#elif MIN_VERSION_ghc(9,5,0)+showGhcCode :: DiagnosticCode -> T.Text+showGhcCode (DiagnosticCode prefix c) = T.pack $ prefix ++ "-" ++ printf "%05d" c+#endif++attachedReason :: Traversal' Diagnostic (Maybe JSON.Value)+attachedReason = data_ . non (JSON.object []) . JSON.atKey "attachedReason"++attachReason :: Maybe DiagnosticReason -> Diagnostic -> Diagnostic+attachReason Nothing = id+attachReason (Just wr) = attachedReason .~ fmap JSON.toJSON (showReason wr)+ where+  showReason = \case+    WarningWithFlag flag -> Just $ catMaybes [showFlag flag]+#if MIN_VERSION_ghc(9,7,0)+    WarningWithFlags flags -> Just $ catMaybes (fmap showFlag $ toList flags)+#endif+    _                    -> Nothing++showFlag :: WarningFlag -> Maybe T.Text+showFlag flag = ("-W" <>) . T.pack . flagSpecName <$> find ((== flag) . flagSpecFlag) wWarningFlags+ ideErrorWithSource   :: Maybe T.Text   -> Maybe DiagnosticSeverity-  -> a+  -> NormalizedFilePath   -> T.Text-  -> (a, ShowDiagnostic, Diagnostic)-ideErrorWithSource source sev fp msg = (fp, ShowDiag, LSP.Diagnostic {-    _range = noRange,-    _severity = sev,-    _code = Nothing,-    _source = source,-    _message = msg,-    _relatedInformation = Nothing,-    _tags = Nothing,-    _codeDescription = Nothing,-    _data_ = Nothing-    })+  -> Maybe (MsgEnvelope GhcMessage)+  -> FileDiagnostic+ideErrorWithSource source sev fdFilePath msg origMsg =+  let lspDiagnostic =+        LSP.Diagnostic {+          _range = noRange,+          _severity = sev,+          _code = Nothing,+          _source = source,+          _message = msg,+          _relatedInformation = Nothing,+          _tags = Nothing,+          _codeDescription = Nothing,+          _data_ = Nothing+        }+  in+  ideErrorFromLspDiag lspDiagnostic fdFilePath origMsg  -- | Defines whether a particular diagnostic should be reported --   back to the user.@@ -80,14 +193,79 @@ instance NFData ShowDiagnostic where     rnf = rwhnf +-- | A Maybe-like wrapper for a GhcMessage that doesn't try to compare, show, or+-- force the GhcMessage inside, so that we can derive Show, Eq, Ord, NFData on+-- FileDiagnostic. FileDiagnostic only uses this as metadata so we can safely+-- ignore it in fields.+--+-- Instead of pattern matching on these constructors directly, consider 'Prism' from+-- the 'lens' package. This allows to conveniently pattern match deeply into the 'MsgEnvelope GhcMessage'+-- constructor.+-- The module 'Development.IDE.GHC.Compat.Error' implements additional 'Lens's and 'Prism's,+-- allowing you to avoid importing GHC modules directly.+--+-- For example, to pattern match on a 'TcRnMessage' you can use the lens:+--+-- @+--   message ^? _SomeStructuredMessage . msgEnvelopeErrorL . _TcRnMessage+-- @+--+-- This produces a value of type `Maybe TcRnMessage`.+--+-- Further, consider utility functions such as 'stripTcRnMessageContext', which strip+-- context from error messages which may be more convenient in certain situations.+data StructuredMessage+  = NoStructuredMessage+  | SomeStructuredMessage (MsgEnvelope GhcMessage)+  deriving (Generic)++instance Show StructuredMessage where+  show NoStructuredMessage      = "NoStructuredMessage"+  show SomeStructuredMessage {} = "SomeStructuredMessage"++instance Eq StructuredMessage where+  (==) NoStructuredMessage NoStructuredMessage           = True+  (==) SomeStructuredMessage {} SomeStructuredMessage {} = True+  (==) _ _                                               = False++instance Ord StructuredMessage where+  compare NoStructuredMessage NoStructuredMessage           = EQ+  compare SomeStructuredMessage {} SomeStructuredMessage {} = EQ+  compare NoStructuredMessage SomeStructuredMessage {}      = GT+  compare SomeStructuredMessage {} NoStructuredMessage      = LT++instance NFData StructuredMessage where+  rnf NoStructuredMessage      = ()+  rnf SomeStructuredMessage {} = ()+ -- | Human readable diagnostics for a specific file. -- --   This type packages a pretty printed, human readable error message --   along with the related source location so that we can display the error --   on either the console or in the IDE at the right source location. ---type FileDiagnostic = (NormalizedFilePath, ShowDiagnostic, Diagnostic)+--   It also optionally keeps a structured diagnostic message GhcMessage in+--   StructuredMessage.+--+data FileDiagnostic = FileDiagnostic+  { fdFilePath             :: NormalizedFilePath+  , fdShouldShowDiagnostic :: ShowDiagnostic+  , fdLspDiagnostic        :: Diagnostic+    -- | The original diagnostic that was used to produce 'fdLspDiagnostic'.+    -- We keep it here, so downstream consumers, e.g. HLS plugins, can use the+    -- the structured error messages and don't have to resort to parsing+    -- error messages via regexes or similar.+    --+    -- The optional GhcMessage inside of this StructuredMessage is ignored for+    -- Eq, Ord, Show, and NFData instances. This is fine because this field+    -- should only ever be metadata and should never be used to distinguish+    -- between FileDiagnostics.+  , fdStructuredMessage    :: StructuredMessage+  }+  deriving (Eq, Ord, Show, Generic) +instance NFData FileDiagnostic+ prettyRange :: Range -> Doc Terminal.AnsiStyle prettyRange Range{..} = f _start <> "-" <> f _end     where f Position{..} = pretty (show $ _line+1) <> colon <> pretty (show $ _character+1)@@ -106,13 +284,17 @@ prettyDiagnostics = vcat . map prettyDiagnostic  prettyDiagnostic :: FileDiagnostic -> Doc Terminal.AnsiStyle-prettyDiagnostic (fp, sh, LSP.Diagnostic{..}) =+prettyDiagnostic FileDiagnostic { fdFilePath, fdShouldShowDiagnostic, fdLspDiagnostic = LSP.Diagnostic{..} } =     vcat-        [ slabel_ "File:    " $ pretty (fromNormalizedFilePath fp)-        , slabel_ "Hidden:  " $ if sh == ShowDiag then "no" else "yes"+        [ slabel_ "File:    " $ pretty (fromNormalizedFilePath fdFilePath)+        , slabel_ "Hidden:  " $ if fdShouldShowDiagnostic == ShowDiag then "no" else "yes"         , slabel_ "Range:   " $ prettyRange _range         , slabel_ "Source:  " $ pretty _source         , slabel_ "Severity:" $ pretty $ show sev+        , slabel_ "Code:    " $ case _code of+                                  Just (InR text) -> pretty text+                                  Just (InL i)    -> pretty i+                                  Nothing         -> "<none>"         , slabel_ "Message: "             $ case sev of               LSP.DiagnosticSeverity_Error       -> annotate $ color Red@@ -150,3 +332,9 @@  defaultTermWidth :: Int defaultTermWidth = 80++makePrisms ''StructuredMessage++makeLensesWith+    (lensRules & lensField .~ mappingNamer (pure . (++ "L")))+    ''FileDiagnostic
src/Development/IDE/Types/HscEnvEq.hs view
@@ -1,25 +1,21 @@+{-# LANGUAGE CPP #-} module Development.IDE.Types.HscEnvEq (   HscEnvEq,     hscEnv, newHscEnvEq,-    hscEnvWithImportPaths,-    newHscEnvEqPreserveImportPaths,-    newHscEnvEqWithImportPaths,     updateHscEnvEq,-    envImportPaths,     envPackageExports,     envVisibleModuleNames,-    deps ) where   import           Control.Concurrent.Async        (Async, async, waitCatch) import           Control.Concurrent.Strict       (modifyVar, newVar)-import           Control.DeepSeq                 (force)+import           Control.DeepSeq                 (force, rwhnf) import           Control.Exception               (evaluate, mask, throwIO) import           Control.Monad.Extra             (eitherM, join, mapMaybeM) import           Data.Either                     (fromRight)-import           Data.Set                        (Set)-import qualified Data.Set                        as Set+import           Data.IORef+import qualified Data.Map                        as M import           Data.Unique                     (Unique) import qualified Data.Unique                     as Unique import           Development.IDE.GHC.Compat      hiding (newUnique)@@ -28,23 +24,18 @@ import           Development.IDE.GHC.Util        (lookupPackageConfig) import           Development.IDE.Graph.Classes import           Development.IDE.Types.Exports   (ExportsMap, createExportsMap)+import           GHC.Driver.Env                  (hsc_all_home_unit_ids) import           Ide.PluginUtils                 (toAbsolute) import           OpenTelemetry.Eventlog          (withSpan)-import           System.FilePath+import           System.Directory                (makeAbsolute) + -- | An 'HscEnv' with equality. Two values are considered equal --   if they are created with the same call to 'newHscEnvEq' or --   'updateHscEnvEq'. data HscEnvEq = HscEnvEq     { envUnique             :: !Unique     , hscEnv                :: !HscEnv-    , deps                  :: [(UnitId, DynFlags)]-               -- ^ In memory components for this HscEnv-               -- This is only used at the moment for the import dirs in-               -- the DynFlags-    , envImportPaths        :: Maybe (Set FilePath)-        -- ^ If Just, import dirs originally configured in this env-        --   If Nothing, the env import dirs are unaltered     , envPackageExports     :: IO ExportsMap     , envVisibleModuleNames :: IO (Maybe [ModuleName])         -- ^ 'listVisibleModuleNames' is a pure function,@@ -59,18 +50,32 @@   update <$> Unique.newUnique  -- | Wrap an 'HscEnv' into an 'HscEnvEq'.-newHscEnvEq :: FilePath -> FilePath -> HscEnv -> [(UnitId, DynFlags)] -> IO HscEnvEq-newHscEnvEq root cradlePath hscEnv0 deps = do-    let relativeToCradle = (takeDirectory cradlePath </>)-        hscEnv = removeImportPaths hscEnv0--    -- Make Absolute since targets are also absolute-    let importPathsCanon = toAbsolute root . relativeToCradle <$> importPaths (hsc_dflags hscEnv0)+newHscEnvEq :: HscEnv -> IO HscEnvEq+newHscEnvEq hscEnv' = do -    newHscEnvEqWithImportPaths (Just $ Set.fromList importPathsCanon) hscEnv deps+    mod_cache <- newIORef emptyInstalledModuleEnv+    file_cache <- newIORef M.empty+    -- This finder cache is for things which are outside of things which are tracked+    -- by HLS. For example, non-home modules, dependent object files etc+#if MIN_VERSION_ghc(9,11,0)+    let hscEnv = hscEnv'+               { hsc_FC = FinderCache+                        { flushFinderCaches = \_ -> error "GHC should never call flushFinderCaches outside the driver"+                        , addToFinderCache  = \(GWIB im _) val -> do+                            if moduleUnit im `elem` hsc_all_home_unit_ids hscEnv'+                            then error "tried to add home module to FC"+                            else atomicModifyIORef' mod_cache $ \c -> (extendInstalledModuleEnv c im val, ())+                        , lookupFinderCache = \(GWIB im _) -> do+                            if moduleUnit im `elem` hsc_all_home_unit_ids hscEnv'+                            then error ("tried to lookup home module from FC" ++ showSDocUnsafe (ppr (im, hsc_all_home_unit_ids hscEnv')))+                            else lookupInstalledModuleEnv <$> readIORef mod_cache <*> pure im+                        , lookupFileCache = \fp -> error ("not used by HLS" ++ fp)+                        }+                } -newHscEnvEqWithImportPaths :: Maybe (Set FilePath) -> HscEnv -> [(UnitId, DynFlags)] -> IO HscEnvEq-newHscEnvEqWithImportPaths envImportPaths hscEnv deps = do+#else+    let hscEnv = hscEnv'+#endif      let dflags = hsc_dflags hscEnv @@ -112,23 +117,6 @@      return HscEnvEq{..} --- | Wrap an 'HscEnv' into an 'HscEnvEq'.-newHscEnvEqPreserveImportPaths-    :: HscEnv -> [(UnitId, DynFlags)] -> IO HscEnvEq-newHscEnvEqPreserveImportPaths = newHscEnvEqWithImportPaths Nothing---- | Unwrap the 'HscEnv' with the original import paths.---   Used only for locating imports-hscEnvWithImportPaths :: HscEnvEq -> HscEnv-hscEnvWithImportPaths HscEnvEq{..}-    | Just imps <- envImportPaths-    = hscSetFlags (setImportPaths (Set.toList imps) (hsc_dflags hscEnv)) hscEnv-    | otherwise-    = hscEnv--removeImportPaths :: HscEnv -> HscEnv-removeImportPaths hsc = hscSetFlags (setImportPaths [] (hsc_dflags hsc)) hsc- instance Show HscEnvEq where   show HscEnvEq{envUnique} = "HscEnvEq " ++ show (Unique.hashUnique envUnique) @@ -136,9 +124,9 @@   a == b = envUnique a == envUnique b  instance NFData HscEnvEq where-  rnf (HscEnvEq a b c d _ _) =+  rnf (HscEnvEq a b _ _) =       -- deliberately skip the package exports map and visible module names-      rnf (Unique.hashUnique a) `seq` b `seq` c `seq` rnf d+      rnf (Unique.hashUnique a) `seq` rwhnf b  instance Hashable HscEnvEq where   hashWithSalt s = hashWithSalt s . envUnique
src/Development/IDE/Types/Options.hs view
@@ -89,9 +89,9 @@   deriving (Eq,Ord,Show,Enum)  data IdePreprocessedSource = IdePreprocessedSource-  { preprocWarnings :: [(GHC.SrcSpan, String)]+  { preprocWarnings :: [(GHC.SrcSpan, String)] -- TODO: Future work could we make these warnings structured as well?     -- ^ Warnings emitted by the preprocessor.-  , preprocErrors   :: [(GHC.SrcSpan, String)]+  , preprocErrors   :: [(GHC.SrcSpan, String)] -- TODO: Future work could we make these errors structured as well?     -- ^ Errors emitted by the preprocessor.   , preprocSource   :: GHC.ParsedSource     -- ^ New parse tree emitted by the preprocessor.
src/Development/IDE/Types/Shake.hs view
@@ -33,10 +33,9 @@ import           HieDb.Types                          (HieDb) import qualified StmContainers.Map                    as STM import           Type.Reflection                      (SomeTypeRep (SomeTypeRep),-                                                       pattern App, pattern Con,-                                                       typeOf, typeRep,-                                                       typeRepTyCon)-import           Unsafe.Coerce                        (unsafeCoerce)+                                                       eqTypeRep, pattern App,+                                                       type (:~~:) (HRefl),+                                                       typeOf, typeRep)  -- | Intended to represent HieDb calls wrapped with (currently) retry -- functionality@@ -86,11 +85,12 @@  -- | fromKeyType (Q (k,f)) = (typeOf k, f) fromKeyType :: Key -> Maybe (SomeTypeRep, NormalizedFilePath)-fromKeyType (Key k) = case typeOf k of-    App (Con tc) a | tc == typeRepTyCon (typeRep @Q)-        -> case unsafeCoerce k of-         Q (_ :: (), f) -> Just (SomeTypeRep a, f)-    _ -> Nothing+fromKeyType (Key k)+  | App tc a <- typeOf k+  , Just HRefl <- tc `eqTypeRep` (typeRep @Q)+  , Q (_, f) <- k+  = Just (SomeTypeRep a, f)+  | otherwise = Nothing  toNoFileKey :: (Show k, Typeable k, Eq k, Hashable k) => k -> Key toNoFileKey k = newKey $ Q (k, emptyFilePath)@@ -101,12 +101,10 @@ instance Show k => Show (Q k) where     show (Q (k, file)) = show k ++ "; " ++ fromNormalizedFilePath file --- | Invariant: the 'v' must be in normal form (fully evaluated).+-- | Invariant: the @v@ must be in normal form (fully evaluated). --   Otherwise we keep repeatedly 'rnf'ing values taken from the Shake database newtype A v = A (Value v)     deriving Show--instance NFData (A v) where rnf (A v) = v `seq` ()  -- In the Shake database we only store one type of key/result pairs, -- namely Q (question) / A (answer).
src/Text/Fuzzy/Parallel.hs view
@@ -89,8 +89,7 @@              -> T.Text   -- ^ Pattern to look for.              -> [T.Text] -- ^ List of texts to check.              -> [Scored T.Text] -- ^ The ones that match.-simpleFilter chunk maxRes pattern xs =-  filter chunk maxRes pattern xs id+simpleFilter chunk maxRes pat xs = filter chunk maxRes pat xs id   -- | The function to filter a list of values by fuzzy search on the text extracted from them,@@ -104,15 +103,15 @@        -- ^ Custom scoring function to use for calculating how close words are        -- When the function returns Nothing, this means the values are incomparable.        -> [Scored t]    -- ^ The list of results, sorted, highest score first.-filter' chunkSize maxRes pattern ts extract match' = partialSortByAscScore maxRes perfectScore (concat vss)+filter' chunkSize maxRes pat ts extract match' = partialSortByAscScore maxRes perfectScore (concat vss)   where       -- Preserve case for the first character, make all others lowercase-      pattern' = case T.uncons pattern of+      pat' = case T.uncons pat of         Just (c, rest) -> T.cons c (T.toLower rest)-        _              -> pattern-      vss = map (mapMaybe (\t -> flip Scored t <$> match' pattern' (extract t))) (chunkList chunkSize ts)+        _              -> pat+      vss = map (mapMaybe (\t -> flip Scored t <$> match' pat' (extract t))) (chunkList chunkSize ts)         `using` parList (evalList rseq)-      perfectScore = fromMaybe (error $ T.unpack pattern) $ match' pattern' pattern'+      perfectScore = fromMaybe (error $ T.unpack pat) $ match' pat' pat'  -- | The function to filter a list of values by fuzzy search on the text extracted from them, -- using a custom matching function which determines how close words are.@@ -122,8 +121,8 @@        -> [t]           -- ^ The list of values containing the text to search in.        -> (t -> T.Text) -- ^ The function to extract the text from the container.        -> [Scored t]    -- ^ The list of results, sorted, highest score first.-filter chunkSize maxRes pattern ts extract =-  filter' chunkSize maxRes pattern ts extract match+filter chunkSize maxRes pat ts extract =+  filter' chunkSize maxRes pat ts extract match  -- | Return all elements of the list that have a fuzzy match against the pattern, -- the closeness of the match is determined using the custom scoring match function that is passed.@@ -136,8 +135,8 @@              -> (T.Text -> T.Text -> Maybe Int)              -- ^ Custom scoring function to use for calculating how close words are              -> [Scored T.Text] -- ^ The ones that match.-simpleFilter' chunk maxRes pattern xs match' =-  filter' chunk maxRes pattern xs id match'+simpleFilter' chunk maxRes pat xs match' =+  filter' chunk maxRes pat xs id match' --------------------------------------------------------------------------------  chunkList :: Int -> [a] -> [[a]]
− test/data/TH/THA.hs
@@ -1,6 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THA where-import Language.Haskell.TH--th_a :: DecsQ-th_a = [d| a = () |]
− test/data/TH/THB.hs
@@ -1,5 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THB where-import THA--$th_a
− test/data/TH/THC.hs
@@ -1,5 +0,0 @@-module THC where-import THB--c ::()-c = a
− test/data/TH/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["-Wmissing-signatures", "-package template-haskell", "THA", "THB", "THC"]}}
− test/data/THCoreFile/THA.hs
@@ -1,23 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THA where-import Language.Haskell.TH-import Control.Monad (when)--th_a :: DecsQ-th_a = do-  when (show (StrictConstructor1 123 True 4567) /= "StrictConstructor1 123 True 4567") $ error "TH validation error"-  when (show (StrictConstructor2 123 True 4567) /= "StrictConstructor2 123 True 4567") $ error "TH validation error"-  when (show (StrictConstructor3 123 True 4567) /= "StrictConstructor3 123 True 4567") $ error "TH validation error"-  when (show (classMethod 'z') /= "True") $ error "TH validation error"-  when (show (classMethod 'a') /= "False") $ error "TH validation error"-  [d| a = () |]--data StrictType1 = StrictConstructor1 !Int !Bool Int deriving Show-data StrictType2 = StrictConstructor2 !Int !Bool !Int deriving Show-data StrictType3 = StrictConstructor3 !Int !Bool !Int deriving Show--class SingleMethodClass a where-  classMethod :: a -> Bool--instance SingleMethodClass Char where-  classMethod = (== 'z')
− test/data/THCoreFile/THB.hs
@@ -1,13 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THB where-import THA-import Control.Monad (when)--$(do-  -- Need to verify in both defining module and usage module"-  when (show (StrictConstructor1 123 True 4567) /= "StrictConstructor1 123 True 4567") $ error "TH validation error"-  when (show (StrictConstructor2 123 True 4567) /= "StrictConstructor2 123 True 4567") $ error "TH validation error"-  when (show (StrictConstructor3 123 True 4567) /= "StrictConstructor3 123 True 4567") $ error "TH validation error"-  when (show (classMethod 'z') /= "True") $ error "TH validation error"-  when (show (classMethod 'a') /= "False") $ error "TH validation error"-  th_a)
− test/data/THCoreFile/THC.hs
@@ -1,5 +0,0 @@-module THC where-import THB--c ::()-c = a
− test/data/THCoreFile/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["-package template-haskell", "THA", "THB", "THC"]}}
− test/data/THLoading/A.hs
@@ -1,5 +0,0 @@-module A where-import B (bar)--foo :: ()-foo = bar
− test/data/THLoading/B.hs
@@ -1,4 +0,0 @@-module B where--bar :: ()-bar = ()
− test/data/THLoading/THA.hs
@@ -1,7 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THA where-import Language.Haskell.TH-import A (foo)--th_a :: DecsQ-th_a = [d| a = foo |]
− test/data/THLoading/THB.hs
@@ -1,5 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THB where-import THA--$th_a
− test/data/THLoading/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["-package template-haskell", "THA", "THB", "A", "B"]}}
− test/data/THNewName/A.hs
@@ -1,6 +0,0 @@-module A (template) where--import Language.Haskell.TH--template :: DecsQ-template = (\consA -> [DataD [] (mkName "A") [] Nothing [NormalC consA []] []]) <$> newName "A"
− test/data/THNewName/B.hs
@@ -1,5 +0,0 @@-module B(A(A)) where--import A--template
− test/data/THNewName/C.hs
@@ -1,4 +0,0 @@-module C where-import B--a = A
− test/data/THNewName/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["-XTemplateHaskell","-Wmissing-signatures","A", "B", "C"]}}
− test/data/THUnboxed/THA.hs
@@ -1,16 +0,0 @@-{-# LANGUAGE TemplateHaskell, UnboxedTuples, BangPatterns #-}-module THA where-import Language.Haskell.TH--data Foo = Foo !Int !Char !String-  deriving Show--newtype Bar = Bar Int-  deriving Show---f :: Int -> (# Int, Int, Foo, Bar#)-f x = (# x , x+1 , Foo x 'a' "test", Bar 1 #)--th_a :: DecsQ-th_a = case f 1 of (# a , b, Foo _ _ _, Bar !_ #) -> [d| a = () |]
− test/data/THUnboxed/THB.hs
@@ -1,5 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module THB where-import THA--$th_a
− test/data/THUnboxed/THC.hs
@@ -1,5 +0,0 @@-module THC where-import THB--c ::()-c = a
− test/data/THUnboxed/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["-Wmissing-signatures", "-package template-haskell", "THA", "THB", "THC"]}}
− test/data/boot/A.hs
@@ -1,10 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module A where--import B( TB(..) )--newtype TA = MkTA Int-    deriving Eq--f :: TB -> TA-f (MkTB x) = MkTA x
− test/data/boot/A.hs-boot
@@ -1,3 +0,0 @@-module A where-newtype TA = MkTA Int-instance Eq TA
− test/data/boot/B.hs
@@ -1,7 +0,0 @@-module B(TA(..), TB(..)) where-import {-# SOURCE #-} A( TA(..) )--data TB = MkTB !Int--g :: TA -> TB-g (MkTA x) = MkTB x
− test/data/boot/C.hs
@@ -1,8 +0,0 @@-module C where--import B-import A hiding (MkTA(..))--x = MkTA-y = MkTB-z = f
− test/data/boot/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["A.hs", "A.hs-boot", "B.hs", "C.hs"]}}
− test/data/boot2/A.hs
@@ -1,12 +0,0 @@-module A where---- E source imports B--- In interface file see source module dependencies: B {-# SOURCE #-}-import E--- C imports B--- In interface file see source module dependencies: B-import C---- Instance for B only available from B.hi not B.hi-boot, so tests we load--- that.-main = print B
− test/data/boot2/B.hs
@@ -1,8 +0,0 @@-module B where--import D--data B = B--instance Show B where-  show B = "B"
− test/data/boot2/B.hs-boot
@@ -1,3 +0,0 @@-module B where--data B = B
− test/data/boot2/C.hs
@@ -1,3 +0,0 @@-module C where--import B
− test/data/boot2/D.hs
@@ -1,3 +0,0 @@-module D where--import {-# SOURCE #-} B
− test/data/boot2/E.hs
@@ -1,3 +0,0 @@-module E(B(B)) where--import {-# SOURCE #-} B
− test/data/boot2/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["A.hs", "B.hs-boot", "B.hs", "C.hs", "D.hs", "E.hs"]}}
− test/data/cabal-exe/a/a.cabal
@@ -1,14 +0,0 @@-cabal-version:       2.2--name:                a-version:             0.1.0.0-author:              Fendor-maintainer:          power.walross@gmail.com-build-type:          Simple--executable a-  main-is:             Main.hs-  hs-source-dirs:      src-  ghc-options:         -Wall-  build-depends:       base-  default-language:    Haskell2010
− test/data/cabal-exe/a/src/Main.hs
@@ -1,3 +0,0 @@-module Main where--main = putStrLn "Hello, Haskell!"
− test/data/cabal-exe/cabal.project
@@ -1,1 +0,0 @@-packages: ./a
− test/data/cabal-exe/hie.yaml
@@ -1,3 +0,0 @@-cradle:-  cabal:-    component: "exe:a"
− test/data/hover/Bar.hs
@@ -1,4 +0,0 @@-module Bar (Bar(..)) where---- | Bar Haddock-data Bar = Bar
− test/data/hover/Foo.hs
@@ -1,6 +0,0 @@-module Foo (Bar, foo) where--import Bar---- | foo Haddock-foo = Bar
− test/data/hover/GotoHover.hs
@@ -1,70 +0,0 @@-{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}-{- HLINT ignore -}-module GotoHover ( module GotoHover) where-import Data.Text (Text, pack)-import Foo (Bar, foo)---data TypeConstructor = DataConstructor-  { fff :: Text-  , ggg :: Int }-aaa :: TypeConstructor-aaa = DataConstructor-  { fff = "dfgy"-  , ggg = 832-  }-bbb :: TypeConstructor-bbb = DataConstructor "mjgp" 2994-ccc :: (Text, Int)-ccc = (fff bbb, ggg aaa)-ddd :: Num a => a -> a -> a-ddd vv ww = vv +! ww-a +! b = a - b-hhh (Just a) (><) = a >< a-iii a b = a `b` a-jjj s = pack $ s <> s-class MyClass a where-  method :: a -> Int-instance MyClass Int where-  method = succ-kkk :: MyClass a => Int -> a -> Int-kkk n c = n + method c--doBind :: Maybe ()-doBind = do unwrapped <- Just ()-            return unwrapped--listCompBind :: [Char]-listCompBind = [ succ c | c <- "ptfx" ]--multipleClause :: Bool -> Char-multipleClause True  =    't'-multipleClause False = 'f'---- | Recognizable docs: kpqz-documented :: Monad m => Either Int (m a)-documented = Left 7518--listOfInt = [ 8391 :: Int, 6268 ]--outer :: Bool-outer = undefined inner where--  inner :: Char-  inner = undefined--imported :: Bar-imported = foo--aa2 :: Bool-aa2 = $(id [| True |])--hole :: Int-hole = _--hole2 :: a -> Maybe a-hole2 = _---- A comment above a type defnition with a deriving clause-data Example = Example-  deriving (Eq)
− test/data/hover/RecordDotSyntax.hs
@@ -1,18 +0,0 @@-{-# LANGUAGE OverloadedRecordDot, DuplicateRecordFields, NoFieldSelectors #-}--module RecordDotSyntax ( module RecordDotSyntax) where--import qualified Data.Maybe as M--data MyRecord = MyRecord-  { a :: String-  , b :: Integer-  , c :: MyChild-  } deriving (Eq, Show)--newtype MyChild = MyChild-  { z :: String-  } deriving (Eq, Show)--x = MyRecord { a = "Hello", b = 12, c = MyChild { z = "there" } }-y = x.a ++ show x.b ++ x.c.z
− test/data/hover/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["Foo", "Bar", "GotoHover", "RecordDotSyntax"]}}
− test/data/ignore-fatal/IgnoreFatal.hs
@@ -1,8 +0,0 @@--- "missing signature" is declared a fatal warning in the cabal file,--- but is ignored in this module.--{-# OPTIONS_GHC -fno-warn-missing-signatures #-}--module IgnoreFatal where--a = 'a'
− test/data/ignore-fatal/cabal.project
@@ -1,1 +0,0 @@-packages: ignore-fatal.cabal
− test/data/ignore-fatal/hie.yaml
@@ -1,4 +0,0 @@-cradle:-  cabal:-    - path: "."-      component: "lib:ignore-fatal"
− test/data/ignore-fatal/ignore-fatal.cabal
@@ -1,10 +0,0 @@-name: ignore-fatal-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2--library-  build-depends: base-  exposed-modules: IgnoreFatal-  hs-source-dirs: .-  ghc-options: -Werror=missing-signatures
− test/data/multi-unit-reexport/a/A.hs
@@ -1,3 +0,0 @@-module A(foo) where-import Data.Text-foo = ()
− test/data/multi-unit-reexport/b/B.hs
@@ -1,3 +0,0 @@-module B(module B) where-import A-qux = foo
− test/data/multi-unit-reexport/c/C.hs
@@ -1,4 +0,0 @@-module C(module C) where-import A-import B-cux = foo `seq` qux
− test/data/multi-unit-reexport/cabal.project
@@ -1,2 +0,0 @@-packages: a b c-multi-repl: True
− test/data/multi-unit-reexport/hie.yaml
@@ -1,6 +0,0 @@-cradle:-  direct:-    arguments: ["-unit" ,"@a-1.0.0-inplace"-               ,"-unit" ,"@b-1.0.0-inplace" -               ,"-unit" ,"@c-1.0.0-inplace"-               ]
− test/data/multi-unit/a/A.hs
@@ -1,3 +0,0 @@-module A(foo) where-import Data.Text-foo = ()
− test/data/multi-unit/b/B.hs
@@ -1,3 +0,0 @@-module B(module B) where-import "a" A-qux = foo
− test/data/multi-unit/c/C.hs
@@ -1,3 +0,0 @@-module C(module C) where-import A-cux = foo
− test/data/multi-unit/cabal.project
@@ -1,2 +0,0 @@-packages: a b c-multi-repl: True
− test/data/multi-unit/hie.yaml
@@ -1,6 +0,0 @@-cradle:-  direct:-    arguments: ["-unit" ,"@a-1.0.0-inplace"-               ,"-unit" ,"@b-1.0.0-inplace" -               ,"-unit" ,"@c-1.0.0-inplace"-               ]
− test/data/multi/a/A.hs
@@ -1,3 +0,0 @@-module A(foo) where-import Control.Concurrent.Async-foo = ()
− test/data/multi/a/a.cabal
@@ -1,9 +0,0 @@-name: a-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2--library-  build-depends: base, async >= 2.0-  exposed-modules: A-  hs-source-dirs: .
− test/data/multi/b/B.hs
@@ -1,3 +0,0 @@-module B(module B) where-import A-qux = foo
− test/data/multi/b/b.cabal
@@ -1,9 +0,0 @@-name: b-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2--library-  build-depends: base, a-  exposed-modules: B-  hs-source-dirs: .
− test/data/multi/c/C.hs
@@ -1,3 +0,0 @@-module C(module C) where-import A-cux = foo
− test/data/multi/c/c.cabal
@@ -1,9 +0,0 @@-name: c-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2--library-  build-depends: base, a-  exposed-modules: C-  hs-source-dirs: .
− test/data/multi/cabal.project
@@ -1,3 +0,0 @@-packages: a b c--allow-newer: base
− test/data/multi/hie.yaml
@@ -1,8 +0,0 @@-cradle:-  cabal:-    - path: "./a"-      component: "lib:a"-    - path: "./b"-      component: "lib:b"-    - path: "./c"-      component: "lib:c"
− test/data/plugin-knownnat/KnownNat.hs
@@ -1,10 +0,0 @@-{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}-{-# LANGUAGE DataKinds, ScopedTypeVariables, TypeOperators #-}-module KnownNat where-import Data.Proxy-import GHC.TypeLits--f :: forall n. KnownNat n => Proxy n -> Integer-f _ = natVal (Proxy :: Proxy n) + natVal (Proxy :: Proxy (n+2))-foo :: Int -> Int -> Int-foo a _b = a + c
− test/data/plugin-knownnat/cabal.project
@@ -1,4 +0,0 @@-packages: .---- Needed for ghc >= 9.0.2 and ghc-typelits-natnormalise == 0.7.6-allow-newer: ghc-typelits-natnormalise:ghc-bignum
− test/data/plugin-knownnat/plugin.cabal
@@ -1,9 +0,0 @@-cabal-version:  1.18-name: plugin-version: 1.0.0-build-type: Simple--library-  build-depends: base, ghc-typelits-knownnat-  exposed-modules: KnownNat-  hs-source-dirs: .
− test/data/recomp/A.hs
@@ -1,6 +0,0 @@-module A(x) where--import B--x :: Int-x = y
− test/data/recomp/B.hs
@@ -1,4 +0,0 @@-module B(y) where--y :: Int-y = undefined
− test/data/recomp/P.hs
@@ -1,5 +0,0 @@-module P() where-import A-import B--bar = x :: Int
− test/data/recomp/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["-Wmissing-signatures","B", "A", "P"]}}
− test/data/references/Main.hs
@@ -1,14 +0,0 @@-module Main where--import References--main :: IO ()-main = return ()----a = 2 :: Int-b = a + 1--acc :: Account-acc = Savings
− test/data/references/OtherModule.hs
@@ -1,9 +0,0 @@-module OtherModule (symbolDefinedInOtherModule, symbolDefinedInOtherOtherModule) where--import OtherOtherModule--symbolDefinedInOtherModule = 1--symbolLocalToOtherModule = 2--someFxn x = x + symbolLocalToOtherModule
− test/data/references/OtherOtherModule.hs
@@ -1,3 +0,0 @@-module OtherOtherModule where--symbolDefinedInOtherOtherModule = "asdf"
− test/data/references/References.hs
@@ -1,25 +0,0 @@-module References where--import OtherModule--foo = bar--bar = let x = bar 42 in const "hello"--baz = do-  x <- bar 23-  return $ bar 14--data Account =-  Checking-  | Savings--bobsAccount = Checking--bobHasChecking = case bobsAccount of-                     Checking -> True-                     Savings -> False--x = symbolDefinedInOtherModule--y = symbolDefinedInOtherOtherModule
− test/data/references/hie.yaml
@@ -1,1 +0,0 @@-cradle: {direct: {arguments: ["Main","OtherModule","OtherOtherModule","References"]}}
− test/data/rootUri/dirA/Foo.hs
@@ -1,3 +0,0 @@-module Foo () where--foo = ()
− test/data/rootUri/dirA/foo.cabal
@@ -1,9 +0,0 @@-name: foo-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2--library-  build-depends: base-  exposed-modules: Foo-  hs-source-dirs: .
− test/data/rootUri/dirB/Foo.hs
@@ -1,3 +0,0 @@-module Foo () where--foo = ()
− test/data/rootUri/dirB/foo.cabal
@@ -1,9 +0,0 @@-name: foo-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2--library-  build-depends: base-  exposed-modules: Foo-  hs-source-dirs: .
− test/data/symlink/hie.yaml
@@ -1,10 +0,0 @@--cradle:-  direct:-    arguments:-      - -i-      - -isrc-      - -iother_loc/-      - other_loc/Sym.hs-      - src/Foo.hs-      - -Wall
− test/data/symlink/some_loc/Sym.hs
@@ -1,4 +0,0 @@-module Sym where--foo :: String-foo = ""
− test/data/symlink/src/Foo.hs
@@ -1,4 +0,0 @@-module Foo where--import Sym-
− test/data/working-dir/a/A.hs
@@ -1,11 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module A(th_a) where--import Language.Haskell.TH-import Language.Haskell.TH.Syntax-import Control.Monad.IO.Class--th_a :: DecsQ-th_a = do-  str <- makeRelativeToProject "wdtest" >>= liftIO . readFile-  [d| a = $(lift str) |]
− test/data/working-dir/a/B.hs
@@ -1,6 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module B() where--import A--$th_a
− test/data/working-dir/a/a.cabal
@@ -1,11 +0,0 @@-name: a-version: 1.0.0-build-type: Simple-cabal-version: >= 1.2-extra-source-files: wdtest--library-  build-depends: base, template-haskell-  exposed-modules: A B-  ghc-options: -Wmissing-signatures-  hs-source-dirs: .
− test/data/working-dir/cabal.project
@@ -1,1 +0,0 @@-packages: a
− test/data/working-dir/hie.yaml
@@ -1,2 +0,0 @@-cradle:-  cabal:
− test/preprocessor/Main.hs
@@ -1,10 +0,0 @@--module Main(main) where--import           System.Environment--main :: IO ()-main = do-    _:input:output:_ <- getArgs-    let f = map (\x -> if x == 'x' then 'y' else x)-    writeFile output . f =<< readFile input