Ctags: Améliorations de l'analyseur Ruby

Créé le 1 juil. 2015  ·  32Commentaires  ·  Source: universal-ctags/ctags

Voici quelques améliorations qui, en fonction de la façon dont les fichiers Ruby sont analysés, pourraient être ajoutées à l'analyseur :

Constantes Camel-Case

class Foo
  THIS_IS_MY_CONSTANT = 3
end

Devrait créer des entrées pour la variable :

  • THIS_IS_MY_CONSTANT

méthodes attr_*

class Foo
  attr_accessor :bar
  attr_reader :baz
  attr_writer :qux
end

Devrait créer des entrées pour les méthodes :

  • bar
  • bar=
  • baz
  • qux=

Méthode des alias

class Foo
  def bar
  end

  alias_method :baz, :bar
end

Devrait créer des entrées pour les méthodes :

  • baz

Analyse de base des rails

Je ne pense pas que ce soit quelque chose sur quoi devenir fou, mais il y a des choses de base Rails-y auxquelles les gens s'attendraient.

class Foo < ActiveRecord::Base
  has_many :bars
  has_one :baz
  belongs_to :qux

  validates :buz
end

Devrait créer des entrées pour les propriétés/attributs :

  • bars
  • bars=
  • baz
  • baz=
  • qux
  • qux=
  • buz
  • buz=

J'espère que cela t'aides.

Parser buenhancement

Tous les 32 commentaires

Merci pour l'entrée.

Puis-je vous demander de convertir ce problème en cas de test ?
Je veux que ceux-ci soient signalés en tant que cas de test marqués "bugs connus (.b)".
Ainsi, les gens peuvent travailler pour les réparer.

(Le projet Universal ctags considère que les cas de test sont la sortie de première classe du projet.)

Voir docs/units.rst. Especailly à propos de *.b maker. Unités/variables-prototypes.cpp.b/.
Vous devrez peut-être créer une sortie idéale (expected.tags) à la main.

@masatake Je n'ai aucune idée de C mais je ferai de mon mieux. Il se peut que je doive simplement copier/coller certaines choses, puis vous demander à tous d'y apporter la touche finale. :le sourire:

Pour créer un cas de test, vous n'avez pas besoin de connaître C.
Par contre je ne connais pas Ruby donc j'ai besoin de votre aide.

ripper-tags est "un générateur de ctags rapide et précis pour le code source ruby ​​utilisant Ripper".

Peut-être qu'il serait logique d'utiliser les ripper-tags comme xcmd , plutôt que d'ajouter ces fonctionnalités à l'analyseur Ruby écrit en C ?

La suite de tests pour ripper-tags suggère qu'elle prend déjà en charge la plupart des fonctionnalités mentionnées par @jfelchner :

Je voudrais continuer à maintenir l'analyseur ruby ​​intégré. Cependant, je vais fournir le moyen de remplacer l'analyseur intégré par l'analyseur ruby ​​basé sur xcmd, ici ripper-tags. J'ai peur qu'il y ait des lacunes sur les lettres aimables entre deux analyseurs.

Quoi qu'il en soit, un PR pour ajouter des cas de test qui ne peuvent pas gérer l'analyseur intégré est vraiment bien venu.
Je traite les cas de test sont le résultat de première classe de ce projet. Les cas de test peuvent conduire au développement d'analyseurs.

@nelstrom J'ai essayé le ripper avec un succès limité. Il a raté toutes sortes de choses que universal-ctags a correctement attrapé. J'ai comparé le diff de la sortie du fichier de balises lors de sa génération sur Rails. Je pense qu'universal-ctags est vraiment proche d'obtenir toutes les informations possibles à partir des fichiers Ruby et j'aime ne pas avoir à installer une autre dépendance.

@nelstrom, je pense que cet éventreur a cependant une tonne de promesses. Parce qu'il peut en fait analyser le fichier Ruby pour l'intention plutôt que la syntaxe. Je pense que ça pourrait être assez génial. Je pense donc que universal-ctags devrait probablement lui permettre d'être utilisé pour analyser les fichiers Ruby.

