4

J'ai un tagger (sous-classe de ITagger) et j'essaie d'appeler GetClassificationSpans pour pouvoir utiliser les classifications pour trouver des commentaires à mettre en forme en utilisant des tags. Cela a fonctionné dans Visual Studio 2013, mais maintenant, lors de son exécution dans Visual Studio 2015, GetClassificationSpans retourne toujours une liste vide - même lorsque j'ai examiné l'étendue dans le débogueur et qu'il passe définitivement un span avec un commentaire dedans.GetClassificationSpans dans Visual Studio 2015 ne renvoie rien

Quelqu'un sait-il ce qui pourrait avoir changé en 2015 en ce qui concerne l'appel GetClassificationSpans?

BTW: Je reçois le classificateur en important le IClassifierAggregatorService dans mon fournisseur de tagger (sous-classe de ITaggerProvider) et en passant le long du constructeur du tagger:

[import] 
IClassifierAggregatorService aggregator; 

Puis-je utiliser l'appel suivant le tagger sur l'aggrégateur que je suis arrivé du fournisseur:

IList<ClassificationSpan> lstClassifiers = aggregator.GetClassifier(span.Snapshot.TextBuffer).GetClassificationSpans(span); 

Et, comme je l'ai dit, la liste des lstClassifiers est toujours vide. Le même code a été trouvé dans VS2013. Je n'arrive pas à trouver quoi que ce soit sur le net qui mentionne des changements dans VS2015 qui pourraient en être la cause.

Merci,

Répondre

1

Bien. Après avoir essayé différentes choses, on dirait qu'il a plusieurs problèmes:

  1. ordre d'exécution doit avoir changé de sorte que les classifications ne semblent pas être mis en place avant l'endroit où je l'appelais GetClassificationSpans avant. (Dans le constructeur d'un tagger de niveau buffer [plutôt que dans un tagger de niveau view].) J'appelle maintenant GetCLassificationSpans uniquement lors d'un traitement de BufferChanged/LayoutChanged. (Seul problème que j'ai maintenant est que je ne semble pas obtenir un événement BufferChanged lorsque le fichier est ouvert.Help, il ne devrait pas être trop difficile de contourner cela.)
  2. Cela semble fonctionner mieux si j'utilise la référence du tampon est passée dans le fournisseur, une référence à IClassifier y est ajoutée et transmise à mon étiqueteur à la place de l'agrégateur (et j'ai donc arrêté d'utiliser la référence du tampon dans l'intervalle d'instantané).
  3. J'ai de meilleurs résultats en mettant à jour mes références à la v14 des DLL du SDK à partir des références v12 que j'utilisais auparavant.

Espérons que cela aide tous ceux qui rencontrent le même problème.

+0

Le déplacement entre les versions des DLL SDK ne devrait pas vraiment avoir d'effet - vous appelez toujours dans le même code une fois que vous exécutez réellement dans Visual Studio. –

0

Ainsi, en général, l'API ITagger n'impose pas qu'un tagueur renvoie les informations «réelles». Au lieu de cela, il s'agit d'une API qui renvoie «toutes les informations que vous aviez à ce moment-là». Si les tampons qui vous causent des problèmes sont des buffers C# ou VB, c'est parce que dans VS2015 nous avons tout déplacé dans Roslyn pour être asynchrone, donc un appel à GetClassificationSpans/GetTags pourrait ne rien retourner tant que nous n'aurons pas recalculé les données. Il y a une nouvelle API, IAccurateTagger, qui permet de demander que les tagueurs donnent de "vraies" données, bien que ce ne soit pas quelque chose que vous voulez exécuter dans les changements de tampon de texte puisque vous allez tuer les performances. Si vous essayez de trouver des commentaires dans VS2015 et que les fichiers qui vous déclenchent sont des tampons C# ou VB, il est préférable d'appeler les API Roslyn qui vous donnent les données d'arbre de syntaxe directe dont vous avez besoin. S'il s'agit d'un type de tampon différent, il vaut mieux appeler IAccurateTagger, mais essayez de le faire aussi soigneusement que possible en raison des conséquences sur les performances.

(De plus, si vous essayez de construire une extension qui se formate automatiquement au fur et à mesure que vous tapez, l'utilisation des tagueurs de classification vous donnera d'autres maux de tête. tags obsolètes si vous l'avez appelé lors d'un changement de balises.)

2

J'ai rencontré le même problème, mais dans un contexte différent. De mon googling, on dirait qu'ils ont changé les classificateurs pour qu'ils soient paresseusement initialisés ... et je suppose que GetClassificationSpans() ne les initialisera pas forcément. MSFT considère toujours cela comme un bug, donc vous pourriez vouloir voter pour le problème on VS Connect.

Une solution de contournement potentielle (comme suggéré par MSFT) consiste à passer à l'aide de TagAggregator au lieu de IClassifier. Ainsi, au lieu de:

var service = container.GetService<IClassifierAggregatorService>(); 
var classifier = service.GetClassifier(textView.TextBuffer); 
var spans = classifier.GetClassificationSpans(new SnapshotSpan(...)); 

Vous pouvez écrire à la place quelque chose comme ceci:

var service = container.GetService<IViewTagAggregatorFactoryService>(); 
var aggregator = service.CreateTagAggregator<IClassificationTag>(textView); 
var tags = aggregator.GetTags(new SnapshotSpan(...))); 

Ceci retourne une liste de IMappingTagSpan<IClassificationTag> au lieu d'une liste de ClassificationSpan, donc la façon dont vous allez travailler avec eux est légèrement différent. Mais les données sous-jacentes semblent être principalement le même --- c'est-à-dire que vous pouvez obtenir une classification et une étendue pour chaque élément lexical. Il y a quelques différences subtiles (voir la description sur VS Connect), mais les résultats étaient assez bons pour mon application.