class Crystal::CleanupTransformer

Overview

This visitor runs at the end and does some simplifications to the resulting AST node.

For example, it rewrites and if true; 1; else; 2; end to a single 1. It does so for other "always true conditions", such as x.is_a?(Foo) where x can only be of type Foo. These simplifications are needed because the codegen would have no idea on how to generate code for unreachable branches, because they have no type, and for now the codegen only deals with typed nodes.

Defined in:

compiler/crystal/semantic/cleanup_transformer.cr

Constructors

Instance Method Summary

Instance methods inherited from class Crystal::Transformer

after_transform(node) after_transform, before_transform(node) before_transform, transform(node : Expressions)
transform(node : Call)
transform(node : NamedArgument)
transform(node : And)
transform(node : Or)
transform(node : StringInterpolation)
transform(node : ArrayLiteral)
transform(node : HashLiteral)
transform(node : NamedTupleLiteral)
transform(node : If)
transform(node : Unless)
transform(node : MultiAssign)
transform(node : Def)
transform(node : Macro)
transform(node : PointerOf)
transform(node : SizeOf)
transform(node : InstanceSizeOf)
transform(node : AlignOf)
transform(node : InstanceAlignOf)
transform(node : OffsetOf)
transform(node : ReadInstanceVar)
transform(node : IsA)
transform(node : RespondsTo)
transform(node : Case)
transform(node : When)
transform(node : Select)
transform(node : ImplicitObj)
transform(node : ClassDef)
transform(node : ModuleDef)
transform(node : AnnotationDef)
transform(node : While)
transform(node : Until)
transform(node : Generic)
transform(node : ExceptionHandler)
transform(node : Rescue)
transform(node : Union)
transform(node : Metaclass)
transform(node : Arg)
transform(node : ProcNotation)
transform(node : Block)
transform(node : ProcLiteral)
transform(node : ProcPointer)
transform(node : Return)
transform(node : Break)
transform(node : Next)
transform(node : Yield)
transform(node : Include)
transform(node : Extend)
transform(node : RangeLiteral)
transform(node : Assign)
transform(node : OpAssign)
transform(node : Out)
transform(node : Nop)
transform(node : NilLiteral)
transform(node : BoolLiteral)
transform(node : NumberLiteral)
transform(node : CharLiteral)
transform(node : StringLiteral)
transform(node : SymbolLiteral)
transform(node : RegexLiteral)
transform(node : Var)
transform(node : InstanceVar)
transform(node : ClassVar)
transform(node : Global)
transform(node : Require)
transform(node : Path)
transform(node : Self)
transform(node : LibDef)
transform(node : FunDef)
transform(node : TypeDef)
transform(node : CStructOrUnionDef)
transform(node : EnumDef)
transform(node : ExternalVar)
transform(node : TypeOf)
transform(node : MagicConstant)
transform(node : Not)
transform(node : TupleLiteral)
transform(node : Cast)
transform(node : NilableCast)
transform(node : TypeDeclaration)
transform(node : UninitializedVar)
transform(node : Alias)
transform(node : Splat)
transform(node : DoubleSplat)
transform(node : VisibilityModifier)
transform(node : Annotation)
transform(node : MacroExpression)
transform(node : MacroLiteral)
transform(node : MacroVerbatim)
transform(node : MacroIf)
transform(node : MacroFor)
transform(node : MacroVar)
transform(node : Underscore)
transform(node : Asm)
transform(node : AsmOperand)
transform(node : MetaVar | MetaMacroVar | Primitive | TypeFilteredNode | TupleIndexer | TypeNode | AssignWithRestriction | YieldBlockBinder | MacroId | Unreachable)
transform(node : FileNode)
transform
, transform_many(exps) transform_many

Instance methods inherited from class Reference

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other)
==
, dup dup, hash(hasher) hash, initialize initialize, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference) : Bool
same?(other : Nil)
same?
, to_s(io : IO) : Nil to_s

