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

Add 2.7 support #148

Merged
merged 1 commit into from Oct 7, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 3 additions & 23 deletions .github/workflows/ci.yml
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: ['2.6']
ruby: ['2.6', '2.7']
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
Expand All @@ -35,7 +35,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: ['2.6']
ruby: ['2.6', '2.7']
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
Expand All @@ -46,34 +46,14 @@ jobs:
gem install bundler
bundle install
- run: bundle exec rspec spec/integration
ruby-mutant:
name: Mutation coverage
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
fail-fast: false
matrix:
ruby: ['2.6']
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- run: |
gem install bundler
bundle install
- run: ./mutant.sh --since HEAD~1 -- 'Unparser*'
ruby-rubocop:
name: Rubocop
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
fail-fast: false
matrix:
ruby: ['2.6']
ruby: ['2.6', '2.7']
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
Expand Down
13 changes: 8 additions & 5 deletions .rubocop.yml
Expand Up @@ -5,6 +5,9 @@ AllCops:
- '**/*.rake'
- 'Gemfile'
- 'Gemfile.triage'
Exclude:
- lib/unparser/precedence/data.rb
- tmp

# Avoid parameter lists longer than five parameters.
Metrics/ParameterLists:
Expand All @@ -30,12 +33,16 @@ Style/CollectionMethods:
find: 'detect'
find_all: 'select'

# Use `fail` as `raise` implies re-raising
Style/SignalException:
EnforcedStyle: semantic

# Limit line length
Layout/LineLength:
Max: 113 # TODO: lower to 79 once the rubocop branch in shared/Gemfile is removed

Metrics/ClassLength:
Max: 175
Max: 205

# Prefer modifiers and explicit if statements over returning early for small methods
Style/GuardClause:
Expand All @@ -50,10 +57,6 @@ Metrics/BlockLength:
Style/RedundantFreeze:
Enabled: false

# Allow Fixnum and Bignum. This Gem supports versions before 2.4
Lint/UnifiedInteger:
Enabled: false

# Disabled because of indenting with private keyword in class bodies.
Layout/IndentationWidth:
Enabled: false
Expand Down
6 changes: 6 additions & 0 deletions Changelog.md
@@ -1,3 +1,9 @@
# v0.5.0 unreleased

* Add 2.7 syntax support
* Fix lots of edge cases via leveraging parser specs
* Add `--literal` mode for CLI

# v0.4.9 2020-09-10

* Change packaging to avoid git in gemspec.
Expand Down
2 changes: 1 addition & 1 deletion bin/unparser
Expand Up @@ -5,6 +5,6 @@ trap('INT') do |status|
exit! 128 + status
end

require 'unparser/cli'
require 'unparser'

exit Unparser::CLI.run(ARGV)
157 changes: 96 additions & 61 deletions lib/unparser.rb
Expand Up @@ -6,6 +6,7 @@
require 'diff/lcs'
require 'diff/lcs/hunk'
require 'mprelude'
require 'optparse'
require 'parser/current'
require 'procto'
require 'set'
Expand All @@ -15,6 +16,10 @@ module Unparser
# Unparser specific AST builder defaulting to modern AST format
class Builder < Parser::Builders::Default
modernize

def initialize
self.emit_file_line_as_literals = false
end
end

EMPTY_STRING = ''.freeze
Expand All @@ -32,12 +37,27 @@ class Builder < Parser::Builders::Default
# @api private
#
def self.unparse(node, comment_array = [])
node = Preprocessor.run(node)
buffer = Buffer.new
comments = Comments.new(comment_array)
root = Emitter::Root.new(Parser::AST::Node.new(:root, [node]), buffer, comments)
Emitter.emitter(node, root).write_to_buffer
buffer.content
return '' if node.nil?

Buffer.new.tap do |buffer|
Emitter::Root.new(
buffer,
node,
Comments.new(comment_array)
).write_to_buffer
end.content
end

# Unparse capturing errors
#
# This is mostly useful for writing testing tools against unparser.
#
# @param [Parser::AST::Node, nil] node
#
# @return [Either<Exception, String>]
def self.unparse_either(node)
MPrelude::Either
.wrap_error(Exception) { unparse(node) }
end

# Parse string into AST
Expand Down Expand Up @@ -74,8 +94,6 @@ def self.parse_with_comments(source)
# @return [Parser::Base]
#
# @api private
#
# ignore :reek:NestedIterators
def self.parser
Parser::CurrentRuby.new(Builder.new).tap do |parser|
parser.diagnostics.tap do |diagnostics|
Expand All @@ -100,75 +118,92 @@ def self.consume_diagnostic(diagnostic)
# @param [String] source
#
# @return [Parser::Source::Buffer]
def self.buffer(source)
Parser::Source::Buffer.new('(string)').tap do |buffer|
buffer.source = source
end
def self.buffer(source, identification = '(string)')
Parser::Source::Buffer.new(identification, source: source)
end
end # Unparser

