@@ -29,6 +29,7 @@ def initialize(location, message)
2929 NonConstantSuperClassName = _ = Class . new ( Base )
3030 TopLevelMethodDefinition = _ = Class . new ( Base )
3131 TopLevelAttributeDefinition = _ = Class . new ( Base )
32+ NonConstantConstantDeclaration = _ = Class . new ( Base )
3233 UnusedInlineAnnotation = _ = Class . new ( Base )
3334 AnnotationSyntaxError = _ = Class . new ( Base )
3435 MixinMultipleArguments = _ = Class . new ( Base )
@@ -237,6 +238,19 @@ def visit_call_node(node)
237238 end
238239 end
239240
241+ def visit_constant_write_node ( node )
242+ return if skip_node? ( node )
243+
244+ # Parse constant declaration (both top-level and in classes/modules)
245+ parse_constant_declaration ( node )
246+ end
247+
248+ def visit_constant_path_write_node ( node )
249+ return if skip_node? ( node )
250+
251+ parse_constant_declaration ( node )
252+ end
253+
240254 def parse_mixin_call ( node )
241255 # Check for multiple arguments
242256 if node . arguments && node . arguments . arguments . length > 1
@@ -353,6 +367,60 @@ def parse_attribute_call(node)
353367 current_module! . members << member
354368 end
355369
370+ def parse_constant_declaration ( node )
371+ # Create TypeName for the constant
372+ unless constant_name = constant_as_type_name ( node )
373+ location =
374+ case node
375+ when Prism ::ConstantWriteNode
376+ node . name_loc
377+ when Prism ::ConstantPathWriteNode
378+ node . target . location
379+ end
380+
381+ diagnostics << Diagnostic ::NonConstantConstantDeclaration . new (
382+ rbs_location ( location ) ,
383+ "Constant name must be a constant"
384+ )
385+ return
386+ end
387+
388+ # Look for leading comment block
389+ leading_block = comments . leading_block! ( node )
390+ report_unused_block ( leading_block ) if leading_block
391+
392+ # Look for trailing type annotation (#: Type)
393+ trailing_block = comments . trailing_block! ( node . location )
394+ type_annotation = nil
395+
396+ if trailing_block
397+ case annotation = trailing_block . trailing_annotation ( [ ] )
398+ when AST ::Ruby ::Annotations ::NodeTypeAssertion
399+ type_annotation = annotation
400+ when AST ::Ruby ::CommentBlock ::AnnotationSyntaxError
401+ diagnostics << Diagnostic ::AnnotationSyntaxError . new (
402+ annotation . location , "Syntax error: " + annotation . error . error_message
403+ )
404+ end
405+ end
406+
407+ # Create the constant declaration
408+ constant_decl = AST ::Ruby ::Declarations ::ConstantDecl . new (
409+ buffer ,
410+ constant_name ,
411+ node ,
412+ leading_block ,
413+ type_annotation
414+ )
415+
416+ # Insert the constant declaration appropriately
417+ if current_module
418+ current_module . members << constant_decl
419+ else
420+ result . declarations << constant_decl
421+ end
422+ end
423+
356424 def insert_declaration ( decl )
357425 if current_module
358426 current_module . members << decl
0 commit comments