Class: Luca::ComponentDefinition

Inherits:
Object
  • Object
show all
Defined in:
lib/luca/component_definition.rb

Defined Under Namespace

Classes: Line

Constant Summary collapse

ARGUMENTS_REGEX =
/^\w+\:\s*\((.+)\)/

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ ComponentDefinition



21
22
23
24
# File 'lib/luca/component_definition.rb', line 21

def initialize source 
  @source     = source
  read_source()
end

Class Attribute Details

.markdownObject

Returns the value of attribute markdown.



12
13
14
# File 'lib/luca/component_definition.rb', line 12

def markdown
  @markdown
end

Instance Attribute Details

#markdownObject

Returns the value of attribute markdown.



7
8
9
# File 'lib/luca/component_definition.rb', line 7

def markdown
  @markdown
end

#sourceObject

Returns the value of attribute source.



7
8
9
# File 'lib/luca/component_definition.rb', line 7

def source
  @source
end

Instance Method Details

#argument_information_for(method) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/luca/component_definition.rb', line 101

def argument_information_for method
  information = []
  definition = find_definition_of(method).line.strip

  if arguments  = definition.match(ARGUMENTS_REGEX)
    arguments = arguments.to_a[1]
    information = arguments.split(',').map(&:strip).inject(information) do |memo, argument|
      parts = argument.split('=').map(&:strip)
      memo << {:argument=>parts[0],:value=>parts[1]}
    end
  end

  information
end

#as_json(options = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/luca/component_definition.rb', line 41

def as_json options={} 
  base = {
    source: source,
    defined_in_file: source,
    type: "javascript",
    starts_on_line: definition_line.line_number
  }

  unless class_name.nil?
    base.merge!({ :class_name           => class_name,
                  :defined_in_file      => source,
                  :header_documentation => header_documentation,
                  :type_alias           => type_alias,
                  :type                 => "component_definition",
                  :css_class_identifier => css_class_identifier,
                  :defines_methods      => method_definition_map,
                  :defines_properties   => property_definition_map })
  end

  if options[:include_contents]
    base.merge!(:source_file_contents => contents)
  end

  if options[:compile]
    base.merge!(:compiled => compiled_contents)
  end

  base
end

#class_nameObject



169
170
171
172
# File 'lib/luca/component_definition.rb', line 169

