Permalink
Browse files

first pass at the browser, hardcoded path to the header file

  • Loading branch information...
1 parent 50a47d0 commit 83feaeca6f9804d58f140a7ae408affb8b00bda4 @mattetti committed Nov 15, 2011
@@ -14,6 +14,7 @@
2B0E2D411471E524000EF78A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B0E2D3F1471E524000EF78A /* MainMenu.xib */; };
2B0E2D441471E524000EF78A /* rb_main.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2B0E2D431471E524000EF78A /* rb_main.rb */; };
2B0E2D461471E524000EF78A /* AppDelegate.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2B0E2D451471E524000EF78A /* AppDelegate.rb */; };
+ 2B0E2D501471F4CB000EF78A /* omni.h in Resources */ = {isa = PBXBuildFile; fileRef = 2B0E2D4F1471F395000EF78A /* omni.h */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -30,13 +31,14 @@
2B0E2D2A1471E524000EF78A /* MacRubyScriptingBridgeBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacRubyScriptingBridgeBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; };
2B0E2D2E1471E524000EF78A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
2B0E2D301471E524000EF78A /* MacRuby.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MacRuby.framework; path = Library/Frameworks/MacRuby.framework; sourceTree = DEVELOPER_DIR; };
- 2B0E2D371471E524000EF78A /* MacRubyScriptingBridgeBrowser-Info.plist */ = {isa = PBXFileReference; path = "MacRubyScriptingBridgeBrowser-Info.plist"; sourceTree = "<group>"; };
+ 2B0E2D371471E524000EF78A /* MacRubyScriptingBridgeBrowser-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MacRubyScriptingBridgeBrowser-Info.plist"; sourceTree = "<group>"; };
2B0E2D391471E524000EF78A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
2B0E2D3B1471E524000EF78A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
- 2B0E2D3D1471E524000EF78A /* MacRubyScriptingBridgeBrowser-Prefix.pch */ = {isa = PBXFileReference; path = "MacRubyScriptingBridgeBrowser-Prefix.pch"; sourceTree = "<group>"; };
+ 2B0E2D3D1471E524000EF78A /* MacRubyScriptingBridgeBrowser-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MacRubyScriptingBridgeBrowser-Prefix.pch"; sourceTree = "<group>"; };
2B0E2D401471E524000EF78A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
2B0E2D431471E524000EF78A /* rb_main.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = rb_main.rb; sourceTree = "<group>"; };
2B0E2D451471E524000EF78A /* AppDelegate.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = AppDelegate.rb; sourceTree = "<group>"; };
+ 2B0E2D4F1471F395000EF78A /* omni.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = omni.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -103,6 +105,7 @@
2B0E2D3E1471E524000EF78A /* Resources */ = {
isa = PBXGroup;
children = (
+ 2B0E2D4F1471F395000EF78A /* omni.h */,
2B0E2D3F1471E524000EF78A /* MainMenu.xib */,
);
name = Resources;
@@ -186,6 +189,7 @@
files = (
2B0E2D3A1471E524000EF78A /* InfoPlist.strings in Resources */,
2B0E2D411471E524000EF78A /* MainMenu.xib in Resources */,
+ 2B0E2D501471F4CB000EF78A /* omni.h in Resources */,
2B0E2D441471E524000EF78A /* rb_main.rb in Resources */,
2B0E2D461471E524000EF78A /* AppDelegate.rb in Resources */,
);
@@ -7,9 +7,143 @@
#
class AppDelegate
- attr_accessor :window
+ attr_accessor :window, :outline, :documentation
+
def applicationDidFinishLaunching(a_notification)
- # Insert code here to initialize your application
+ @documentation = parse_objc_header
+ @outline.dataSource = self
+ @outline.doubleAction = "preview:"
+ end
+
+ def outlineView(view, numberOfChildrenOfItem: item)
+ obj = klass_for_item(item) || documentation
+ if obj && item
+ nbr_of_item_children(obj)
+ elsif obj
+ obj.size
+ else
+ 0
+ end
+ end
+
+ def outlineView(view, child: idx, ofItem: item)
+ if item.nil?
+ name = documentation[idx][0]
+ elsif
+ name = name_for_method_or_prop(item, idx)
+ end
+ name
+ end
+
+ def outlineView(view, isItemExpandable: item)
+ obj = object_for_item(item, false)
+ obj && obj.size > 0
+ end
+
+ def outlineView(view, objectValueForTableColumn: column, byItem: item)
+ item.description
+ end
+
+ # Parse the provided header file and return an object representing the parsed data.
+ # TODO: expose constants, capitalize class names and make the header selection dynamic
+ def parse_objc_header
+ file = File.join(NSBundle.mainBundle.resourcePath.fileSystemRepresentation, 'omni.h')
+ puts file
+ header = File.open(file)
+ doc = {}
+
+ File.foreach(header) do |line|
+ if line =~ /^@interface /
+ @current_class = line[/^@interface\s(.*)\s:/, 1]
+ next if @current_class.nil?
+ @current_class = @current_class.capitalize
+ elsif line =~ /^- /
+ doc[@current_class] ||= {}
+ doc[@current_class][:methods] ||= []
+ returned_class = line[/^- \((.*?)\)/, 1].gsub(' *', '')
+ selector = line[/^- \(.*?\)(.*);/, 1].strip
+ selector =~ /(.*?):/
+ method_name = $1 || selector
+ types = selector.scan(/\((.*?)\)/).flatten
+ selector_args = [method_name] + selector.scan(/\s(\w.*?):/).flatten
+ ruby_method_with_types = Hash[selector_args.zip(types)]
+ sa2 = selector_args.dup
+ method_signature = sa2.shift
+ if types.empty?
+ method_signature << "("
+ else
+ method_signature << "(param_1"
+ sa2.each_with_index do |karg, idx|
+ method_signature << ", "
+ method_signature << "#{karg}: param_#{idx+2}"
+ end
+ end
+ method_signature << ")"
+ comment = line[/\/\/(.*)/, 1]
+ comment = comment.strip unless comment.nil?
+ doc[@current_class][:methods] << {
+ :returned => returned_class,
+ :selector => selector,
+ :method_signature => selector_args,
+ :method_argument_types => types,
+ :method => method_signature,
+ :comment => comment}
+ elsif line =~ /^@property/
+ doc[@current_class] ||= {}
+ doc[@current_class][:properties] ||= []
+ property = line[/\s([a-z|\*|[0-9]]*?);/i, 1].gsub('*', '')
+ comment = line[/\/\/(.*)/, 1]
+ comment = comment.strip unless comment.nil?
+ doc[@current_class][:properties] << {:name => property, :comment => comment}
+ end
+ end
+ doc.delete_if{|node| node.nil?}.sort{|a,b| item_sort_value(a) <=> item_sort_value(b)}.to_a
+ end
+
+ def preview(sender)
+ if outline.selectedRow >= 0
+ puts "you clicked row: #{outline.selectedRow}"
+ end
+ end
+
+ def windowWillClose(sender); exit(1); end
+
+ private
+
+ def name_for_method_or_prop(item, idx)
+ doc = klass_for_item(item)
+ return nil unless doc
+ @sorted_list ||= {}
+ @sorted_list[doc[0]] ||= ((doc[1][:properties] || []) + (doc[1][:methods] || [])).compact.sort{|a,b| (a[:method] || a[:name]) <=> (b[:method] || b[:name])}
+ item_doc = @sorted_list[doc[0]][idx]
+ name = item_doc[:method] || item_doc[:name] if item_doc
+ name
+ end
+
+ def nbr_of_item_children(obj)
+ list = obj[1]
+ total = 0
+ return total unless list
+ meths = list[:methods]
+ props = list[:properties]
+ total += meths.size if meths
+ total += props.size if props
+ total
+ end
+
+ def item_sort_value(item)
+ val = item && item[0] ? item[0] : ""
+ val
+ end
+
+ def object_for_item(item, fallback=true)
+ obj = klass_for_item(item)
+ obj ||= documentation if fallback
+ obj
+ end
+
+ def klass_for_item(item)
+ documentation.find{|klass| klass != nil && klass[0] == item.description}
end
end
Oops, something went wrong.

0 comments on commit 83feaec

Please sign in to comment.