require 'unparser/buffer'
require 'unparser/node_helpers'
require 'unparser/preprocessor'
require 'unparser/comments'
require 'unparser/constants'
require 'unparser/dsl'
require 'unparser/ast'
require 'unparser/ast/local_variable_scope'
require 'unparser/diff'
require 'unparser/buffer'
require 'unparser/generation'
require 'unparser/color'
require 'unparser/comments'
require 'unparser/constants'
require 'unparser/diff'
require 'unparser/dsl'
require 'unparser/emitter'
require 'unparser/emitter/literal'
require 'unparser/emitter/literal/primitive'
require 'unparser/emitter/literal/singleton'
require 'unparser/emitter/literal/dynamic'
require 'unparser/emitter/literal/regexp'
require 'unparser/emitter/literal/array'
require 'unparser/emitter/literal/hash'
require 'unparser/emitter/literal/range'
require 'unparser/emitter/literal/dynamic_body'
require 'unparser/emitter/literal/execute_string'
require 'unparser/emitter/meta'
require 'unparser/emitter/send'
require 'unparser/emitter/send/unary'
require 'unparser/emitter/send/binary'
require 'unparser/emitter/send/regular'
require 'unparser/emitter/send/conditional'
require 'unparser/emitter/send/attribute_assignment'
require 'unparser/emitter/block'
require 'unparser/emitter/assignment'
require 'unparser/emitter/variable'
require 'unparser/emitter/splat'
require 'unparser/emitter/cbase'
require 'unparser/emitter/alias'
require 'unparser/emitter/args'
require 'unparser/emitter/argument'
require 'unparser/emitter/array'
require 'unparser/emitter/array_pattern'
require 'unparser/emitter/assignment'
require 'unparser/emitter/begin'
require 'unparser/emitter/flow_modifier'
require 'unparser/emitter/undef'
require 'unparser/emitter/def'
require 'unparser/emitter/binary'
require 'unparser/emitter/block'
require 'unparser/emitter/case'
require 'unparser/emitter/case_guard'
require 'unparser/emitter/case_match'
require 'unparser/emitter/cbase'
require 'unparser/emitter/class'
require 'unparser/emitter/module'
require 'unparser/emitter/op_assign'
require 'unparser/emitter/const_pattern'
require 'unparser/emitter/def'
require 'unparser/emitter/defined'
require 'unparser/emitter/dstr'
require 'unparser/emitter/dsym'
require 'unparser/emitter/flipflop'
require 'unparser/emitter/float'
require 'unparser/emitter/flow_modifier'
require 'unparser/emitter/for'
require 'unparser/emitter/hash'
require 'unparser/emitter/hash_pattern'
require 'unparser/emitter/hookexe'
require 'unparser/emitter/super'
require 'unparser/emitter/retry'
require 'unparser/emitter/redo'
require 'unparser/emitter/if'
require 'unparser/emitter/alias'
require 'unparser/emitter/yield'
require 'unparser/emitter/binary'
require 'unparser/emitter/case'
require 'unparser/emitter/for'
require 'unparser/emitter/repetition'
require 'unparser/emitter/root'
require 'unparser/emitter/match'
require 'unparser/emitter/empty'
require 'unparser/emitter/flipflop'
require 'unparser/emitter/rescue'
require 'unparser/emitter/resbody'
require 'unparser/emitter/ensure'
require 'unparser/emitter/in_match'
require 'unparser/emitter/in_pattern'
require 'unparser/emitter/index'
require 'unparser/emitter/kwbegin'
require 'unparser/emitter/lambda'
require 'unparser/emitter/masgn'
require 'unparser/emitter/match'
require 'unparser/emitter/match_alt'
require 'unparser/emitter/match_as'
require 'unparser/emitter/match_rest'
require 'unparser/emitter/match_var'
require 'unparser/emitter/mlhs'
require 'unparser/emitter/module'
require 'unparser/emitter/op_assign'
require 'unparser/emitter/pin'
require 'unparser/emitter/primitive'
require 'unparser/emitter/range'
require 'unparser/emitter/regexp'
require 'unparser/emitter/repetition'
require 'unparser/emitter/rescue'
require 'unparser/emitter/root'
require 'unparser/emitter/send'
require 'unparser/emitter/simple'
require 'unparser/emitter/splat'
require 'unparser/emitter/super'
require 'unparser/emitter/undef'
require 'unparser/emitter/variable'
require 'unparser/emitter/xstr'
require 'unparser/emitter/yield'
require 'unparser/writer'
require 'unparser/writer/binary'
require 'unparser/writer/dynamic_string'
require 'unparser/writer/resbody'
require 'unparser/writer/rescue'
require 'unparser/writer/send'
require 'unparser/writer/send/attribute_assignment'
require 'unparser/writer/send/binary'
require 'unparser/writer/send/regular'
require 'unparser/writer/send/unary'
require 'unparser/node_details'
require 'unparser/node_details/send'
require 'unparser/cli'

require 'unparser/validation'
# make it easy for zombie
require 'unparser/finalize'
1 change: 0 additions & 1 deletion lib/unparser/ast.rb
Expand Up @@ -2,7 +2,6 @@

module Unparser
# Namespace for AST processing tools
# :reek:TooManyConstants
module AST

FIRST_CHILD = ->(node) { node.children.first }.freeze
Expand Down