@masatake Je n'ai pas oublié de vous faire parvenir ces cas de test, je suis juste super débordé en ce moment. Probablement le week-end prochain.

universal-ctags ne semble pas gérer ces cas, contrairement à ripper-tags :

  • alias
  • alias_method
  • reconnaître que les méthodes définies dans class << self sont des méthodes de classe, pas des méthodes d'instance
  • méthodes définies dans class_eval ou module_eval correctement étendues au module correspondant
  • définitions constantes
  • classes définies avec Class.new
  • classes définies avec Struct.new
  • modules définis avec Module.new
  • méthodes définies avec define_method
  • méthodes générées à partir de attr_accessor , attr_reader , attr_writer

Et ce ne sont que les cas que j'ai pu repérer dans les 3 minutes de tests occasionnels. Donc, vous voyez, je ne suis pas vraiment convaincu que les ripper-tags "ont raté toutes sortes de choses que les universal-ctags ont correctement attrapées". Si vous trouvez qu'une définition de méthode ou de classe n'est pas correctement reconnue avec les balises ripper, veuillez y signaler un problème. Merci!

Je suis :+1: pour améliorer les balises Ruby dans le projet universal-ctags, mais en raison de limitations techniques, il sera difficilement en mesure de prendre en charge toutes les constructions de métaprogrammation que Ripper peut reconnaître car c'est un véritable analyseur Ruby.

@mislav et c'est pourquoi j'ai dit :

Je pense que cet éventreur a une tonne de promesses cependant. Parce qu'il peut en fait analyser le fichier Ruby pour l'intention plutôt que la syntaxe.

:le sourire:

Mais il a manqué des choses. Quelques éléments d'un point de vue linguistique, mais le plus souvent, le fichier de balises qu'il a généré n'avait pas presque tous les champs et options qu'un fichier généré standard ctags .

Je n'essaie pas de frapper votre bijou @mislav. Je suis un grand fan de ce que ripper essaie d'accomplir. Personnellement, je pense qu'écrire un analyseur de balises en utilisant quelque chose qui peut analyser la langue elle-même plutôt que simplement le texte est la meilleure approche. Mais nous savons tous que l'open source est un travail difficile et parfois ingrat. Les projets vont et viennent. Je suis sûr qu'il y a eu des projets pour lesquels vous _souhaitez_ avoir du temps, mais ne le faites pas. Il ya seulement autant d'heures dans la journée.

Donc tout ce que je dis, c'est que si universal-ctags peut faire 90% du chemin, que quelqu'un puisse simplement le ramasser et partir (sans avoir besoin de savoir que ripper est une chose) , puis passez à ripper lorsque cela est approprié, alors cela aide à la fois le nouveau développeur qui vient juste d'accéder à un système de balisage pour la première fois, et aussi à l'avenir universal-ctags d'avoir à dépendre d'un projet qui pourrait ou non exister à l'avenir.

Encore une fois, je pense que l'idée derrière ripper est géniale. Je pense juste qu'il doit également y avoir une solution intégrée dans universal-ctags .

Je n'essaie pas de frapper votre bijou @mislav.

Je comprends. Et ce n'est pas ma bibliothèque ; J'ai juste travaillé dessus pour apporter ces améliorations.

Mais dans un fil qui consiste à comparer différentes implémentations de ctags d'un langage, je pense qu'il est plus constructif de souligner spécifiquement quelle construction une implémentation ne parvient pas à gérer au lieu de dire "il a raté toutes sortes de choses". À tout le moins, j'apprécierais les rapports de bogues.

Ce serait bien si vous pouviez fournir l'exemple de code Ruby qui n'est pas géré correctement ainsi que la liste des balises attendues. Idéalement, cela viendrait comme une demande d'extraction ajoutant de nouvelles unités de test, mais si cela n'est pas possible tant que les exemples sont toujours fournis, l'un de nous pourrait créer les unités de test et essayer d'améliorer l'analyseur existant.

