rgen 0.4.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG +95 -83
  2. data/Rakefile +4 -3
  3. data/lib/ea_support/ea_support.rb +54 -0
  4. data/lib/ea_support/id_store.rb +32 -0
  5. data/lib/ea_support/uml13_ea_metamodel.rb +562 -0
  6. data/lib/ea_support/uml13_ea_metamodel_ext.rb +45 -0
  7. data/lib/ea_support/uml13_ea_metamodel_generator.rb +43 -0
  8. data/lib/ea_support/uml13_ea_to_uml13.rb +72 -0
  9. data/lib/ea_support/uml13_to_uml13_ea.rb +82 -0
  10. data/lib/rgen/ecore/ecore.rb +16 -2
  11. data/lib/rgen/ecore/ecore_builder_methods.rb +81 -0
  12. data/lib/rgen/ecore/ecore_instantiator.rb +5 -1
  13. data/lib/rgen/metamodel_builder/builder_extensions.rb +11 -3
  14. data/lib/rgen/metamodel_builder/module_extension2.rb +205 -0
  15. data/lib/rgen/method_delegation.rb +99 -0
  16. data/lib/rgen/model_builder.rb +27 -0
  17. data/lib/rgen/model_builder/builder_context.rb +318 -0
  18. data/lib/rgen/model_builder/model_serializer.rb +201 -0
  19. data/lib/rgen/model_builder/reference_resolver.rb +156 -0
  20. data/lib/rgen/template_language/directory_template_container.rb +6 -2
  21. data/lib/rgen/template_language/output_handler.rb +2 -4
  22. data/lib/rgen/template_language/template_container.rb +212 -195
  23. data/lib/rgen/transformer.rb +95 -4
  24. data/lib/transformers/ecore_to_uml13.rb +66 -0
  25. data/lib/transformers/uml13_to_ecore.rb +16 -7
  26. data/test/ea_instantiator_test.rb +8 -14
  27. data/test/ea_serializer_test.rb +3 -9
  28. data/test/ea_serializer_test/ea_testmodel_regenerated.xml +2 -2
  29. data/test/ea_serializer_test/ea_testmodel_regenerated_import.log +3 -0
  30. data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +19 -19
  31. data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +44 -44
  32. data/test/method_delegation_test.rb +178 -0
  33. data/test/model_builder/builder_context_test.rb +59 -0
  34. data/test/model_builder/builder_test.rb +284 -0
  35. data/test/model_builder/ecore_internal.rb +103 -0
  36. data/test/model_builder/ecore_original.rb +163 -0
  37. data/test/model_builder/ecore_original_regenerated.rb +163 -0
  38. data/test/model_builder/reference_resolver_test.rb +156 -0
  39. data/test/model_builder/serializer_test.rb +63 -0
  40. data/test/model_builder_test.rb +4 -0
  41. data/test/rgen_test.rb +2 -0
  42. data/test/template_language_test.rb +41 -1
  43. data/test/template_language_test/expected_result1.txt +1 -3
  44. data/test/template_language_test/templates/define_local_test/local.tpl +8 -0
  45. data/test/template_language_test/templates/define_local_test/test.tpl +8 -0
  46. data/test/template_language_test/templates/evaluate_test/test.tpl +7 -0
  47. data/test/template_language_test/templates/no_indent_test/no_indent.tpl +3 -0
  48. data/test/template_language_test/templates/no_indent_test/sub1/no_indent.tpl +3 -0
  49. data/test/template_language_test/templates/no_indent_test/test.tpl +24 -0
  50. data/test/template_language_test/templates/no_indent_test/test2.tpl +13 -0
  51. data/test/template_language_test/templates/no_indent_test/test3.tpl +10 -0
  52. data/test/template_language_test/templates/template_resolution_test/sub1.tpl +9 -0
  53. data/test/template_language_test/templates/template_resolution_test/sub1/sub1.tpl +3 -0
  54. data/test/template_language_test/templates/template_resolution_test/test.tpl +4 -0
  55. data/test/template_language_test/testout.txt +1 -3
  56. data/test/testmodel/ea_testmodel_import.log +1 -0
  57. data/test/testmodel/ea_testmodel_regenerated.xml +808 -0
  58. data/test/transformer_test.rb +3 -5
  59. metadata +52 -3
  60. data/lib/instantiators/ea_instantiator.rb +0 -39