Constructor methods inherited from class Reference

new new, unsafe_construct(address : Pointer, *args, **opts) : self unsafe_construct

Class methods inherited from class Reference

pre_initialize(address : Pointer) pre_initialize

Instance methods inherited from class Object

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other)
===
, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash
hash
, in?(collection : Object) : Bool
in?(*values : Object) : Bool
in?
, inspect(io : IO) : Nil
inspect : String
inspect
, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil!
not_nil!
, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String
to_json
, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil
to_pretty_json
, to_s(io : IO) : Nil
to_s : String
to_s
, to_yaml(io : IO) : Nil
to_yaml : String
to_yaml
, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

Class methods inherited from class Object

from_json(string_or_io : String | IO, root : String)
from_json(string_or_io : String | IO)
from_json
, from_yaml(string_or_io : String | IO) from_yaml

Macros inherited from class Object

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

Constructor Detail

def self.new(program : Program) #

[View source]

Instance Method Detail

def after_transform(node) #

[View source]
def build_raise(msg : String, node : ASTNode) #

[View source]
def check_arg_is_not_closure(node, message, arg) #

[View source]
def check_args_are_not_closure(node, message) #

[View source]
def compute_last_truthiness(&) #

[View source]
def false_literal #

[View source]
def find_unreachable_parent(expanded) #

[View source]
def flatten_collect(exp, exps) #

[View source]
def has_enum_type?(type) #

[View source]
def inside_def! #

[View source]
def replace_unreachable_if_needed(node, expanded) #

If any of the types checked in case is an enum, it can happen that the unreachable can be reached by doing SomeEnum.new(some_value). In that case we replace the Unreachable node with raise "...". In the future we should disallow creating such values.


[View source]
def reset_last_status #

[View source]
def simple_constant?(node, consts) #

[View source]
def simple_constant?(node) #

[View source]
def target_def_is_captured_block?(arg : Call) #

Checks whether arg's target def has the following definition:

def f(&block)
  block
end

That is, the def returns its captured block and does nothing else. An example is Proc.new(&block).


[View source]
def transform(node : AnnotationDef) #

[View source]
def transform(node : Def) #

[View source]
def transform(node : ClassDef) #

[View source]
def transform(node : Include) #

[View source]
def transform(node : Extend) #

[View source]
def transform(node : Expressions) #

[View source]
def transform(node : Case) #

[View source]
def transform(node : StringInterpolation) #

[View source]
def transform(node : MultiAssign) #

[View source]
def transform(node : Global) #

[View source]
def transform(node : InstanceSizeOf) #

[View source]
def transform(node : InstanceAlignOf) #

[View source]
def transform(node : ExpandableNode) #

[View source]
def transform(node : Assign) #

[View source]
def transform(node : Path) #

[View source]
def transform(node : Generic) #

[View source]
def transform(node : Call) #

[View source]
def transform(node : ProcPointer) #

[View source]
def transform(node : ProcLiteral) #

[View source]
def transform(node : Yield) #

[View source]
def transform(node : While) #

[View source]
def transform(node : If) #

[View source]
def transform(node : IsA) #

[View source]
def transform(node : RespondsTo) #

[View source]
def transform(node : Cast) #

[View source]
def transform(node : NilableCast) #

[View source]
def transform(node : FunDef) #

[View source]
def transform(node : ExceptionHandler) #

[View source]
def transform(node : TupleLiteral) #

[View source]
def transform(node : NamedTupleLiteral) #

[View source]
def transform(node : CStructOrUnionDef) #

[View source]
def transform(node : Primitive) #

[View source]
def transform(node : TypeOf) #

[View source]
def transform(node : AssignWithRestriction) #

[View source]
def transform_is_a_or_responds_to(node, &) #

[View source]
def true_literal #

[View source]
def untyped_expression(node, msg = nil) #

[View source]
def var?(node) #

[View source]