Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type check RDoc related Ruby code #1466

Merged
merged 4 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions lib/rbs/annotate/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,20 @@ def format(newline_at_end:)

def self.each_part(doc, &block)
if block
if doc.file
yield doc
document =
case doc
when String
raise
when RDoc::Comment
document = doc.parse
when RDoc::Markup::Document
document = doc
end

if document.file
yield document
else
doc.each do |d|
document.each do |d|
each_part(d, &block)
end
end
Expand Down
11 changes: 10 additions & 1 deletion lib/rbs/annotate/rdoc_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,16 @@ def find_class(typename)
def docs
if ds = yield
unless ds.empty?
ds.map(&:comment)
ds.map do |code_object|
case comment = code_object.comment
when String
raise
when RDoc::Comment
comment.parse
when RDoc::Markup::Document
comment
end
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions sig/annotate/formatter.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ module RBS

def self.translate: (RDoc::Markup::Document) -> String?

def self.each_part: (RDoc::Markup::Document) { (RDoc::Markup::Document) -> void } -> void
| (RDoc::Markup::Document) -> Enumerator[RDoc::Markup::Document, void]
def self.each_part: (RDoc::Markup::Document | RDoc::Comment | String) { (RDoc::Markup::Document) -> void } -> void
| (RDoc::Markup::Document | RDoc::Comment | String) -> Enumerator[RDoc::Markup::Document, void]
end
end
end
2 changes: 1 addition & 1 deletion sig/annotate/rdoc_annotater.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module RBS
end

interface _WithRDocComment
def comment: () -> RDoc::Markup::Document
def comment: () -> (RDoc::Markup::Document | RDoc::Comment | String)
end

def each_part: (Array[Object & _WithRDocComment], tester: _PathTester) { ([RDoc::Markup::Document, Object & _WithRDocComment]) -> void } -> void
Expand Down
4 changes: 4 additions & 0 deletions sig/rdoc/rbs.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ end
module RBS
module RDocPlugin
class Parser
@top_level: RDoc::TopLevel

@content: String

type allowed_decls = RBS::AST::Declarations::Class
| RBS::AST::Declarations::Module
| RBS::AST::Declarations::Constant
Expand Down
47 changes: 0 additions & 47 deletions sig/shims.rbs

This file was deleted.

55 changes: 55 additions & 0 deletions stdlib/rdoc/0/code_object.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
%a{annotate:rdoc:skip}
module RDoc
# <!-- rdoc-file=lib/rdoc/code_object.rb -->
# Base class for the RDoc code tree.
#
# We contain the common stuff for contexts (which are containers) and other
# elements (methods, attributes and so on)
#
# Here's the tree of the CodeObject subclasses:
#
# * RDoc::Context
# * RDoc::TopLevel
# * RDoc::ClassModule
# * RDoc::AnonClass (never used so far)
# * RDoc::NormalClass
# * RDoc::NormalModule
# * RDoc::SingleClass
#
#
# * RDoc::MethodAttr
# * RDoc::Attr
# * RDoc::AnyMethod
# * RDoc::GhostMethod
# * RDoc::MetaMethod
#
#
# * RDoc::Alias
# * RDoc::Constant
# * RDoc::Mixin
# * RDoc::Require
# * RDoc::Include
#
class CodeObject
# <!-- rdoc-file=lib/rdoc/code_object.rb -->
# Our comment
#
attr_reader comment: Markup::Document | Comment | String

# <!--
# rdoc-file=lib/rdoc/code_object.rb
# - new()
# -->
# Creates a new CodeObject that will document itself and its children
#
def initialize: () -> void

# <!--
# rdoc-file=lib/rdoc/code_object.rb
# - comment=(comment)
# -->
# Replaces our comment with `comment`, unless it is empty.
#
def comment=: (Markup::Document | Comment | String | nil) -> (Markup::Document | Comment | String)
end
end
60 changes: 60 additions & 0 deletions stdlib/rdoc/0/comment.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
%a{annotate:rdoc:skip}
module RDoc
# <!-- rdoc-file=lib/rdoc/comment.rb -->
# A comment holds the text comment for a RDoc::CodeObject and provides a unified
# way of cleaning it up and parsing it into an RDoc::Markup::Document.
#
# Each comment may have a different markup format set by #format=. By default
# 'rdoc' is used. The :markup: directive tells RDoc which format to use.
#
# See RDoc::Markup@Other+directives for instructions on adding an alternate
# format.
#
class Comment
# <!-- rdoc-file=lib/rdoc/comment.rb -->
# The format of this comment. Defaults to RDoc::Markup
#
attr_reader format: String

# <!-- rdoc-file=lib/rdoc/comment.rb -->
# The RDoc::TopLevel this comment was found in
#
attr_accessor location: String

# <!--
# rdoc-file=lib/rdoc/comment.rb
# - new(text = nil, location = nil, language = nil)
# -->
# Creates a new comment with `text` that is found in the RDoc::TopLevel
# `location`.
#
def initialize: (?String? text, ?RDoc::Context? location, ?String? language) -> void