@@ -0,0 +1,156 @@
1
+ require 'rgen/array_extensions'
2
+
3
+ module RGen
4
+
5
+ module ModelBuilder
6
+
7
+ class ReferenceResolver
8
+ ResolverJob = Struct.new(:receiver, :reference, :namespace, :string)
9
+
10
+ class ResolverException < Exception
11
+ end
12
+
13
+ class ToplevelNamespace
14
+ def initialize(ns)
15
+ raise "Namespace must be an Enumerable" unless ns.is_a?(Enumerable)
16
+ @ns = ns
17
+ end
18
+ def elements
19
+ @ns
20
+ end
21
+ end
22
+
23
+ def initialize
24
+ @jobs = []
25
+ @elementName = {}
26
+ end
27
+
28
+ def addJob(job)
29
+ @jobs << job
30
+ end
31
+
32
+ def setElementName(element, name)
33
+ @elementName[element] = name
34
+ end
35
+
36
+ def resolve(ns=[])
37
+ @toplevelNamespace = ToplevelNamespace.new(ns)
38
+ (@jobs || []).each_with_index do |job, i|
39
+ target = resolveReference(job.namespace || @toplevelNamespace, job.string.split("."))
40
+ raise ResolverException.new("Can not resolve reference #{job.string}") unless target
41
+ if job.reference.many
42
+ job.receiver.addGeneric(job.reference.name, target)
43
+ else
44
+ job.receiver.setGeneric(job.reference.name, target)
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # TODO: if a reference can not be fully resolved, but a prefix can be found,
52
+ # the exception reported is that its first path element can not be found on
53
+ # toplevel
54
+ def resolveReference(namespace, nameParts)
55
+ element = resolveReferenceDownwards(namespace, nameParts)
56
+ if element.nil? && parentNamespace(namespace)
57
+ element = resolveReference(parentNamespace(namespace), nameParts)
58
+ end
59
+ element
60
+ end
61
+
62
+ def resolveReferenceDownwards(namespace, nameParts)
63
+ firstPart, *restParts = nameParts
64
+ element = namespaceElementByName(namespace, firstPart)
65
+ return nil unless element
66
+ if restParts.size > 0
67
+ resolveReferenceDownwards(element, restParts)
68
+ else
69
+ element
70
+ end
71
+ end
72
+
73
+ def namespaceElementByName(namespace, name)
74
+ @namespaceElementsByName ||= {}
75
+ return @namespaceElementsByName[namespace][name] if @namespaceElementsByName[namespace]
76
+ hash = {}
77
+ namespaceElements(namespace).each do |e|
78
+ raise ResolverException.new("Multiple elements named #{elementName(e)} found in #{nsToS(namespace)}") if hash[elementName(e)]
79
+ hash[elementName(e)] = e if elementName(e)
80
+ end
81
+ @namespaceElementsByName[namespace] = hash
82
+ hash[name]
83
+ end
84
+
85
+ def parentNamespace(namespace)
86
+ if namespace.class.respond_to?(:ecore)
87
+ parents = elementParents(namespace)
88
+ raise ResolverException.new("Element #{nsToS(namespace)} has multiple parents") \
89
+ if parents.size > 1
90
+ parents.first || @toplevelNamespace
91
+ else
92
+ nil
93
+ end
94
+ end
95
+
96
+ def namespaceElements(namespace)
97
+ if namespace.is_a?(ToplevelNamespace)
98
+ namespace.elements
99
+ elsif namespace.class.respond_to?(:ecore)
100
+ elementChildren(namespace)
101
+ else
102
+ raise ResolverException.new("Element #{nsToS(namespace)} can not be used as a namespace")
103
+ end
104
+ end
105
+
106
+ def nsToS(namespace)
107
+ if namespace.is_a?(ToplevelNamespace)
108
+ "toplevel namespace"
109
+ else
110
+ result = namespace.class.name
111
+ result += ":\"#{elementName(namespace)}\"" if elementName(namespace)
112
+ result
113
+ end
114
+ end
115
+
116
+ def elementName(element)
117
+ @elementName[element]
118
+ end
119
+
120
+ def elementChildren(element)
121
+ @elementChildren ||= {}
122
+ return @elementChildren[element] if @elementChildren[element]
123
+ children = containmentRefs(element).collect do |r|
124
+ element.getGeneric(r.name)
125
+ end.flatten.compact
126
+ @elementChildren[element] = children
127
+ end
128
+
129
+ def elementParents(element)
130
+ @elementParents ||= {}
131
+ return @elementParents[element] if @elementParents[element]
132
+ parents = parentRefs(element).collect do |r|
133
+ element.getGeneric(r.name)
134
+ end.flatten.compact
135
+ @elementParents[element] = parents
136
+ end
137
+
138
+ def containmentRefs(element)
139
+ @containmentRefs ||= {}
140
+ @containmentRefs[element.class] ||= eAllReferences(element).select{|r| r.containment}
141
+ end
142
+
143
+ def parentRefs(element)
144
+ @parentRefs ||= {}
145
+ @parentRefs[element.class] ||= eAllReferences(element).select{|r| r.eOpposite && r.eOpposite.containment}
146
+ end
147
+
148
+ def eAllReferences(element)
149
+ @eAllReferences ||= {}
150
+ @eAllReferences[element.class] ||= element.class.ecore.eAllReferences
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ end
@@ -13,6 +13,7 @@ class DirectoryTemplateContainer
13
13
 