@mislav cool. :+1: :heart: J'aurais certainement ajouté des problèmes, mais le projet n'a eu aucune activité depuis plus d'un an et demi et a des problèmes et des relations publiques qui sont plus anciens que cela, donc j'ai l'impression qu'il a été abandonné et c'est aussi pourquoi je ne suis pas entré dans beaucoup de détails sur ce qu'il n'a pas fait correctement. Je suis content qu'il soit toujours maintenu. Comme je l'ai dit, je pense qu'un analyseur est de loin la meilleure solution. :le sourire:

@vhda c'est sur ma liste ! :)

Je viens de signaler les bogues suivants de l'analyseur Ruby : #452 #453 #454 #455

Ils ne sont pas liés aux améliorations proposées ci-dessus, mais ils étaient le résultat de la génération de ctags sur le code source de Rails et de sa comparaison avec la sortie des ripper-tags. @jfelchner : ripper-tags gère assez bien le code source de Rails, mais j'ai trouvé ce que vous vouliez dire concernant les définitions de balises supprimées. Il ignore actuellement les définitions de méthode à l'intérieur d'autres méthodes :

def foo
  def obj.bar() end # ripper-tags ignores this
end

ainsi que dans les blocs de type DSL

included do
  def foo() end # ripper-tags ignores this
end

ainsi que lors de la définition de méthodes pour les classes/modules anonymes :

Class.new do
  def foo() end # ripper-tags ignores this
end

Je vais prendre ces problèmes avec le projet ripper-tags et ne dérangerai plus ce fil à ce sujet ; il suffit d'envoyer un avertissement à tous ceux qui souhaitent essayer les deux analyseurs.

Je suis :+1: sur les améliorations proposées à l'origine par l'OP ici, à commencer par la reconnaissance des définitions constantes, mais je pense que la résolution des bogues actuels de l'analyseur Ruby est une priorité plus importante.

Merci pour votre aide @mislav. Nous examinerons ces problèmes dès que possible.

[yamato@x201]~/var/ctags-github% ripper-tags a.rb --list-kinds=Ruby
c  classes
f  methods
m  modules
F  singleton methods
C  constants
a  aliases
[yamato@x201]~/var/ctags-github% ./ctags --list-kinds=Ruby        
c  classes
f  methods
m  modules
F  singleton methods
d  describes
C  contexts

les contextes et les constantes sont en conflit. Évidemment, les constantes sont plus importantes.
Doit-on distinguer décrire et contexte ? Je pense que nous ne devrions pas.
Ruby est si populaire que nous aimerions continuer à maintenir l'analyseur syntaxique intégré.
Cependant, un analyseur alternatif basé sur xcmd peut être utile. Pour le préparer, ctags doit
traduire F dans la sortie du ripper-tag en !.

Une question est une variable $GLOBAL.

[yamato@x201]~/var/ctags-github% cat a.rb
$global = "A"
CONSTANT = "B"
describe = "X"
context = "Y"
[yamato@x201]~/var/ctags-github% ripper-tags -f - ./a.rb
!_TAG_FILE_FORMAT   2   /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED   1   /0=unsorted, 1=sorted, 2=foldcase/
CONSTANT    ./a.rb  /^CONSTANT = "B"$/;"    C   class:
[yamato@x201]~/var/ctags-github% ./ctags -f - ./a.rb
= "X"   ./a.rb  /^describe = "X"$/;"    d
= "Y"   ./a.rb  /^context = "Y"$/;" C   describe:= "X"

Je me demande pourquoi les gens ne veulent pas marquer les variables globales.

Une suggestion avec un cas de test est la bienvenue.

les contextes et les constantes sont en conflit. Évidemment, les constantes sont plus importantes.

Oui, je vous ai suggéré de supprimer le support (cassé) des contextes et décrit ici https://github.com/universal-ctags/ctags/issues/453#issuecomment -124327142

