#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Tue, 12 Apr 2016 15:00:48 +0200
changeset 16280 b4b9c4079ee8
parent 16279 f41a5b9c0ca4
child 16281 cbc89f67739a
#FEATURE by cg class: Tools::TagList added:8 methods changed:5 methods hacky kludgy objc tags
Tools__TagList.st
--- a/Tools__TagList.st	Mon Apr 11 11:23:10 2016 +0200
+++ b/Tools__TagList.st	Tue Apr 12 15:00:48 2016 +0200
@@ -65,6 +65,7 @@
     TagsSuffixes at:#'text/asm'                 put:#( 's' 'asm' ).
     TagsSuffixes at:#'text/c'                   put:#( 'c' 'h' 'ci' 'hi' 'sc' 'sth').
     TagsSuffixes at:#'text/cpp'                 put:#( 'cc' 'cpp' 'cxx' 'c++' 'hxx' 'hpp' 'h++').
+    TagsSuffixes at:#'text/x-objcsrc'           put:#( 'm').
     TagsSuffixes at:#'text/eiffel'              put:#( 'e' 'eif' ).
     TagsSuffixes at:#'text/fortran'             put:#( 'f' 'for' 'ftn' 'f77' 'f90' ).
     TagsSuffixes at:#'text/html'                put:#( 'htm' 'html').
@@ -203,6 +204,12 @@
     ^ self tagsSuffixes at:#'text/make'
 !
 
+objcSuffixes
+    "returns a list of supported c-suffixes"
+
+    ^ self tagsSuffixes at:#'text/x-objcsrc'
+!
+
 ozSuffixes
     "returns a list of supported oz-suffixes
     "
@@ -361,6 +368,10 @@
     ^ false
 !
 
+isObjcSuffix:suffix
+    ^ self isSuffix:suffix in:self objcSuffixes
+!
+
 isOzSuffix:suffix
     ^ self isSuffix:suffix in:self ozSuffixes
 !
@@ -1103,6 +1114,22 @@
     "Created: / 21-08-2012 / 21:01:38 / cg"
 !
 
+hideObjcClasses
+    ^ self flagNamed:#hideObjcClasses 
+!
+
+hideObjcClasses:aBoolean
+    self flagNamed:#hideObjcClasses put:aBoolean.
+!
+
+hideObjcMethods
+    ^ self flagNamed:#hideObjcMethods 
+!
+
+hideObjcMethods:aBoolean
+    self flagNamed:#hideObjcMethods put:aBoolean.
+!
+
 hideOzClasses
     ^ self flagNamed:#hideOzClasses 
 !
@@ -1708,7 +1735,8 @@
      When first called, looks for ctags (both a private and the system-supplied),
      and tries to see what version that is. I prefer exuberant ctags version"
 
-    |lcSuffix shellCommand isCSuffix isCPlusPlusSuffix isJavaSuffix isEiffelSuffix isFortranSuffix
+    |lcSuffix shellCommand isCSuffix isCPlusPlusSuffix isObjcSuffix
+     isJavaSuffix isEiffelSuffix isFortranSuffix
      isTCLSuffix isRubySuffix isPythonSuffix isPhpSuffix isJavaScriptSuffix
      showOnly response suff fn langValue langOption moreOptions|
 
@@ -1799,6 +1827,7 @@
         ].
     ].
     isCPlusPlusSuffix := self class isCPlusPlusSuffix:lcSuffix.