14
14
  def initialize(metamodel=nil, output_path=nil, parent=nil)
15
15
  @containers = {}
16
+ @directoryContainers = {}
16
17
  @parent = parent
17
18
  @metamodel = metamodel
18
19
  @output_path = output_path
@@ -24,7 +25,7 @@ class DirectoryTemplateContainer
24
25
  if !File.directory?(qf) && f =~ /^(.*)\.tpl$/
25
26
  (@containers[$1] = TemplateContainer.new(@metamodel, @output_path, self,qf)).load
26
27
  elsif File.directory?(qf) && f != "." && f != ".."
27
- (@containers[f] = DirectoryTemplateContainer.new(@metamodel, @output_path, self)).load(qf)
28
+ (@directoryContainers[f] = DirectoryTemplateContainer.new(@metamodel, @output_path, self)).load(qf)
28
29
  end
29
30
  }
30
31
  end
@@ -64,9 +65,12 @@ class DirectoryTemplateContainer
64
65
  private
65
66
 
66
67
  def _expand(template, *all_args)
67
- if template =~ /^\/?([^:\/]+)(?:::|\/)([^:\/].*)/
68
+ if template =~ /^\/?(\w+)::(\w.*)/
68
69
  raise "Template not found: #{$1}" unless @containers[$1]
69
70
  @containers[$1].expand($2, *all_args)
71
+ elsif template =~ /^\/?(\w+)\/(\w.*)/
72
+ raise "Template not found: #{$1}" unless @directoryContainers[$1]
73
+ @directoryContainers[$1].expand($2, *all_args)
70
74
  else
71
75
  raise "Invalid template name: #{template}"
72
76
  end
@@ -7,6 +7,7 @@ module TemplateLanguage
7
7
 
8
8
  class OutputHandler
9
9
  attr_writer :indent
10
+ attr_accessor :noIndentNextLine
10
11
 
11
12
  def initialize(indent=0, indentString=" ", mode=:explicit)