Cependant, un analyseur alternatif basé sur xcmd peut être utile. Pour le préparer, ctags doit traduire F dans la sortie du ripper-tag en !.

Que vouliez-vous dire exactement par cette dernière phrase ? Les ripper-tags ne sont-ils pas déjà compatibles avec xcmd ?

Je me demande pourquoi les gens ne veulent pas marquer les variables globales.

Nous ne les utilisons pas beaucoup en Ruby. De plus, contrairement à une constante, une variable globale peut être réaffectée facilement. Générer des ctags pour les variables globales impliquerait de générer une balise pour chacune de ses affectations. Cela peut être très bruyant et pas très utile. Je ne pense pas que nous ayons besoin de suivre les variables globales.

@mislav , merci d'avoir expliqué les variables globales dans Ruby. Je comprends la situation.

Que vouliez-vous dire exactement par cette dernière phrase ? Les ripper-tags ne sont-ils pas déjà compatibles avec xcmd ?

Je réfléchis à ce qui est nécessaire pour utiliser les ripper-tags via xcmd.
La lettre F est réservée à un fichier d'entrée lui-même dans ctags :

[yamato@x201]~/var/ctags-github% ./ctags --extra=+f main/main.h 
./ctags --extra=+f main/main.h 
[yamato@x201]~/var/ctags-github% grep ' F$' tags 
main.h  main/main.h 1;" F

Cela entre en conflit avec les "méthodes singleton F" des ripper-tags.
l'analyseur ruby ​​utilise également 'F' pour le même type.
Cependant ctags main traduit F en !.

% ./ctags --extra=+f a.rb
% cat tags
...
a.rb    a.rb    1;" !

Ctags peut le traduire car l'analyseur Ruby est intégré.
Nous devons étendre le code de traduction (saveur) pouvant être utilisé dans xcmd.

Devrions-nous alors passer à l'utilisation de ! pour les méthodes singleton ? ! n'est pas un personnage très intuitif pour marquer cela. Quel est le support de l'éditeur de texte pour ces lettres qui indiquent la balise « genre » ?

Alors faut-il passer à l'utilisation ! pour les méthodes singleton ?

Je suis désolé, je suis confus. La balise a pour le fichier d'entrée est injectée par ctags lui-même même si xcmd est utilisé comme analyseur.
Aucune traduction n'est donc nécessaire.

@mislav , voulez-vous essayer l'analyseur ripper-tags+xcmd ?

J'ai fait une nouvelle version de ripper-tags que j'espérais être compatible avec xcmd mais l'intégration ne semble pas fonctionner parfaitement.

$ ctags --version
Universal Ctags Development, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Jul 21 2015, 12:41:18
  Addresses: <[email protected]>, https://github.com/universal-ctags/ctags
  Optional compiled features: +wildcards, +regex, +debug, +option-directory, +coproc

$ ctags --xcmd-ruby=ripper-tags -R -f -

La sortie de la commande ci-dessus est constituée de balises Ruby générées comme le feraient normalement des balises universelles. Cependant, je m'attendais à voir dans la sortie des balises que seules les balises ripper auraient reconnues, telles que des définitions constantes. En effet, lorsque je lance ripper-tags -R -f - manuellement, je vois ces définitions.

Donc, il ne semble pas que ctags utilise ripper-tags pour le langage Ruby ici. Des pointeurs sur la façon de déboguer ?

$ ripper-tags --list-kind=ruby
c  classes
f  methods
m  modules
F  singleton methods
C  constants
a  aliases

Voici ce que j'ai avec --verbose :

Reading initial options from command line
  Option: --xcmd-ruby=ripper-tags
loading path kinds of Ruby from [ripper-tags --list-kinds=Ruby]
        status: 32512
xcmd: the ripper-tags backend is not available

Oh, je suis surpris que tu sois un développeur de ripper-tags.
OK je prépare un prototype. S'il te plaît attend un moment.

https://github.com/masatake/ctags/tree/ripper-tags-xcmd

Pourriez-vous essayer cette branche ?

