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.crConstructors
Instance Method Summary
- #after_transform(node)
- #build_raise(msg : String, node : ASTNode)
- #check_arg_is_not_closure(node, message, arg)
- #check_args_are_not_closure(node, message)
- #compute_last_truthiness(&)
- #false_literal
- #find_unreachable_parent(expanded)
- #flatten_collect(exp, exps)
- #has_enum_type?(type)
- #inside_def!
-
#replace_unreachable_if_needed(node, expanded)
If any of the types checked in
caseis an enum, it can happen that the unreachable can be reached by doingSomeEnum.new(some_value). - #reset_last_status
- #simple_constant?(node, consts)
- #simple_constant?(node)
-
#target_def_is_captured_block?(arg : Call)
Checks whether arg's target def has the following definition:
- #transform(node : AnnotationDef)
- #transform(node : Def)
- #transform(node : ClassDef)
- #transform(node : Include)
- #transform(node : Extend)
- #transform(node : Expressions)
- #transform(node : Case)
- #transform(node : StringInterpolation)
- #transform(node : MultiAssign)
- #transform(node : Global)
- #transform(node : InstanceSizeOf)
- #transform(node : InstanceAlignOf)
- #transform(node : ExpandableNode)
- #transform(node : Assign)
- #transform(node : Path)
- #transform(node : Generic)
- #transform(node : Call)
- #transform(node : ProcPointer)
- #transform(node : ProcLiteral)
- #transform(node : Yield)
- #transform(node : While)
- #transform(node : If)
- #transform(node : IsA)
- #transform(node : RespondsTo)
- #transform(node : Cast)
- #transform(node : NilableCast)
- #transform(node : FunDef)
- #transform(node : ExceptionHandler)
- #transform(node : TupleLiteral)
- #transform(node : NamedTupleLiteral)
- #transform(node : CStructOrUnionDef)
- #transform(node : Primitive)
- #transform(node : TypeOf)
- #transform(node : AssignWithRestriction)
- #transform_is_a_or_responds_to(node, &)
- #true_literal
- #untyped_expression(node, msg = nil)
- #var?(node)
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
Instance Method Detail
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.
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).