morpher 0.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of morpher might be problematic. Click here for more details.

Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.circle.yml +6 -0
  3. data/.gitignore +5 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +8 -0
  6. data/Changelog.md +60 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +20 -0
  9. data/README.md +56 -0
  10. data/Rakefile +95 -0
  11. data/circle.yml +7 -0
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/heckle.yml +3 -0
  16. data/config/mutant.yml +8 -0
  17. data/config/reek.yml +109 -0
  18. data/config/rubocop.yml +138 -0
  19. data/config/yardstick.yml +2 -0
  20. data/examples/README.md +13 -0
  21. data/examples/a.rb +25 -0
  22. data/examples/b.rb +35 -0
  23. data/lib/morpher.rb +111 -0
  24. data/lib/morpher/compiler.rb +17 -0
  25. data/lib/morpher/compiler/emitter.rb +82 -0
  26. data/lib/morpher/compiler/error.rb +84 -0
  27. data/lib/morpher/compiler/evaluator.rb +63 -0
  28. data/lib/morpher/compiler/evaluator/emitter.rb +224 -0
  29. data/lib/morpher/compiler/preprocessor.rb +29 -0
  30. data/lib/morpher/compiler/preprocessor/emitter.rb +54 -0
  31. data/lib/morpher/compiler/preprocessor/emitter/anima.rb +69 -0
  32. data/lib/morpher/compiler/preprocessor/emitter/boolean.rb +31 -0
  33. data/lib/morpher/compiler/preprocessor/emitter/key.rb +87 -0
  34. data/lib/morpher/compiler/preprocessor/emitter/noop.rb +45 -0
  35. data/lib/morpher/compiler/preprocessor/emitter/param.rb +50 -0
  36. data/lib/morpher/evaluation.rb +118 -0
  37. data/lib/morpher/evaluator.rb +40 -0
  38. data/lib/morpher/evaluator/binary.rb +46 -0
  39. data/lib/morpher/evaluator/nary.rb +97 -0
  40. data/lib/morpher/evaluator/nullary.rb +92 -0
  41. data/lib/morpher/evaluator/nullary/parameterized.rb +48 -0
  42. data/lib/morpher/evaluator/predicate.rb +22 -0
  43. data/lib/morpher/evaluator/predicate/boolean.rb +76 -0
  44. data/lib/morpher/evaluator/predicate/contradiction.rb +36 -0
  45. data/lib/morpher/evaluator/predicate/eql.rb +50 -0
  46. data/lib/morpher/evaluator/predicate/negation.rb +52 -0
  47. data/lib/morpher/evaluator/predicate/primitive.rb +49 -0
  48. data/lib/morpher/evaluator/predicate/tautology.rb +36 -0
  49. data/lib/morpher/evaluator/transformer.rb +75 -0
  50. data/lib/morpher/evaluator/transformer/attribute.rb +25 -0
  51. data/lib/morpher/evaluator/transformer/block.rb +81 -0
  52. data/lib/morpher/evaluator/transformer/coerce.rb +166 -0
  53. data/lib/morpher/evaluator/transformer/custom.rb +34 -0
  54. data/lib/morpher/evaluator/transformer/domain.rb +86 -0
  55. data/lib/morpher/evaluator/transformer/domain/attribute_accessors.rb +60 -0
  56. data/lib/morpher/evaluator/transformer/domain/attribute_hash.rb +52 -0
  57. data/lib/morpher/evaluator/transformer/domain/instance_variables.rb +60 -0
  58. data/lib/morpher/evaluator/transformer/domain/param.rb +54 -0
  59. data/lib/morpher/evaluator/transformer/guard.rb +62 -0
  60. data/lib/morpher/evaluator/transformer/hash_transform.rb +149 -0
  61. data/lib/morpher/evaluator/transformer/input.rb +37 -0
  62. data/lib/morpher/evaluator/transformer/key.rb +86 -0
  63. data/lib/morpher/evaluator/transformer/map.rb +100 -0
  64. data/lib/morpher/evaluator/transformer/merge.rb +25 -0
  65. data/lib/morpher/evaluator/transformer/static.rb +27 -0
  66. data/lib/morpher/evaluator/unary.rb +79 -0
  67. data/lib/morpher/node_helpers.rb +19 -0
  68. data/lib/morpher/printer.rb +233 -0
  69. data/lib/morpher/printer/mixin.rb +58 -0
  70. data/lib/morpher/registry.rb +51 -0
  71. data/lib/morpher/type_lookup.rb +51 -0
  72. data/morpher.gemspec +29 -0
  73. data/spec/integration_spec.rb +184 -0
  74. data/spec/rcov.opts +7 -0
  75. data/spec/shared/evaluator_behavior.rb +155 -0
  76. data/spec/spec_helper.rb +36 -0
  77. data/spec/support/ice_nine_config.rb +8 -0
  78. data/spec/support/let_mock_helper.rb +8 -0
  79. data/spec/support/strip_helper.rb +12 -0
  80. data/spec/unit/morpher/compiler/preprocessor_spec.rb +46 -0
  81. data/spec/unit/morpher/evaluator/nullary/parameterized_spec.rb +25 -0
  82. data/spec/unit/morpher/evaluator/predicate/boolean/and_spec.rb +11 -0
  83. data/spec/unit/morpher/evaluator/predicate/boolean/or_spec.rb +26 -0
  84. data/spec/unit/morpher/evaluator/predicate/boolean/xor_spec.rb +26 -0
  85. data/spec/unit/morpher/evaluator/predicate/contrandiction_spec.rb +7 -0
  86. data/spec/unit/morpher/evaluator/predicate/eql_spec.rb +11 -0
  87. data/spec/unit/morpher/evaluator/predicate/negation_spec.rb +10 -0
  88. data/spec/unit/morpher/evaluator/predicate/primitive_spec.rb +17 -0
  89. data/spec/unit/morpher/evaluator/predicate/tautology_spec.rb +7 -0
  90. data/spec/unit/morpher/evaluator/transformer/attribute_spec.rb +9 -0
  91. data/spec/unit/morpher/evaluator/transformer/block_spec.rb +92 -0
  92. data/spec/unit/morpher/evaluator/transformer/coerce/parse_int_spec.rb +23 -0
  93. data/spec/unit/morpher/evaluator/transformer/custom_spec.rb +13 -0
  94. data/spec/unit/morpher/evaluator/transformer/domain/attribute_accessors_spec.rb +48 -0
  95. data/spec/unit/morpher/evaluator/transformer/domain/attribute_hash_spec.rb +40 -0
  96. data/spec/unit/morpher/evaluator/transformer/domain/instance_variables_spec.rb +47 -0
  97. data/spec/unit/morpher/evaluator/transformer/guard_spec.rb +12 -0
  98. data/spec/unit/morpher/evaluator/transformer/hash_transform_spec.rb +47 -0
  99. data/spec/unit/morpher/evaluator/transformer/input_spec.rb +11 -0
  100. data/spec/unit/morpher/evaluator/transformer/map_spec.rb +25 -0
  101. data/spec/unit/morpher/evaluator/transformer/static_spec.rb +10 -0
  102. data/spec/unit/morpher/evaluator_spec.rb +15 -0
  103. data/spec/unit/morpher/printer_spec.rb +21 -0
  104. data/spec/unit/morpher/registry_spec.rb +11 -0
  105. data/spec/unit/morpher_spec.rb +53 -0
  106. metadata +302 -0