12
13
  self.mode = mode
@@ -22,6 +23,7 @@ module TemplateLanguage
22
23
  #
23
24
  def concat(s)
24
25
  return @output.concat(s) if s.is_a? OutputHandler
26
+ #puts [object_id, noIndentNextLine, @state, @output.to_s, s].inspect
25
27
  s = s.to_str.gsub(/^[\t ]*\r?\n/,'') if @ignoreNextNL
26
28
  s = s.to_str.gsub(/^\s+/,'') if @ignoreNextWS
27
29
  @ignoreNextNL = @ignoreNextWS = false if s =~ /\S/
@@ -74,10 +76,6 @@ module TemplateLanguage
74
76
  @ignoreNextWS = true
75
77
  end
76
78
 
77
- def noIndentNextLine
78
- @noIndentNextLine = true
79
- end
80
-
81
79
  def mode=(m)
82
80
  raise StandardError.new("Unknown mode: #{m}") unless [:direct, :explicit].include?(m)
83
81
  @mode = m
@@ -8,208 +8,225 @@ require 'rgen/template_language/template_helper'
8
8
 
9
9
  module RGen
10
10
 
11
- module TemplateLanguage
12
-
13
- class TemplateContainer
14
- include TemplateHelper
15
-
16
- def initialize(metamodels, output_path, parent, filename)
17
- @templates = {}
18
- @parent = parent
19
- @filename = filename
20
- @indent = 0
21
- @output_path = output_path
22
- @metamodels = metamodels
23
- @metamodels = [ @metamodels ] unless @metamodels.is_a?(Array)
24
- end
25
-
26
- def load
27
- File.open(@filename,"rb") do |f|
28
- begin
29
- @@metamodels = @metamodels
30
- fileContent = f.read
31
- _detectNewLinePattern(fileContent)
32
- ERB.new(fileContent,nil,nil,'@output').result(binding)
33
- rescue Exception => e
34
- processAndRaise(e)
11
+ module TemplateLanguage
12
+
13
+ class TemplateContainer
14
+ include TemplateHelper
15
+
16
+ def initialize(metamodels, output_path, parent, filename)
17
+ @templates = {}
18
+ @parent = parent
19
+ @filename = filename
20
+ @indent = 0
21
+ @output_path = output_path
22
+ @metamodels = metamodels
23
+ @metamodels = [ @metamodels ] unless @metamodels.is_a?(Array)
35
24
  end
