Skip to content

サンプルコード内の class Foo; endclass ;Foo end と表示される #178

Open
@ysjj

Description

@ysjj

概要

Rubyリファレンスマニュアルのサンプルコードで、class Foo; endclass ;Foo end と表示されています。

具体例: Module#private_constant
image

ソースを確認したところ、 class Foo; end (相当)で書かれていました。
image

再現確認

irb 上の次のコードで再現することが確認できました。

irb> require 'bitclust'
irb> BitClust::SyntaxHighlighter.new('class A; end').highlight
=> "<span class=\"k\">class</span> ;<span class=\"nn\"></span><span class=\"o\"></span><span class=\"nc\">A</span> <span class=\"k\">end</span>"

原因分析

この状態は on_const;on_default で処理されることが関係しているようです。

def on_const(token, data)
case
when @stack.last == :class
@name_buffer << token
when @stack.last == :module
@name_buffer << token
when @stack.last == :symbol
data << "#{token}</span>"
@stack.pop
else
on_default(:on_const, token, data)
end
data
end

クラス名(and/or モジュール名; 以下、同様)をトリガーとする on_const ではトークンが data ではなく @name_buffer に保存されます。
ですが、次の ; をトリガーとする on_default ではトークンが data に保存されます。
この時点で data にはクラス名の前に ; が保存された状態となっています。

対処案

基本的に ; は改行と同様に扱えば良いと考えています。
つまり on_nl と同等の on_semicolon を設ければ良さそうです。

def on_nl(token, data)
case
when @name_buffer.empty?
return on_default(:on_nl, token, data)
when @stack.last == :module
name = @name_buffer.join
data << "<span class=\"nn\">#{name}</span>"
@stack.pop
@name_buffer.clear
when @stack.last == :class
namespace = @name_buffer.values_at(0..-3).join
operator = @name_buffer[-2]
name = @name_buffer.last
data << "<span class=\"nn\">#{namespace}</span>"
data << "<span class=\"o\">#{operator}</span>"
data << "<span class=\"nc\">#{name}</span>"
@stack.pop
@name_buffer.clear
end
on_default(:on_nl, token, data)
end

対処コード

フォーク リポジトリにて上述の対処案で修正されることを確認しています:

b853df0...ysjj:rurema-bitclust:da05f15

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions