Created
November 9, 2022 20:17
-
-
Save kddnewton/d4b349eb2f8dfe1ce6bfed2178b0a9c6 to your computer and use it in GitHub Desktop.
Linting with Syntax Tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module SyntaxTree | |
# This class is used to create a mutation that transforms syntax trees based | |
# on various linting rules. | |
class Linter | |
def mutation | |
SyntaxTree.mutation do |mutator| | |
# Lint/AssignmentInCondition | |
mutator.mutate("IfNode[predicate: Assign | OpAssign] | UnlessNode[predicate: Assign | OpAssign] | WhileNode[predicate: Assign | OpAssign] | UntilNode[predicate: Assign | OpAssign]") do |node| | |
node.copy(predicate: Paren.new( | |
lparen: LParen.default, | |
contents: node.predicate, | |
location: node.predicate.location | |
)) | |
end | |
# Lint/BigDecimalNew | |
mutator.mutate("CallNode[receiver: { value: { value: 'BigDecimal' } }, message: { value: 'new' }]") do |node| | |
node.copy(receiver: nil, operator: nil, message: node.receiver) | |
end | |
# Lint/BinaryOperatorWithIdenticalOperands | |
mutator.mutate("Binary[operator: :'&&']") do |node| | |
node.left === node.right ? node.left : node | |
end | |
# Lint/BooleanSymbol | |
mutator.mutate("SymbolLiteral[value: Kw[value: 'true' | 'false']]") do |node| | |
node.value | |
end | |
# Lint/Debugger | |
mutator.mutate("VCall[value: { value: 'debugger' }] | CallNode[receiver: { value: { value: 'binding' } }, message: { value: 'pry' | 'irb' }]") do |node| | |
VoidStmt.new(location: node.location) | |
end | |
# Lint/LiteralInInterpolation | |
mutator.mutate("StringEmbExpr[statements: { body: [FloatLiteral | Imaginary | Int | RationalLiteral | VarRef[value: { value: 'false' | 'true' | 'nil' }]] }]") do |node| | |
case (literal = node.statements.body.first) | |
when FloatLiteral, Imaginary, Int, RationalLiteral | |
TStringContent.new(value: literal.value, location: node.location) | |
when VarRef | |
TStringContent.new(value: literal.value.value, location: node.location) | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment