Achèvement membre Intellisense (managed de package)
L'achèvement membre Intellisense est une info-bulle qui affiche une liste de membres possibles d'une portée précise tels qu'une classe, une structure, une énumération, ou un espace de noms. Par exemple, en c#, si l'utilisateur entre « this » suivi d'un point, une liste de tous les membres de la classe ou de la structure à la portée actuelle est affichés dans une liste de laquelle l'utilisateur peut sélectionner.
Managed package (MPF) fournit la prise en charge de l'info-bulle et de gérer la liste de l'info-bulle ; il suffit coopération de l'analyseur pour fournir les données qui figurent dans la liste.
Fonctionnement
Voici les deux façons d'une liste des membres est affichée à l'aide de les classes de MPF :
Positionnement le signe insertion sur un identificateur ou après un caractère et sélectionner membres d'achèvement Liste des membres le menu pour IntelliSense .
Le scanner d' IScanner détecte un caractère membre d'achèvement et définit un déclencheur jeton d' MemberSelect pour ce caractère.
Un caractère membre d'achèvement indique qu'un membre d'une classe, d'une structure, ou d'une énumération doit suivre. Par exemple, en c# ou Visual Basic le caractère membre d'achèvement est ., alors que dans C++ le caractère est . ou ->. La valeur de déclencheur est définie lorsque le membre sélectionnez le caractère est analysé.
L'ordre de La liste des membres Intellisense
L'ordre d' SHOWMEMBERLIST initialise un appel à la méthode d' Completion sur la classe d' Source et la méthode d' Completion , à son tour, les appels l'analyseur de méthode d' ParseSource avec la raison de l'analyse d' DisplayMemberList.
L'analyseur détermine le contexte de la position actuelle ainsi que le jeton sous ou immédiatement avant la position actuelle. En fonction de ce jeton, une liste de déclarations est présentée. Par exemple, en c#, si vous positionnez le signe insertion sur un membre de classe et sélectionnez Liste des membres, vous obtenez une liste de tous les membres de la classe. Si vous positionnez le signe insertion une fois qu'un point suivant une variable objet, vous obtenez une liste de tous les membres de la classe que l'objet représente. Notez que si le signe insertion est positionné sur un membre lorsque la liste des membres est affichée, sélectionner un membre de la liste remplace le membre sur laquelle figure le signe insertion à celui de la liste.
Le déclencheur de jeton
Le déclencheur d' MemberSelect initialise un appel à la méthode d' Completion sur la classe d' Source et la méthode d' Completion , à son tour, les appels l'analyseur avec la raison de l'analyse d' MemberSelect (si le déclencheur symbolique comprenait également la balise d' MatchBraces , la raison d'analyser est MemberSelectAndHighlightBraces qui associe la sélection de membre et les accolades mise en surbrillance).
L'analyseur détermine le contexte de la position actuelle ainsi que ce qui a été tapé avant le membre sélectionnez le caractère. À partir de ces informations, l'analyseur crée une liste de tous les membres de la portée demandée. Cette liste des déclarations est stockée dans l'objet d' AuthoringScope qui est retourné par la méthode d' ParseSource . Si les déclarations sont retournées, l'info-bulle membre d'achèvement est affichée. l'info-bulle est gérée par une instance de la classe d' CompletionSet .
Activer la prise en charge de l'achèvement membre
Vous devez avoir l'entrée du Registre d' CodeSense la valeur 1 pour prendre en charge toute opération Intellisense. Cette entrée du Registre peut être définie avec un paramètre nommé passé à l'attribut d'utilisateur d' ProvideLanguageServiceAttribute associé au package de langage. Les classes de service de langage lisent la valeur de cette entrée du Registre de la propriété d' EnableCodeSense sur la classe d' LanguagePreferences .
Si votre scanner retourne le déclencheur de jeton d' MemberSelect, et votre analyseur retourne une liste de déclarations, la liste de saisie semi-automatique membre s'affiche.
Achèvement de membre de prise en charge dans le scanner
Le scanner doit être en mesure de détecter un caractère membre d'achèvement et définir le déclencheur de jeton d' MemberSelect lorsque ce caractère est analysé.
Exemple
Voici un exemple simplifié pour détecter le caractère membre d'achèvement et de définir la balise appropriée d' TokenTriggers . Cet exemple est dans des fins de illustration uniquement. Elle suppose que votre scanner contient une méthode GetNextToken qui identifie et retourne des jetons d'une ligne de texte. L'exemple de code définit simplement le déclencheur chaque fois qu'il constate le bon type de caractère.
using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio.TextManager.Interop;
namespace TestLanguagePackage
{
public class TestScanner : IScanner
{
private Lexer lex;
private const char memberSelectChar = '.';
public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo,
ref int state)
{
bool foundToken = false
string token = lex.GetNextToken();
if (token != null)
{
foundToken = true;
char c = token[0];
if (c == memberSelectChar)
{
tokenInfo.Trigger |= TokenTriggers.MemberSelect;
}
}
return foundToken;
}
}
}
Achèvement de membre de prise en charge de l'analyseur
Pour conclusion membre, la classe d' Source appelle la méthode d' GetDeclarations . Vous devez implémenter la liste dans une classe dérivée de la classe d' Declarations . Consultez la classe d' Declarations pour plus d'informations sur les méthodes que vous devez implémenter.
L'analyseur est appelé avec MemberSelect ou MemberSelectAndHighlightBraces lorsqu'un membre sélectionnez caractère est tapé. L'emplacement donné dans l'objet d' ParseRequest est juste après le membre sélectionnez le caractère. L'analyseur doit collecter les noms de tous les membres qui peuvent apparaître dans une liste de membres à ce point particulier dans le code source. L'analyseur doit analyser la ligne en cours pour déterminer la portée qu'il souhaite associé au membre sélectionnez le caractère.
Cette portée est basé sur le type de l'identificateur avant le membre sélectionnez le caractère. Par exemple, en c#, selon la variable membre languageService qui a un type d' LanguageService, en tapant le languageService. produit une liste de tous les membres de la classe d' LanguageService . Également en c#, tapant ce qui suit. produit une liste de tous les membres de la classe dans la portée actuelle.
Exemple
L'exemple suivant illustre une manière de remplir une liste d' Declarations . ce code suppose que l'analyseur construit une déclaration et l'ajoute à la liste en appelant une méthode d' AddDeclaration sur la classe d' TestAuthoringScope .
using System.Collections;
using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio.TextManager.Interop;
namespace TestLanguagePackage
{
internal class TestDeclaration
{
public string Name; // Name of declaration
public int TypeImageIndex; // Glyph index
public string Description; // Description of declaration
public TestDeclaration(string name, int typeImageIndex, string description)
{
this.Name = name;
this.TypeImageIndex = typeImageIndex;
this.Description = description;
}
}
//===================================================
internal class TestDeclarations : Declarations
{
private ArrayList declarations;
public TestDeclarations()
: base()
{
declarations = new ArrayList();
}
public void AddDeclaration(TestDeclaration declaration)
{
declarations.Add(declaration);
}
//////////////////////////////////////////////////////////////////////
// Declarations of class methods that must be implemented.
public override int GetCount()
{
// Return the number of declarations to show.
return declarations.Count;
}
public override string GetDescription(int index)
{
// Return the description of the specified item.
string description = "";
if (index >= 0 && index < declarations.Count)
{
description = ((TestDeclaration)declarations[index]).Description;
}
return description;
}
public override string GetDisplayText(int index)
{
// Determine what is displayed in the tool tip list.
string text = null;
if (index >= 0 && index < declarations.Count)
{
text = ((TestDeclaration)declarations[index]).Name;
}
return text;
}
public override int GetGlyph(int index)
{
// Return index of image to display next to the display text.
int imageIndex = -1;
if (index >= 0 && index < declarations.Count)
{
imageIndex = ((TestDeclaration)declarations[index]).TypeImageIndex;
}
return imageIndex;
}
public override string GetName(int index)
{
string name = null;
if (index >= 0 && index < declarations.Count)
{
name = ((TestDeclaration)declarations[index]).Name;
}
return name;
}
}
//===================================================
public class TestAuthoringScope : AuthoringScope
{
private TestDeclarations declarationsList;
public void AddDeclaration(TestDeclaration declaration)
{
if (declaration != null)
{
if (declarationsList == null)
{
declarationsList = new TestDeclarations();
}
declarationsList.AddDeclaration(declaration);
}
}
public override Declarations GetDeclarations(IVsTextView view,
int line,
int col,
TokenInfo info,
ParseReason reason)
{
return declarationsList;
}
/////////////////////////////////////////////////
// Remainder of AuthoringScope methods not shown.
/////////////////////////////////////////////////
}
//===================================================
class TestLanguageService : LanguageService
{
public override AuthoringScope ParseSource(ParseRequest req)
{
TestAuthoringScope scope = new TestAuthoringScope();
if (req.Reason == ParseReason.MemberSelect ||
req.Reason == ParseReason.MemberSelectAndHighlightBraces)
{
// Gather list of declarations based on what the user
// has typed so far. In this example, this list is an array of
// MemberDeclaration objects (a helper class you might implement
// to hold member declarations).
// How this list is gathered is dependent on the parser
// and is not shown here.
MemberDeclarations memberDeclarations;
memberDeclarations = GetDeclarationsForScope();
// Now populate the Declarations list in the authoring scope.
// GetImageIndexBasedOnType() is a helper method you
// might implement to convert a member type to an index into
// the image list returned from the language service.
foreach (MemberDeclaration dec in memberDeclarations)
{
scope.AddDeclaration(new TestDeclaration(
dec.Name,
GetImageIndexBasedOnType(dec.Type),
dec.Description));
}
}
return scope;
}
}
}