@@ -45,6 +45,16 @@ Used for automatic registration and provider discovery.")
4545
4646; ;; Provider Conditions
4747
48+ ; ; Reader function declarations for exported condition accessors
49+ (defgeneric provider-error-provider (condition )
50+ (:documentation " Return the provider that encountered the error." ))
51+
52+ (defgeneric provider-error-message (condition )
53+ (:documentation " Return the error message, or NIL if not specified." ))
54+
55+ (defgeneric provider-unavailable-reason (condition )
56+ (:documentation " Return the reason why the provider is unavailable, or NIL." ))
57+
4858(define-condition provider-error (error )
4959 ((provider :initarg :provider
5060 :reader provider-error-provider
@@ -81,6 +91,22 @@ required runtime not connected, etc."))
8191
8292; ;; Provider Definition Macro
8393
94+ (eval-when (:compile-toplevel :load-toplevel :execute )
95+ (defun %parse-provider-options (options)
96+ " Parse provider definition options at macro-expansion time.
97+ Returns values: (provider-name priority languages class-options).
98+ Signals an error if :provider-name is not specified."
99+ (let ((provider-name (cadr (assoc :provider-name options)))
100+ (priority (or (cadr (assoc :priority options)) 5 ))
101+ (languages (cadr (assoc :languages options)))
102+ (class-options (remove-if (lambda (opt)
103+ (member (car opt)
104+ ' (:provider-name :priority :languages )))
105+ options)))
106+ (unless provider-name
107+ (error " define-call-graph-provider requires :provider-name option" ))
108+ (values provider-name priority languages class-options))))
109+
84110(defmacro define-call-graph-provider (name (&rest superclasses) slots &body options)
85111 " Define a new call graph provider class with common boilerplate.
86112
@@ -92,38 +118,30 @@ OPTIONS are class options plus special provider options:
92118 :provider-name - Keyword name for the provider (required)
93119 :priority - Provider priority (default 5)
94120 :languages - List of supported language keywords
95- :register - If T, auto-register with *provider-registry*
121+
122+ To register the provider, call register-provider explicitly after load:
123+ (register-provider *provider-registry*
124+ (make-instance 'my-python-provider)
125+ '(:python))
96126
97127Example:
98128 (define-call-graph-provider my-python-provider ()
99129 ((parser :accessor my-provider-parser))
100130 (:provider-name :my-python)
101131 (:priority 5)
102- (:languages (:python))
103- (:register t))"
104- (let* ((superclasses (or superclasses ' (call-graph-provider)))
105- (provider-name (cadr (assoc :provider-name options)))
106- (priority (or (cadr (assoc :priority options)) 5 ))
107- (languages (cadr (assoc :languages options)))
108- (register (cadr (assoc :register options)))
109- (class-options (remove-if (lambda (opt)
110- (member (car opt)
111- ' (:provider-name :priority :languages :register )))
112- options)))
113- (unless provider-name
114- (error " define-call-graph-provider requires :provider-name option" ))
115- ` (progn
116- (defclass , name , superclasses
117- , slots
118- ,@ class-options)
119- (defmethod provider-name ((provider , name))
120- , provider-name)
121- (defmethod provider-priority ((provider , name))
122- , priority)
123- ,@ (when languages
124- ` ((defmethod provider-languages ((provider , name))
125- ' ,languages)))
126- ,@ (when register
127- ` ((let ((provider (make-instance ' ,name)))
128- (register-provider *provider-registry* provider ' ,languages)))))))
132+ (:languages (:python)))"
133+ (multiple-value-bind (provider-name priority languages class-options)
134+ (%parse-provider-options options)
135+ (let ((superclasses (or superclasses ' (call-graph-provider))))
136+ ` (progn
137+ (defclass , name , superclasses
138+ , slots
139+ ,@ class-options)
140+ (defmethod provider-name ((provider , name))
141+ , provider-name)
142+ (defmethod provider-priority ((provider , name))
143+ , priority)
144+ ,@ (when languages
145+ ` ((defmethod provider-languages ((provider , name))
146+ ' ,languages)))))))
129147
0 commit comments