def class_name 
  match = definition_line && definition_line.match(/register.*["|'](.*)["|']/)
  match && match[1]
end

#compiledObject



131
132
133
# File 'lib/luca/component_definition.rb', line 131

def compiled
  compiled_contents
end

#compiled_contentsObject



135
136
137
# File 'lib/luca/component_definition.rb', line 135

def compiled_contents
  compiler.output
end

#compilerObject



127
128
129
# File 'lib/luca/component_definition.rb', line 127

def compiler
  AssetCompiler.new(input: contents, type: "coffeescript")
end

#component_definitionObject



174
175
176
# File 'lib/luca/component_definition.rb', line 174

def component_definition
  self
end

#contentsObject



123
124
125
# File 'lib/luca/component_definition.rb', line 123

def contents
  @contents.to_s
end

#css_class_identifierObject



153
154
155
156
157
158
159
160
161
162
163
# File 'lib/luca/component_definition.rb', line 153

def css_class_identifier
  return '' unless view_based?

  parts = class_name.split('.')
  parts -= ['views','components'] 

  parts.map!(&:underscore)
  parts.map!(&:dasherize)

  parts.join('-')
end

#default_value_for(property) ⇒ Object



95
96
97
98
99
# File 'lib/luca/component_definition.rb', line 95

def default_value_for property
  definition = find_definition_of(property).line.strip
  property, value = definition.split(':')
  value && value.strip
end

#definesObject



262
263
264
# File 'lib/luca/component_definition.rb', line 262

def defines
  lines.select(&:defines_property_or_method?).collect(&:defines)
end

#defines_methodsObject



266
267
268
# File 'lib/luca/component_definition.rb', line 266

def defines_methods
  lines.select(&:defines_method?).collect(&:defines)
end

#defines_propertiesObject



274
275
276
# File 'lib/luca/component_definition.rb', line 274

def defines_properties
  lines.select(&:defines_property?).collect(&:defines)
end

#definition_lineObject



256
257
258
259
260
# File 'lib/luca/component_definition.rb', line 256

def definition_line
  lines.detect do |line|
    !line.comment? && line.component_definition?
  end
end

#definition_proxy_variable_nameObject



248
249
250
# File 'lib/luca/component_definition.rb', line 248

def definition_proxy_variable_name
  definition_line.split('=').first.strip
end

#documentation_for(method_or_property, compile = true) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/luca/component_definition.rb', line 193

def documentation_for method_or_property, compile=true
  comment_lines = find_comments_above(method_or_property).collect(&:line)
  comments = comment_lines.map do |comment_line|
    comment_line.gsub(/\A\s*\#/,'').strip
  end

  data = comments.reverse.join("\n")

  docs = if compile == true
    self.class.markdown.render(data) rescue data
  end

  docs
end

#extendsObject



165
166
167
# File 'lib/luca/component_definition.rb', line 165

def extends
  extends_line.split(' ').last.gsub(/"|'/,'')
end

#extends_lineObject



185
186
187
188
189
190
191
# File 'lib/luca/component_definition.rb', line 185

def extends_line
  match = lines.detect do |line|
    line.component_extension?(definition_proxy_variable_name)
  end

  match && match.strip
end

#find_comments_above(method_or_property) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/luca/component_definition.rb', line 232

def find_comments_above method_or_property
  comment_lines = []
  if line = find_definition_of( method_or_property )
    line_number = line.line_number
    indentation_level = line.indentation_level        

    next_line = find_line_by_number( line_number -= 1)
    while !next_line.nil? && next_line.indentation_level == indentation_level && next_line.comment?
      comment_lines << next_line
      next_line = find_line_by_number( line_number -= 1)
    end
  end

  comment_lines
end

#find_definition_of(method_or_property) ⇒ Object



270
271
272
# File 'lib/luca/component_definition.rb', line 270

def find_definition_of method_or_property
  lines.select(&:defines_property_or_method?).detect {|line| line.defines && line.defines.length > 0 && line.defines == method_or_property }
end

#find_line_by_number(line_number = 1) ⇒ Object



252
253
254
# File 'lib/luca/component_definition.rb', line 252

def find_line_by_number line_number=1
  lines.detect {|line| line.line_number == line_number }
end

#header_comment_linesObject



212
213
214
215
216
217
218
219
220
# File 'lib/luca/component_definition.rb', line 212

def header_comment_lines
  header_lines  = lines[ (0..(definition_line.line_number || 0) ) ]
  comments      = header_lines.select(&:comment?).map(&:line)
  
  comments.map! {|line| line.gsub(/\A\s*\#[\ |\n]/,'') }
  comments.reject! {|line| line.match(/\=\s*require/) }

  comments
end

#header_comments(compile = true) ⇒ Object



222
223
224
225
226
227
228
229
230
# File 'lib/luca/component_definition.rb', line 222

def header_comments compile=true
  combined = header_comment_lines.join("")

  if compile && self.class.markdown && self.class.markdown.respond_to?(:render)
    self.class.markdown.render(combined)
  else
    combined
  end
end

#header_documentationObject



208
209
210
# File 'lib/luca/component_definition.rb', line 208

def header_documentation
  header_comments(true)
end

#linesObject



178
179
180
181
182
183
# File 'lib/luca/component_definition.rb', line 178

def lines
  line_number = 0
  contents.lines.map do |line|
    Line.new(line, (line_number += 1) )
  end
end

#method_definition_mapObject



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/luca/component_definition.rb', line 71

def method_definition_map
  defines_methods.inject({}) do |memo, meth|
    definition_line = find_definition_of(meth)
    memo[meth] = {
      defined_on_line: definition_line.line_number,
      documentation: documentation_for(meth) || "",
      arguments: argument_information_for(meth)        
    } 
    memo
  end
end

#parseObject



120
121
# File 'lib/luca/component_definition.rb', line 120

def parse
end

#property_definition_mapObject



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/luca/component_definition.rb', line 83

def property_definition_map
  defines_properties.inject({}) do |memo,property|
    definition_line = find_definition_of(property)
    memo[property] = {
      defined_on_line: definition_line.line_number,
      documentation: documentation_for(property),
      default: default_value_for(property) 
    }
    memo
  end
end

#read_sourceObject



26
27
28
29
# File 'lib/luca/component_definition.rb', line 26

def read_source
  raise "Invalid source type" unless source.match(/.coffee|.js/)
  @contents   = IO.read(source)
end

#to_change_notificationObject



37
38
39
# File 'lib/luca/component_definition.rb', line 37

def to_change_notification
  as_json(compile:true, include_contents:true)
end

#type_aliasObject



139
140
141
142
# File 'lib/luca/component_definition.rb', line 139

def type_alias
  classified = class_name && class_name.split('.').last
  classified && classified.underscore
end

#update(contents) ⇒ Object



31
32
33
34
35
# File 'lib/luca/component_definition.rb', line 31

def update contents
#  File.open(source,'w+') do |fh|
#    fh.puts(contents)
#  end
end

#valid?Boolean



116
117
118
# File 'lib/luca/component_definition.rb', line 116

def valid?
  !class_name.nil?
end

#view_based?Boolean



144
145
146
147
148
149
150
151
# File 'lib/luca/component_definition.rb', line 144

def view_based?
  extends && !(
    extends.match('.models.') || 
    extends.match('.collections.') || 
    extends.match(/Collection$/) || 
    extends.match(/Model$/)
    )
end