36
- end
37
- end
38
-
39
- # if this container can handle the call, the expansion result is returned
40
- # otherwise expand is called on the appropriate container and the result is added to @output
41
- def expand(template, *all_args)
42
- args, params = _splitArgsAndOptions(all_args)
43
- if params.has_key?(:foreach)
44
- raise StandardError.new("expand :foreach argument is not enumerable") \
45
- unless params[:foreach].is_a?(Enumerable)
46
- _expand_foreach(template, args, params)
47
- else
48
- _expand(template, args, params)
49
- end
50
- end
51
-
52
- def this
53
- @context
54
- end
55
-
56
- def method_missing(name, *args)
57
- @context.send(name, *args)
58
- end
59
-
60
- def self.const_missing(name)
61
- super unless @@metamodels
62
- @@metamodels.each do |mm|
63
- return mm.const_get(name) rescue NameError
64
- end
65
- super
66
- end
67
-
68
- private
69
-
70
- def nonl
71
- @output.ignoreNextNL
72
- end
73
-
74
- def nows
75
- @output.ignoreNextWS
76
- end
77
-
78
- def nl
79
- _direct_concat(@newLinePattern)
80
- end
81
-
82
- def ws
83
- _direct_concat(" ")
84
- end
85
-
86
- def iinc
87
- @indent += 1
88
- @output.indent = @indent
89
- end
90
-
91
- def idec
92
- @indent -= 1 if @indent > 0
93
- @output.indent = @indent
94
- end
95
-
96
- def define(template, params={}, &block)
97
- @templates[template] ||= {}
98
- cls = params[:for] || Object
99
- @templates[template][cls] = block
100
- end
101
-
102
- def file(name, indentString=nil)
103
- old_output, @output = @output, OutputHandler.new(@indent, indentString || @parent.indentString)
104
- begin
105
- yield
106
- rescue Exception => e
107
- processAndRaise(e)
108
- end
109
- path = ""
110
- path += @output_path+"/" if @output_path
111
- dirname = File.dirname(path+name)
112
- FileUtils.makedirs(dirname) unless File.exist?(dirname)
113
- File.open(path+name,"wb") { |f| f.write(@output) }
114
- @output = old_output
115
- end
116
-
117
- # private private
118
-
119
- def _expand_foreach(template, args, params)
120
- sep = params[:separator]
121
- params[:foreach].each_with_index {|e,i|
122
- single_params = params.dup
123
- single_params[:for] = e
124
- _direct_concat(sep.to_s) if sep && i > 0
125
- _expand(template, args, single_params)
126
- }
127
- end
128
-
129
- LOCAL_TEMPLATE_REGEX = /^:*(\w+)$/
130
-
131
- def _expand(template, args, params)
132
- raise StandardError.new("expand :for argument evaluates to nil") if params.has_key?(:for) && params[:for].nil?
133
- context = params[:for]
134
- @indent = params[:indent] || @indent
135
- # if this is the first call to expand within this container, @output is nil
136
- noIndentNextLine = params[:noIndentNextLine]
137
- noIndentNextLine = (@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0]) if noIndentNextLine.nil?
138
- old_context, @context = @context, context if context
139
- local_output = nil
140
- if template =~ LOCAL_TEMPLATE_REGEX
141
- tplname = $1
142
- raise StandardError.new("Template not found: #{$1}") unless @templates[tplname]
143
- old_output, @output = @output, OutputHandler.new(@indent, @parent.indentString)
144
- @output.noIndentNextLine if noIndentNextLine
145
- _call_template(tplname, @context, args)
146
- local_output, @output = @output, old_output
147
- else
148
- local_output = @parent.expand(template, *(args.dup << {:for => @context, :indent => @indent, :noIndentNextLine => noIndentNextLine}))
149
- end
150
- _direct_concat(local_output)
151
- @context = old_context if old_context
152
- local_output
153
- end
154
-
155
- def processAndRaise(e, tpl=nil)
156
- bt = e.backtrace.dup
157
- e.backtrace.each_with_index do |t,i|
158
- if t =~ /\(erb\):(\d+):/
159
- bt[i] = "#{@filename}:#{$1}"
160
- bt[i] += ":in '#{tpl}'" if tpl
161
- break
25
+
26
+ def load
27
+ File.open(@filename,"rb") do |f|
28
+ begin
29
+ @@metamodels = @metamodels
30
+ fileContent = f.read
31
+ _detectNewLinePattern(fileContent)
32
+ ERB.new(fileContent,nil,nil,'@output').result(binding)
33
+ rescue Exception => e
34
+ processAndRaise(e)
35
+ end
36
+ end
162
37
  end