# <!--
# rdoc-file=lib/rdoc/comment.rb
# - format=(format)
# -->
# Sets the format of this comment and resets any parsed document
#
def format=: (String format) -> void

def normalized?: () -> bool

# <!--
# rdoc-file=lib/rdoc/comment.rb
# - normalize()
# -->
# Normalizes the text. See RDoc::Text#normalize_comment for details
#
def normalize: () -> self

# <!--
# rdoc-file=lib/rdoc/comment.rb
# - parse()
# -->
# Parses the comment into an RDoc::Markup::Document. The parsed document is
# cached until the text is changed.
#
def parse: () -> Markup::Document
end
end
153 changes: 153 additions & 0 deletions stdlib/rdoc/0/context.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
%a{annotate:rdoc:skip}
module RDoc
# <!-- rdoc-file=lib/rdoc/context.rb -->
# A Context is something that can hold modules, classes, methods, attributes,
# aliases, requires, and includes. Classes, modules, and files are all Contexts.
#
class Context < CodeObject
include Comparable

# <!-- rdoc-file=lib/rdoc/context.rb -->
# Types of methods
#
TYPES: ::Array["class" | "instance"]

TOMDOC_TITLES: ::Array[nil | "Public" | "Internal" | "Deprecated"]

type class_types = singleton(RDoc::NormalClass) | singleton(RDoc::SingleClass)

# <!--
# rdoc-file=lib/rdoc/context.rb
# - new()
# -->
# Creates an unnamed empty context with public current visibility
#
def initialize: () -> void

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_alias(an_alias)
# -->
# Adds `an_alias` that is automatically resolved
#
def add_alias: (RDoc::Alias an_alias) -> RDoc::Alias

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_attribute(attribute)
# -->
# Adds `attribute` if not already there. If it is (as method(s) or attribute),
# updates the comment if it was empty.
#
# The attribute is registered only if it defines a new method. For instance,
# `attr_reader :foo` will not be registered if method `foo` exists, but
# `attr_accessor :foo` will be registered if method `foo` exists, but `foo=`
# does not.
#
def add_attribute: (RDoc::Attr attribute) -> RDoc::Attr

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_class(class_type, given_name, superclass = '::Object')
# -->
# Adds a class named `given_name` with `superclass`.
#
# Both `given_name` and `superclass` may contain '::', and are interpreted
# relative to the `self` context. This allows handling correctly examples like
# these:
# class RDoc::Gauntlet < Gauntlet
# module Mod
# class Object # implies < ::Object
# class SubObject < Object # this is _not_ ::Object
#
# Given `class Container::Item` RDoc assumes `Container` is a module unless it
# later sees `class Container`. `add_class` automatically upgrades `given_name`
# to a class in this case.
#
def add_class: (class_types class_type, ::String given_name, ?::String superclass) -> (RDoc::NormalClass | RDoc::SingleClass)

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_constant(constant)
# -->
# Adds `constant` if not already there. If it is, updates the comment, value
# and/or is_alias_for of the known constant if they were empty/nil.
#
def add_constant: (RDoc::Constant constant) -> RDoc::Constant

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_include(include)
# -->
# Adds included module `include` which should be an RDoc::Include
#
def add_include: (RDoc::Include `include`) -> RDoc::Include

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_extend(ext)
# -->
# Adds extension module `ext` which should be an RDoc::Extend
#
def add_extend: (RDoc::Extend ext) -> RDoc::Extend

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_method(method)
# -->
# Adds `method` if not already there. If it is (as method or attribute), updates
# the comment if it was empty.
#
def add_method: (RDoc::AnyMethod method) -> RDoc::AnyMethod

# <!--
# rdoc-file=lib/rdoc/context.rb
# - add_module(class_type, name)
# -->
# Adds a module named `name`. If RDoc already knows `name` is a class then that
# class is returned instead. See also #add_class.
#
def add_module: (singleton(RDoc::NormalModule) class_type, String name) -> RDoc::NormalModule

# <!-- rdoc-file=lib/rdoc/context.rb -->
# All attr* methods
#
def attributes: () -> Array[Attr]

# <!-- rdoc-file=lib/rdoc/context.rb -->
# Constants defined
#
def constants: () -> Array[Constant]

# <!--
# rdoc-file=lib/rdoc/context.rb
# - find_module_named(name)
# -->
# Find a module with `name` using ruby's scoping rules
#
def find_module_named: (untyped name) -> (untyped | self)

# <!--
# rdoc-file=lib/rdoc/context.rb
# - full_name()
# -->
# The full name for this context. This method is overridden by subclasses.
#
def full_name: () -> "(unknown)"

# <!-- rdoc-file=lib/rdoc/context.rb -->
# Methods defined in this context
#
def method_list: () -> Array[AnyMethod]

def to_s: () -> ::String

# <!--
# rdoc-file=lib/rdoc/context.rb
# - top_level()
# -->
# Return the TopLevel that owns us
#
def top_level: () -> RDoc::TopLevel
end
end
Loading