+    isObjcSuffix := self class isObjcSuffix:lcSuffix.
 
     (shellCommand notNil and:[(ctagsIsExCtags ? false)]) ifTrue:[
         isJavaSuffix := self class isJavaSuffix:lcSuffix.
@@ -1806,7 +1835,8 @@
         isFortranSuffix := self class isFortranSuffix:lcSuffix.
 
         "/ ex_ctags supports c, c++, java, fortran and a few others
-        (isCSuffix or:[isCPlusPlusSuffix or:[isJavaSuffix or:[isEiffelSuffix or:[isFortranSuffix]]]]) ifFalse:[
+        (isCSuffix or:[isCPlusPlusSuffix or:[isObjcSuffix
+        or:[isJavaSuffix or:[isEiffelSuffix or:[isFortranSuffix]]]]]) ifFalse:[
             (ctagsIsExCtags5x ? false) ifFalse:[
                 ^ nil
             ].
@@ -1830,7 +1860,7 @@
 "/            shellCommand := shellCommand, ' -f - --file-scope=yes'.
         shellCommand := shellCommand, ' -f - --file-scope=yes --excmd=number'.
 
-        (isCSuffix or:[isCPlusPlusSuffix]) ifTrue:[
+        (isCSuffix or:[isCPlusPlusSuffix or:[isObjcSuffix]]) ifTrue:[
             isCPlusPlusSuffix 
                 ifTrue:[ langValue := 'c++']
                 ifFalse:[ langValue := 'c'].
@@ -2238,7 +2268,19 @@
         shellCmd notNil ifTrue:[
             tagTypesPresent := false.     "/ will be set again, when ctags command provides types
             list := ((self getTagListFromFile:aFile usingCommand:shellCmd mode:nil in:aTempDirectory) ? #()) asOrderedCollection.
-            list addAll:(self getAdditionalCTagsInFile:aFile withList:list)
+            "/ kludge: I am better in getting cases/switches/labels
+            list addAll:(self getAdditionalCTagsInFile:aFile withList:list).
+            "/ another kludge - add in my own scanned objc tags
+            (self class isObjcSuffix:aFile suffix) ifTrue:[
+                |objcTags|
+                
+                objcTags := self objcTagsInFile:aFile.
+                list 
+                    removeAllSuchThat:[:ctag | 
+                        objcTags contains:[:objctag | objctag lineNumber = ctag lineNumber]
+                    ].
+                list addAll:objcTags.    
+            ].    
         ].
     ].
 
@@ -3063,6 +3105,11 @@
         "/ lisp tags - simulated
         ^ self lispTagsInFile:pathName
     ].
+    ((self class isObjcSuffix:suffix)
+    or:[(mime ? '') includesString:'objcsrc']) ifTrue:[
+        "/ objc tags - simulated
+        ^ self objcTagsInFile:pathName
+    ].
     ((self class isOzSuffix:suffix)
     or:[(mime ? '') includesString:'oz']) ifTrue:[
         "/ oz tags - simulated
@@ -3634,6 +3681,71 @@
               ]
 !
 
+objcTagFromLine:line lineNr:lineNr
+    "objc tags:
+     naive, q&d scan for lines starting with some common patterns"
+
+    |l nm lineStream kwLen type hideHolder skipType|
+
+    l := line withoutSeparators.
+    skipType := false.
+    
+    (l startsWith:'@interface') ifTrue:[
+        kwLen := '@interface' size.
+        type := Tag::TInterface.
+        hideHolder := self hideObjcClasses.
+    ].
+    (l startsWith:'@implementation') ifTrue:[
+        kwLen := '@implementation' size.
+        type := Tag::TClass.
+        hideHolder := self hideObjcClasses.
+    ].
+    (l startsWith:'@property') ifTrue:[
+        kwLen := '@property' size.
+        type := Tag::TMacro.
+    ].
+    (l startsWithAnyOf:'+-') ifTrue:[
+        kwLen := 1.
+        type := Tag::TMethod.
+        hideHolder := self hideObjcMethods.
+        skipType := true.
+    ].
+    hideHolder value ~~ true ifTrue:[
+        kwLen notNil ifTrue:[
+            lineStream := l readStream.
+            lineStream skip:kwLen; skipSeparators.
+            skipType ifTrue:[
+                lineStream peek == $( ifTrue:[
+                    lineStream next. lineStream skipThrough:$).
+                    lineStream skipSeparators.
+                ].    
+            ].
+            
+            nm := lineStream upToElementForWhich:[:ch | (ch isLetterOrDigit or:['_' includes:ch]) not].
+            (nm notEmpty and:[nm first isLetterOrUnderline]) ifTrue:[    
+                ^ type 
+                                label:nm 
+                                pattern:nil
+                                type:nil
+                                lineNumber:lineNr.
+            ]
+        ].
+    ].
+    
+    ^ nil
+!
+
+objcTagsInFile:aFilePath
+    "objc tags:
+     naive, q&d scan for lines starting with some wellknown patterns"
+
+    ^ self
+        linewiseNaiveTagsInFile:aFilePath 
+        using:[:line :lineNr |
+                self objcTagFromLine:line lineNr:lineNr
+              ]
+!
+
 ozTagFromLine:line lineNr:lineNr
     "oz tags:
      naive, q&d scan for lines starting with: