@@ -5,7 +5,9 @@ Authors: Leonardo de Moura
55-/
66prelude
77import Lean.Util.Sorry
8+ import Lean.Widget.Types
89import Lean.Message
10+ import Lean.DocString.Links
911
1012namespace Lean
1113
@@ -53,6 +55,48 @@ register_builtin_option warningAsError : Bool := {
5355 descr := "treat warnings as errors"
5456}
5557
58+ /--
59+ A widget for displaying error names and explanation links.
60+ -/
61+ -- Note that we cannot tag this as a `builtin_widget_module` in this module because doing so would
62+ -- create circular imports. Instead, we add this attribute post-hoc in `Lean.ErrorExplanation`.
63+ def errorDescriptionWidget : Widget.Module where
64+ javascript := "
65+ import { createElement } from 'react';
66+ export default function ({ code, explanationUrl }) {
67+ const sansText = { fontFamily: 'var(--vscode-font-family)' }
68+
69+ const codeSpan = createElement('span', {}, [
70+ createElement('span', { style: sansText }, 'Error code: '), code])
71+ const brSpan = createElement('span', {}, '\\ n')
72+ const linkSpan = createElement('span', { style: sansText },
73+ createElement('a', { href: explanationUrl }, 'View explanation'))
74+
75+ const all = createElement('div', { style: { marginTop: '1em' } }, [codeSpan, brSpan, linkSpan])
76+ return all
77+ }"
78+
79+ /--
80+ If `msg` is tagged as a named error, appends the error description widget displaying the
81+ corresponding error name and explanation link. Otherwise, returns `msg` unaltered.
82+ -/
83+ private def MessageData.appendDescriptionWidgetIfNamed (msg : MessageData) : MessageData :=
84+ match errorNameOfKind? msg.kind with
85+ | some errorName =>
86+ let url := manualRoot ++ s! "find/?domain={ errorExplanationManualDomain} &name={ errorName} "
87+ let inst := {
88+ id := ``errorDescriptionWidget
89+ javascriptHash := errorDescriptionWidget.javascriptHash
90+ props := return json% {
91+ code: $(toString errorName),
92+ explanationUrl: $url
93+ }
94+ }
95+ -- Note: we do not generate corresponding message data for the widget because it pollutes
96+ -- console output
97+ msg.composePreservingKind <| .ofWidget inst .nil
98+ | none => msg
99+
56100/--
57101Log the message `msgData` at the position provided by `ref` with the given `severity`.
58102If `getRef` has position information but `ref` does not, we use `getRef`.
@@ -80,26 +124,63 @@ def logAt (ref : Syntax) (msgData : MessageData)
80124def logErrorAt (ref : Syntax) (msgData : MessageData) : m Unit :=
81125 logAt ref msgData MessageSeverity.error
82126
127+ /--
128+ Log a named error message using the given message data. The position is provided by `ref`.
129+
130+ Note: Use the macro `logNamedErrorAt`, which validates error names, instead of calling this function
131+ directly.
132+ -/
133+ protected def «logNamedErrorAt » (ref : Syntax) (name : Name) (msgData : MessageData) : m Unit :=
134+ logAt ref (msgData.tagWithErrorName name) MessageSeverity.error
135+
83136/-- Log a new warning message using the given message data. The position is provided by `ref`. -/
84137def logWarningAt [MonadOptions m] (ref : Syntax) (msgData : MessageData) : m Unit := do
85138 logAt ref msgData .warning
86139
140+ /--
141+ Log a named error warning using the given message data. The position is provided by `ref`.
142+
143+ Note: Use the macro `logNamedWarningAt`, which validates error names, instead of calling this function
144+ directly.
145+ -/
146+ protected def «logNamedWarningAt » (ref : Syntax) (name : Name) (msgData : MessageData) : m Unit :=
147+ logAt ref (msgData.tagWithErrorName name) MessageSeverity.warning
148+
87149/-- Log a new information message using the given message data. The position is provided by `ref`. -/
88150def logInfoAt (ref : Syntax) (msgData : MessageData) : m Unit :=
89151 logAt ref msgData MessageSeverity.information
90152
91153/-- Log a new error/warning/information message using the given message data and `severity`. The position is provided by `getRef`. -/
92- def log (msgData : MessageData) (severity : MessageSeverity := MessageSeverity.error): m Unit := do
154+ def log (msgData : MessageData) (severity : MessageSeverity := MessageSeverity.error)
155+ (isSilent : Bool := false ) : m Unit := do
93156 let ref ← MonadLog.getRef
94- logAt ref msgData severity
157+ logAt ref msgData severity isSilent
95158
96159/-- Log a new error message using the given message data. The position is provided by `getRef`. -/
97160def logError (msgData : MessageData) : m Unit :=
98161 log msgData MessageSeverity.error
99162
163+ /--
164+ Log a named error message using the given message data. The position is provided by `getRef`.
165+
166+ Note: Use the macro `logNamedError`, which validates error names, instead of calling this function
167+ directly.
168+ -/
169+ protected def «logNamedError » (name : Name) (msgData : MessageData) : m Unit :=
170+ log (msgData.tagWithErrorName name) MessageSeverity.error
171+
100172/-- Log a new warning message using the given message data. The position is provided by `getRef`. -/
101173def logWarning [MonadOptions m] (msgData : MessageData) : m Unit := do
102- log msgData (if warningAsError.get (← getOptions) then .error else .warning)
174+ log msgData .warning
175+
176+ /--
177+ Log a named warning using the given message data. The position is provided by `getRef`.
178+
179+ Note: Use the macro `logNamedWarning`, which validates error names, instead of calling this function
180+ directly.
181+ -/
182+ protected def «logNamedWarning » (name : Name) (msgData : MessageData) : m Unit :=
183+ log (msgData.tagWithErrorName name) MessageSeverity.warning
103184
104185/-- Log a new information message using the given message data. The position is provided by `getRef`. -/
105186def logInfo (msgData : MessageData) : m Unit :=
0 commit comments