163
- end
164
- raise e, e.to_s, bt
165
- end
166
-
167
- def _call_template(tpl, context, args)
168
- found = false
169
- @templates[tpl].each_pair do |key, value|
170
- if context.is_a?(key)
171
- proc = @templates[tpl][key]
172
- arity = proc.arity
173
- arity = 0 if arity == -1 # if no args are given
174
- raise StandardError.new("Wrong number of arguments calling template #{tpl}: #{args.size} for #{arity} "+
175
- "(Beware: Hashes as last arguments are taken as options and are ignored)") \
176
- if arity != args.size
38
+
39
+ def expand(template, *all_args)
40
+ args, params = _splitArgsAndOptions(all_args)
41
+ if params.has_key?(:foreach)
42
+ raise StandardError.new("expand :foreach argument is not enumerable") \
43
+ unless params[:foreach].is_a?(Enumerable)
44
+ _expand_foreach(template, args, params)
45
+ else
46
+ _expand(template, args, params)
47
+ end
48
+ end
49
+
50
+ def evaluate(template, *all_args)
51
+ args, params = _splitArgsAndOptions(all_args)
52
+ raise StandardError.new(":foreach can not be used with evaluate") if params[:foreach]
53
+ _expand(template, args, params.merge({:_evalOnly => true}))
54
+ end
55
+
56
+ def this
57
+ @context
58
+ end
59
+
60
+ def method_missing(name, *args)
61
+ @context.send(name, *args)
62
+ end
63
+
64
+ def self.const_missing(name)
65
+ super unless @@metamodels
66
+ @@metamodels.each do |mm|
67
+ return mm.const_get(name) rescue NameError
68
+ end
69
+ super
70
+ end
71
+
72
+ private
73
+
74
+ def nonl
75
+ @output.ignoreNextNL
76
+ end
77
+
78
+ def nows
79
+ @output.ignoreNextWS
80
+ end
81
+
82
+ def nl
83
+ _direct_concat(@newLinePattern)
84
+ end
85
+
86
+ def ws
87
+ _direct_concat(" ")
88
+ end
89
+
90
+ def iinc
91
+ @indent += 1
92
+ @output.indent = @indent
93
+ end
94
+
95
+ def idec
96
+ @indent -= 1 if @indent > 0
97
+ @output.indent = @indent
98
+ end
99
+
100
+ TemplateDesc = Struct.new(:block, :local)
101
+
102
+ def define(template, params={}, &block)
103
+ _define(template, params, &block)
104
+ end
105
+
106
+ def define_local(template, params={}, &block)
107
+ _define(template, params.merge({:local => true}), &block)
108
+ end
109
+
110
+ def file(name, indentString=nil)
111
+ old_output, @output = @output, OutputHandler.new(@indent, indentString || @parent.indentString)
177
112
  begin
178
- @@metamodels = @metamodels
179
- proc.call(*args)
113
+ yield
180
114
  rescue Exception => e
181
- processAndRaise(e, tpl)
115
+ processAndRaise(e)
182
116
  end
183
- found = true
117
+ path = ""
118
+ path += @output_path+"/" if @output_path
119
+ dirname = File.dirname(path+name)
120
+ FileUtils.makedirs(dirname) unless File.exist?(dirname)
121
+ File.open(path+name,"wb") { |f| f.write(@output) }
122
+ @output = old_output
184
123
  end