%  ./ctags --libexec-dir=./libexec --data-dir=./data --options=ripper-tags --list-kinds=ripper-ruby
c  classes 
f  methods 
m  modules 
F  singleton methods 
C  constants 
a  aliases 
% cat a.rb
cat a.rb
$global = "A"
CONSTANT = "B"
describe = "X"
context = "Y"
%  ./ctags --libexec-dir=./libexec --data-dir=./data --options=ripper-tags  -o - ./a.rb
CONSTANT    ./a.rb  /^CONSTANT = "B"$/;"    C   class:
%  ./ctags -o - ./a.rb
= "X"   ./a.rb  /^describe = "X"$/;"    d
= "Y"   ./a.rb  /^context = "Y"$/;" C   describe:= "X"

Pourriez-vous essayer cette branche ?

Votre branche travaille pour moi. Une idée de pourquoi cela n'a pas fonctionné avec --xcmd-ruby=ripper-tags ?

Ne serait-il pas possible d'utiliser --xcmd-ruby=ripper-tags sans définir de pilote soit dans ctags core, soit dans ~/.ctags.d/drivers/ripper-tags ?

Ne devrait-il pas être possible d'utiliser --xcmd-ruby=ripper-tags sans définir de pilote dans ctags core ou dans ~/.ctags.d/drivers/ripper-tags ?

Comme vous l'avez écrit, l'interface entre ctags et le backend xcmd peut être un peu redondante.
Je l'ai fait parce que je n'étais pas sûr de la façon dont l'interface entre les deux devrait être.
Je ne suis toujours pas sûr. Je mémorise ce que vous avez écrit ici comme une suggestion importante. Merci.
Autant que je me souvienne, vous êtes la première personne à essayer volontairement la fonctionnalité xcmd.

C'est bien que ctags utilise des ripper-tags au lieu de l'analyseur ruby ​​intégré lorsque ripper-tags est disponible là où ctags s'exécute.

--langdef=ripper_ruby
--altname-rupper_ruby=ruby
`ripper_ruby+ripper_ruby-ruby

(Je me souviens juste que '-' ne peut pas être utilisé dans le nom lang.)
--altname-<LANG>= est évidemment utile.
--languages=? est trop compliqué.

Lorsque --fields=+l est donné, ctags ajoute un champ de langue. par exemple

timeStamp       main/main.c     /^#undef timeStamp$/;"  d       language:C      file:

Actuellement % ./ctags --fields=+l --libexec-dir=./libexec --data-dir=./data --options=ripper-tags -o - ./a.rb peut générer :

CONSTANT    ./a.rb  /^CONSTANT = "B"$/;"    C   class:  language:ripper_ruby

Les utilisateurs peuvent vouloir

CONSTANT    ./a.rb  /^CONSTANT = "B"$/;"    C   class:  language:ruby

--altname-rupper_ruby=ruby est à cet effet.

@mislav , Puis-je vous demander d'ajouter les pseudo-tags suivants aux ripper-tags ?

  • !_TAG_PROGRAM_AUTHOR
  • !_TAG_PROGRAM_NAME
  • !_TAG_PROGRAM_URL
  • !_TAG_PROGRAM_VERSION

Ils ne sont pas obligatoires, mais ctags utilise ces balises renvoyées par le backend xcmd.

Après la sortie de la version 1.0.0., j'ajouterai plus de fonctionnalités à la fonction xcmd pour utiliser les ripper-tags.

J'utilise des ctags depuis un certain temps maintenant et je viens honnêtement de lancer une nouvelle regex personnalisée dans mon .ctags pour gérer divers cas extrêmes que j'ai trouvés ne pas fonctionner avec les ctags universels. (Certaines syntaxes Ruby Edge, associations Rails, portées, etc.).

Je n'avais jamais vu d'étiquettes d'éventreur auparavant ; J'aime _vraiment_ l'idée que ce projet l'utilise :+1: :+1:

Cette page vous a été utile?
0 / 5 - 0 notes