@@ -0,0 +1,29 @@
1
+ module Morpher
2
+ class Compiler
3
+ # AST preprocessor
4
+ class Preprocessor < self
5
+ include Concord.new(:emitters)
6
+
7
+ # Call preprocessor
8
+ #
9
+ # @param [Node] node
10
+ # the raw AST node after DSL
11
+ #
12
+ # @return [Node]
13
+ # the transformed ast node
14
+ #
15
+ # @api private
16
+ #
17
+ def call(node)
18
+ loop do
19
+ emitter = emitters.fetch(node.type, Emitter::Noop)
20
+ node = emitter.call(self, node)
21
+ break if emitter.equal?(Emitter::Noop)
22
+ end
23
+
24
+ node
25
+ end
26
+
27
+ end # Preprocessor
28
+ end # Compiler
29
+ end # Morpher
@@ -0,0 +1,54 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Preprocessor
4
+ # Abstract preprocessor emitter
5
+ class Emitter < Compiler::Emitter
6
+ include Registry, Concord.new(:preprocessor, :node)
7
+
8
+ # Return output
9
+ #
10
+ # @return [AST::Node]
11
+ #
12
+ # @api private
13
+ #
14
+ def output
15
+ validate_node
16
+ processed_node
17
+ end
18
+ memoize :output
19
+
20
+ private
21
+
22
+ # Visit node
23
+ #
24
+ # @param [Node] node
25
+ # original untransformed node
26
+ #
27
+ # @return [Node]
28
+ # transformed node
29
+ #
30
+ # @api private
31
+ #
32
+ def visit(node)
33
+ preprocessor.call(node)
34
+ end
35
+
36
+ # Validate node
37
+ #
38
+ # @return [undefined]
39
+ # if successful
40
+ #
41
+ # @raise [Error]
42
+ # otherwise
43
+ #
44
+ # @api private
45
+ #
46
+ def validate_node
47
+ assert_children_amount(named_children.length)
48
+ end
49
+
50
+ end # Emitter
51
+
52
+ end # Preprocessor
53
+ end # Compiler
54
+ end # Morpher
@@ -0,0 +1,69 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Preprocessor
4
+ class Emitter
5
+ # Abstract base class for anima emitters
6
+ class Anima < self
7
+ include AbstractType
8
+
9
+ children :model
10
+
11
+ private
12
+
13
+ # Return domain param
14
+ #
15
+ # @return [Transformer::Domain::Param]
16
+ #
17
+ # @api private
18
+ #
19
+ def param
20
+ Morpher::Evaluator::Transformer::Domain::Param.new(
21
+ model,
22
+ model.anima.attribute_names
23
+ )
24
+ end
25
+
26
+ class Dump < self
27
+
28
+ register :anima_dump
29
+
30
+ private
31
+
32
+ # Return transformed node
33
+ #
34
+ # @param [Node] node
35
+ #
36
+ # @return [Node]
37
+ #
38
+ # @api private
39
+ #
40
+ def processed_node
41
+ s(:dump_attribute_hash, param)
42
+ end
43
+
44
+ end # Dump
45
+
46
+ class Load < self
47
+
48
+ register :anima_load
49
+
50
+ private
51
+
52
+ # Return transformed node
53
+ #
54
+ # @param [Node] node
55
+ #
56
+ # @return [Node]
57
+ #
58
+ # @api private
59
+ #
60
+ def processed_node
61
+ s(:load_attribute_hash, param)
62
+ end
63
+
64
+ end # Load
65
+ end # Anima
66
+ end # Emitter
67
+ end # Preprocessor
68
+ end # Compiler
69
+ end # Morpher
@@ -0,0 +1,31 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Preprocessor
4
+ class Emitter
5
+ # Preprocessor for boolean primitive
6
+ class Boolean < self
7
+ register :boolean
8
+
9
+ children
10
+
11
+ NODE = s(:xor, s(:primitive, TrueClass), s(:primitive, FalseClass))
12
+
13
+ private
14
+
15
+ # Return transformed node
16
+ #
17
+ # @param [Node] node
18
+ #
19
+ # @return [Node]
20
+ #
21
+ # @api private
22
+ #
23
+ def processed_node
24
+ NODE
25
+ end
26
+
27
+ end # Boolean
28
+ end # Emitter
29
+ end # Preprocessor
30
+ end # Compiler
31
+ end # Morpher
@@ -0,0 +1,87 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Preprocessor
4
+ class Emitter
5
+
6
+ # Namespace class for key preprocessors
7
+ class Key < self
8
+ include AbstractType
9
+
10
+ # Key symbolization preprocessor
11
+ class Symbolize < self
12
+
13
+ register :key_symbolize
14
+
15
+ children :key, :operand
16
+
17
+ private
18
+
19
+ # Return transformed node
20
+ #
21
+ # @param [Node] node
22
+ #
23
+ # @return [Node]
24
+ #
25
+ # @api private
26
+ #
27
+ def processed_node
28
+ s(:key_transform, key.to_s, key.to_sym, operand)
29
+ end
30
+
31
+ end # Symbolize
32
+
33
+ # Neutral key preprocessor
34
+ class Neutral < self
35
+
36
+ register :key
37
+
38
+ children :key, :operand
39
+
40
+ private
41
+
42
+ # Return transformed node
43
+ #
44
+ # @param [Node] node
45
+ #
46
+ # @return [Node]
47
+ #
48
+ # @api private
49
+ #
50
+ def processed_node
51
+ s(:key_transform, key, key, operand)
52
+ end
53
+
54
+ end # Neutral
55
+
56
+ # Key transformation preprocessor
57
+ class Transform < self
58
+ register :key_transform
59
+
60
+ children :from, :to, :operand
61
+
62
+ private
63
+
64
+ # Return transformed node
65
+ #
66
+ # @param [Node] node
67
+ #
68
+ # @return [Node]
69
+ #
70
+ # @api private
71
+ #
72
+ def processed_node
73
+ s(
74
+ :block,
75
+ s(:key_fetch, from),
76
+ visit(operand),
77
+ s(:key_dump, to)
78
+ )
79
+ end
80
+
81
+ end # Transform
82
+
83
+ end # Key
84
+ end # Emitter
85
+ end # Preprocessor
86
+ end # Compiler
87
+ end # Morpher
@@ -0,0 +1,45 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Preprocessor
4
+ class Emitter
5
+
6
+ # Noop emitter just descending into children
7
+ class Noop < self
8
+
9
+ private
10
+
11
+ # Return output
12
+ #
13
+ # @return [Node]
14
+ #
15
+ # @api private
16
+ #
17
+ def processed_node
18
+ mapped_children = node.children.map do |child|
19
+ if child.kind_of?(node.class)
20
+ visit(child)
21
+ else
22
+ child
23
+ end
24
+ end
25
+ s(node.type, *mapped_children)
26
+ end
27
+
28
+ # Validate node
29
+ #
30
+ # @return [undefined]
31
+ # if successful
32
+ #
33
+ # @raise [Error]
34
+ # otherwise
35
+ #
36
+ # @api private
37
+ #
38
+ def validate_node
39
+ end
40
+
41
+ end # Noop
42
+ end # Emitter
43
+ end # Preprocessor
44
+ end # Compiler
45
+ end # Morpher
@@ -0,0 +1,50 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Preprocessor
4
+ class Emitter
5
+
6
+ # Param domain transformer specific emitter
7
+ class Param < self
8
+
9
+ register :param
10
+
11
+ children :model
12
+
13
+ private
14
+
15
+ # Return output
16
+ #
17
+ # @return [Node]
18
+ #
19
+ # @api private
20
+ #
21
+ def processed_node
22
+ param = Morpher::Evaluator::Transformer::Domain::Param.new(
23
+ model,
24
+ remaining_children
25
+ )
26
+ s(:raw, param)
27
+ end
28
+
29
+ # Validate node
30
+ #
31
+ # @return [undefined]
32
+ # if successful
33
+ #
34
+ # @raise [Error]
35
+ # otherwise
36
+ #
37
+ # @api private
38
+ #
39
+ def validate_node
40
+ remaining_children.each_with_index do |child, index|
41
+ next if child.kind_of?(Symbol)
42
+ fail Error::ChildType, Symbol, child, index
43
+ end
44
+ end
45
+
46
+ end # Noop
47
+ end # Emitter
48
+ end # Preprocessor
49
+ end # Compiler
50
+ end # Morpher
@@ -0,0 +1,118 @@
1
+ module Morpher
2
+ # Abstract namespace class for evaluation states
3
+ class Evaluation
4
+ include AbstractType, Printer::Mixin, Adamantium::Flat, Anima.new(
5
+ :evaluator,
6
+ :input,
7
+ :output,
8
+ :success
9
+ )
10
+
11
+ private :success
12
+
13
+ # Test if evaluation was successful
14
+ #
15
+ # @return [true]
16
+ # if evaluation was successful
17
+ #
18
+ # @return [false]
19
+ # otherwise
20
+ #
21
+ # @api private
22
+ #
23
+ alias_method :success?, :success
24
+ public :success?
25
+
26
+ ERROR_DEFAULTS = IceNine.deep_freeze(
27
+ output: Undefined,
28
+ success: false
29
+ )
30
+
31
+ SUCCESS_DEFAULTS = IceNine.deep_freeze(
32
+ success: true
33
+ )
34
+
35
+ # Return error instance
36
+ #
37
+ # @param [Hash<Symbol, Object>] attributes
38
+ #
39
+ # @return [Evaluation]
40
+ #
41
+ # @api private
42
+ #
43
+ def self.error(attributes)
44
+ new(ERROR_DEFAULTS.merge(attributes))
45
+ end
46
+
47
+ # Return successful instance
48
+ #
49
+ # @param [Hash<Symbol, Object>] attributes
50
+ #
51
+ # @return [Evaluation]
52
+ #
53
+ # @api private
54
+ #
55
+ def self.success(attributes)
56
+ new(SUCCESS_DEFAULTS.merge(attributes))
57
+ end
58
+
59
+ # Evaluation state for nullary evaluators
60
+ class Nullary < self
61
+
62
+ printer do
63
+ name
64
+ indent do
65
+ attributes :input, :output, :success?
66
+ visit :evaluator
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ # Evaluation state for nary evaluators
73
+ class Nary < self
74
+ include anima.add(:evaluations)
75
+
76
+ printer do
77
+ name
78
+ indent do
79
+ attributes :input, :output, :success?
80
+ attribute_class :evaluator
81
+ visit_many :evaluations
82
+ end
83
+ end
84
+
85
+ end # Evaluation
86
+
87
+ # Evaluation state for unary evaluators
88
+ class Binary < self
89
+ include anima.add(:left_evaluation, :right_evaluation)
90
+
91
+ printer do
92
+ name
93
+ indent do
94
+ attributes :input, :output, :success?
95
+ visit :left_evaluation
96
+ visit :right_evaluation
97
+ end
98
+ end
99
+
100
+ end # Unary
101
+
102
+ # Evaluation state for unary evaluators
103
+ class Unary < self
104
+ include anima.add(:operand_evaluation)
105
+
106
+ printer do
107
+ name
108
+ indent do
109
+ attributes :input, :output, :success?
110
+ visit :operand_evaluation
111
+ visit :evaluator
112
+ end
113
+ end
114
+
115
+ end # Unary
116
+
117
+ end # Evaluation
118
+ end # Morpher