124
+
125
+ # private private
126
+
127
+ def _define(template, params={}, &block)
128
+ @templates[template] ||= {}
129
+ cls = params[:for] || Object
130
+ @templates[template][cls] = TemplateDesc.new(block, params[:local])
131
+ end
132
+
133
+ def _expand_foreach(template, args, params)
134
+ sep = params[:separator]
135
+ params[:foreach].each_with_index {|e,i|
136
+ _direct_concat(sep.to_s) if sep && i > 0
137
+ output = _expand(template, args, params.merge({:for => e}))
138
+ }
139
+ end
140
+
141
+ LOCAL_TEMPLATE_REGEX = /^:*(\w+)$/
142
+
143
+ def _expand(template, args, params)
144
+ raise StandardError.new("expand :for argument evaluates to nil") if params.has_key?(:for) && params[:for].nil?
145
+ context = params[:for]
146
+ @indent = params[:indent] || @indent
147
+ noIndentNextLine = params[:_noIndentNextLine] ||
148
+ (@output.is_a?(OutputHandler) && @output.noIndentNextLine) ||
149
+ (@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0])
150
+ caller = params[:_caller] || self
151
+ old_context, @context = @context, context if context
152
+ local_output = nil
153
+ if template =~ LOCAL_TEMPLATE_REGEX
154
+ tplname = $1
155
+ raise StandardError.new("Template not found: #{$1}") unless @templates[tplname]
156
+ old_output, @output = @output, OutputHandler.new(@indent, @parent.indentString)
157
+ @output.noIndentNextLine = noIndentNextLine
158
+ _call_template(tplname, @context, args, caller == self)
159
+ old_output.noIndentNextLine = false if old_output.is_a?(OutputHandler) && !old_output.noIndentNextLine
160
+ local_output, @output = @output, old_output
161
+ else
162
+ local_output = @parent.expand(template, *(args.dup << {:for => @context, :indent => @indent, :_noIndentNextLine => noIndentNextLine, :_evalOnly => true, :_caller => caller}))
163
+ end
164
+ _direct_concat(local_output) unless params[:_evalOnly]
165
+ @context = old_context if old_context
166
+ local_output.to_s
167
+ end
168
+
169
+ def processAndRaise(e, tpl=nil)
170
+ bt = e.backtrace.dup
171
+ e.backtrace.each_with_index do |t,i|
172
+ if t =~ /\(erb\):(\d+):/
173
+ bt[i] = "#{@filename}:#{$1}"
174
+ bt[i] += ":in '#{tpl}'" if tpl
175
+ break
176
+ end
177
+ end
178
+ raise e, e.to_s, bt
179
+ end
180
+
181
+ def _call_template(tpl, context, args, localCall)
182
+ found = false
183
+ @templates[tpl].each_pair do |key, value|
184
+ if context.is_a?(key)
185
+ templateDesc = @templates[tpl][key]
186
+ proc = templateDesc.block
187
+ arity = proc.arity
188
+ arity = 0 if arity == -1 # if no args are given
189
+ raise StandardError.new("Wrong number of arguments calling template #{tpl}: #{args.size} for #{arity} "+
190
+ "(Beware: Hashes as last arguments are taken as options and are ignored)") \
191
+ if arity != args.size
192
+ raise StandardError.new("Template can only be called locally: #{tpl}") \
193
+ if templateDesc.local && !localCall
194
+ begin
195
+ @@metamodels = @metamodels
196
+ proc.call(*args)
197
+ rescue Exception => e
198
+ processAndRaise(e, tpl)
199
+ end
200
+ found = true
201
+ end
202
+ end
203
+ raise StandardError.new("Template class not matching: #{tpl} for #{context.class.name}") unless found
204
+ end
205
+
206
+ def _direct_concat(s)
207
+ if @output.is_a? OutputHandler
208
+ @output.direct_concat(s)
209
+ else
210
+ @output << s
211
+ end
212
+ end
185
213
 
214
+ def _detectNewLinePattern(text)
215
+ tests = 0
216
+ rnOccurances = 0
217
+ text.scan(/(\r?)\n/) do |groups|
218
+ tests += 1
219
+ rnOccurances += 1 if groups[0] == "\r"
220
+ break if tests >= 10
221
+ end
222
+ if rnOccurances > (tests / 2)
223
+ @newLinePattern = "\r\n"
224
+ else
225
+ @newLinePattern = "\n"
226
+ end
227
+ end
228
+
186
229
  end
187
- raise StandardError.new("Template class not matching: #{tpl} for #{context.class.name}") unless found
188
- end
189
-
190
- def _direct_concat(s)
191
- if @output.is_a? OutputHandler
192
- @output.direct_concat(s)
193
- else
194
- @output << s
195
- end
196
- end
197
-
198
- def _detectNewLinePattern(text)
199
- tests = 0
200
- rnOccurances = 0
201
- text.scan(/(\r?)\n/) do |groups|
202
- tests += 1
203
- rnOccurances += 1 if groups[0] == "\r"
204
- break if tests >= 10
205
- end
206
- if rnOccurances > (tests / 2)
207
- @newLinePattern = "\r\n"
208
- else
209
- @newLinePattern = "\n"
210
- end
230
+
211
231
  end
212
- end
213
-
214
- end
215
232
 
216
233
  end