Partager via


Analyseur de service de langage et scanner (managed de package)

L'analyseur est le cœur du service de langage. Les classes de langage managées (MPF) du package présence d'un analyseur de langage pour sélectionner des informations sur le code affiché. Un analyseur sépare le texte dans les entités lexicales puis identifie ces jetons par le type et la fonctionnalité.

Discussion

Voici une méthode c#.

namespace MyNamespace
{
    class MyClass
    {
        public void MyFunction(int arg1)
        {
            int var1 = arg1;
        }
    }
}

dans cet exemple, les jetons sont les mots et les signes de ponctuation. Les types de jetons sont les suivantes.

Nom du jeton

Type de jeton

l'espace de noms, classe, public, void, int

mot clé

=

.

{ } ( ) ;

séparateur

MyNamespace, MyClass, MyFunction, arg1, var1

identifier

MyNamespace

Espace de noms

MyClass

classe

MyFunction

méthode

arg1

Paramètre

var1

variable locale

le rôle de l'analyseur est d'identifier les jetons. Certains jetons peuvent avoir plusieurs types. Une fois l'analyseur a identifié les jetons, le service de langage peut utiliser ces informations pour fournir les fonctionnalités utiles, telles que la mise en surbrillance de la syntaxe, accolades correspondantes, et les opérations Intellisense.

types d'analyseurs

Un analyseur de service de langage n'est pas le même que analyseur utilisé dans le cadre d'un compilateur. Toutefois, ce type de l'analyseur doit utiliser un scanneur et un analyseur, de la même façon qu'un analyseur de compilateur.

  • Un scanner est utilisé pour identifier des types de jetons. Ces informations sont utilisées pour la syntaxe mise en surbrillance et pour identifier rapidement les types de jetons qui peuvent déclencher d'autres opérations, par exemple, accolades correspondantes. Ce scanner est représenté par l'interface d' IScanner .

  • un analyseur est utilisé pour décrire les fonctions et la portée des jetons. Ces informations sont utilisées dans les opérations d'Intellisense pour identifier les éléments de langage, tels que des méthodes, des variables, des paramètres, et les déclarations, et fournir des listes de membres et les signatures de méthode selon le contexte. Cet analyseur est également utilisé pour localiser les paires d'éléments correspondantes de langage, telles que les accolades et les parenthèses. Cet analyseur est accessible via la méthode d' ParseSource dans la classe d' LanguageService .

La manière dont vous implémentez un scanneur et un analyseur pour votre service de langage vous appartient. plusieurs ressources sont disponibles que décriviez comment les analyseurs fonctionnent et comment écrire votre propre analyseur. En outre, plusieurs produits commercial libres et sont disponibles qu'vous aide à créer un analyseur.

L'analyseur de ParseSource

Contrairement à un analyseur utilisé dans le cadre d'un compilateur (où les jetons sont convertis en forme quelconque de code exécutable), un analyseur de service de langage peut être appelé pour de nombreuses raisons et dans de nombreux contextes. La manière dont vous implémentez cette approche dans la méthode d' ParseSource dans la classe d' LanguageService vous appartient. Il est important de ne pas oublier que la méthode d' ParseSource peut être appelée sur un thread d'arrière-plan.

Avertissement

la structure d' ParseRequest contient une référence à l'objet d' IVsTextView .cet objet d' IVsTextView ne peut pas être en arrière-plan thread utilisé.En fait, nombreuses classes de la base MPF ne peuvent pas être en arrière-plan thread utilisé.Celles-ci incluent Source, ViewFilter, les classes d' CodeWindowManager , et toute autre classe que communique directement ou indirectement avec la vue.

Cet analyseur analyse en général le fichier source entier la première fois qu'elle est appelée ou lorsque la valeur raison de l'analyse d' Check est affiché. Les appels suivants à la méthode d' ParseSource gèrent une petite portion de code analysé et peuvent être exécutés plus rapidement à l'aide de les résultats de l'opération d'analyse complète précédente. La méthode d' ParseSource communique les résultats de l'opération d'analyse parmi les objets d' AuthoringSink et d' AuthoringScope . L'objet d' AuthoringSink est utilisé pour collecter les informations pour une raison spécifique d'analyse, par exemple, informations sur les étendues de l'accolade correspondante ou signatures de méthode qui ont des listes de paramètres. AuthoringScope fournit des collections de déclarations et de signatures de méthode et les prend également en charge pour l'atteindre l'option avancée de modification (Atteindre la définition, Accédez à la déclaration, Accédez à la référence).

Le scanner d'IScanner

Vous devez également implémenter un scanner qui implémente IScanner. Toutefois, étant donné que ce scanner opère fichier ligne par ligne via la classe d' Colorizer , il est en général plus facile d'implémenter. Au début de chaque ligne, le MPF donne à la classe d' Colorizer une valeur à utiliser comme variable d'état qui est passée au scanner. À la fin de chaque ligne, le scanner retourne la variable d'état mise à jour. Le MPF met en cache les informations d'état pour chaque ligne afin que le scanner puisse démarrer l'analyse de toute ligne sans avoir à démarrer au début du fichier source. cette analyse rapide d'une ligne unique permet à l'éditeur pour fournir la rétroaction rapide à l'utilisateur.

analyse pour l'accolade correspondante

Cet exemple illustre l'ordre d'exécution pour faire correspondre une accolade fermante que l'utilisateur a tapée. Dans ce processus, le scanner utilisé pour la colorisation est également utilisé pour déterminer le type de jeton et si le jeton peut déclencher une opération de correspondance-accolade. Si le déclencheur est trouvé, la méthode d' ParseSource est appelée pour rechercher l'accolade correspondante. Enfin, les deux accolades sont mises en surbrillance.

Bien que l'accolade soit utilisée dans les noms des déclencheurs et analyse des raisons, ce processus n'est pas limité à l'accolade réelle. Toute paire de caractères qu'il est spécifié comme étant une paire correspondante est prise en charge. Les exemples incluent (et), < et >, et [et].

Supposez que le service prend en charge du langage correspondant à l'accolade.

  1. L'utilisateur tape une accolade fermante (}).

  2. Les accolades est insérée au curseur dans le fichier source et le curseur est avancée par un.

  3. la méthode d' OnCommand dans la classe d' Source est appelée avec l'accolade fermante typée.

  4. les appels de méthode d' OnCommand la méthode d' GetTokenInfo dans la classe d' Source pour obtenir le jeton à la position juste avant la position du curseur actuelle. ce jeton correspond à l'accolade fermante typée).

    1. les appels de méthode d' GetTokenInfo la méthode d' GetLineInfo sur l'objet d' Colorizer pour obtenir tous les jetons sur la ligne en cours.

    2. Les appels de méthode d' GetLineInfo la méthode d' SetSource sur l'objet d' IScanner avec le texte de la ligne active.

    3. La méthode d' GetLineInfo appelle plusieurs la méthode d' ScanTokenAndProvideInfoAboutIt sur l'objet d' IScanner pour rassembler les jetons de la ligne active.

    4. Les appels de méthode d' GetTokenInfo une méthode privée dans la classe d' Source pour obtenir le jeton qui contient l'emplacement souhaité, puis passe dans la liste de jetons obtenus à partir de la méthode d' GetLineInfo .

  5. La méthode d' OnCommand recherche une balise de jeton du déclencheur d' MatchBraces sur le jeton qui est retourné par la méthode d' GetTokenInfo ; autrement dit, le jeton qui représente l'accolade fermante).

  6. Si la balise du déclencheur d' MatchBraces est trouvée, la méthode d' MatchBraces dans la classe d' Source est appelée.

  7. La méthode d' MatchBraces lance une opération d'analyse avec la valeur raison de l'analyse d' HighlightBraces. cette opération appelle finalement la méthode d' ParseSource sur la classe d' LanguageService . Si l'analyse asynchrone est activée, cet appel à la méthode d' ParseSource se produit sur un thread d'arrière-plan.

  8. Lorsque l'opération d'analyse est terminée, un gestionnaire interne d'achèvement (également appelé une méthode de rappel) HandleMatchBracesResponse nommé est appelé dans la classe d' Source . Cet appel est effectuée automatiquement par la classe de base d' LanguageService , pas par l'analyseur.

  9. La méthode d' HandleMatchBracesResponse obtient une liste d'étendues de l'objet d' AuthoringSink stocké dans l'objet d' ParseRequest . (L'étendue d'Un est une structure d' TextSpan qui spécifie une plage des lignes et des caractères dans le fichier source.) Cette liste d'étendues contient généralement deux étendues, une pour les accolades ouvrantes et fermantes.

  10. Les appels de méthode d' HandleBracesResponse la méthode d' HighlightMatchingBrace sur l'objet d' IVsTextView stocké dans l'objet d' ParseRequest . Cela met en surbrillance les étendues données.

  11. Si la propriété EnableShowMatchingBrace d' LanguagePreferences est activée, la méthode d' HandleBracesResponse obtient le texte qui est entouré par l'étendue correspondante et affiche les 80 premiers caractères de cette étendue dans la barre d'état. Cela fonctionne mieux si la méthode d' ParseSource inclut l'élément de langage qui accompagne les paires correspondantes. Pour plus d'informations, consultez la propriété EnableShowMatchingBrace.

  12. fait.

Résumé

L'opération d'accolades correspondantes est généralement limitée aux paires simples d'éléments de langage. Les éléments complexes, tels que les triples correspondants ("if(…) », « { » et « } », ou « else », « { » et « }"), peuvent être mis en surbrillance dans le cadre d'une opération de Word-achèvement. Par exemple, lorsque le mot « d'autre » est terminé, l'instruction correspondante de « if » peut être mise en surbrillance. S'il y avait une série d' if/d'instructions d'else if , tous peuvent être mis en surbrillance en utilisant le même mécanisme que l'accolade correspondante. La classe de base d' Source prend déjà en charge cette opération, comme suit : Le scanner doit retourner la valeur de jeton MatchBraces de déclencheur est combiné avec la valeur MemberSelect de déclencheur pour le jeton qui se trouve avant la position du curseur.

Pour plus d'informations, consultez Accolades correspondantes (managed de package).

Analyse la colorisation

Code source de Colorizing est simple, identifie uniquement le type d'informations sur la couleur de jetons et de retour sur ce type. La classe d' Colorizer joue le rôle d'intermédiaire entre l'éditeur et le scanner pour fournir des informations sur la couleur sur chaque jeton. La classe d' Colorizer utilise l'objet d' IScanner pour vous aider dans colorizing une ligne ainsi que des informations d'état de marshaling pour toutes les lignes d'un fichier source. Dans les classes de service de langage de MPF, la classe d' Colorizer ne doit pas être substituée car elle communique avec le scanner uniquement via l'interface d' IScanner . Vous fournissez l'objet qui implémente l'interface d' IScanner en substituant la méthode d' GetScanner sur la classe d' LanguageService .

Le scanner d' IScanner reçoit une ligne de code source pour la méthode d' SetSource . Les appels à la méthode d' ScanTokenAndProvideInfoAboutIt sont répétés pour obtenir le jeton suivant dans la ligne jusqu'à ce que la ligne ne soit atteinte des jetons. Pour la colorisation, le MPF traite tout le code source comme une séquence de lignes. Par conséquent, le scanner doit pouvoir faire face à la source provenant en tant que lignes. En outre, toute ligne peut être passée au scanner à tout moment, et la seule garantie est que le scanner reçoit la variable d'état de la ligne pour la ligne sur à analyser.

la classe d' Colorizer est également utilisée pour identifier les déclencheurs symboliques. Ces déclencheurs indiquent le MPF qu'un jeton donné peut démarrer une opération complexe, telle que le mot ou l'accolade correspondante. Étant donné qu'identification de ces déclencheurs doit être rapide et doit se produire à tout emplacement, le scanner est plus adapté pour cette tâche.

Pour plus d'informations, consultez Syntaxe Colorizing (managed de package).

Analyse la fonctionnalité et la portée

L'analyse la fonctionnalité et la portée requiert plus de temps que l'identification des types de jetons qui sont produits. L'analyseur doit identifier non seulement le type de jeton, mais également des fonctionnalités pour laquelle le jeton est utilisé. Par exemple, un identificateur est un simple nom, mais dans votre langage, un identificateur peut être le nom d'une classe, d'un espace de noms, méthode, ou d'une variable, selon le contexte. Le type général du jeton peut être un identificateur, mais l'identificateur peut également avoir d'autres significations, selon ce qui est il et où il est défini. Cet ID. requiert que l'analyseur pour avoir une connaissance plus étendue relatives au langage qui est analysé. C'est la classe d' AuthoringSink entre. La classe d' AuthoringSink collecte des informations sur les identificateurs, méthodes, couples de langue correspondants (tels que les accolades et les parenthèses), et le langage triple (similaire aux couples de langue mais il existe trois parties, par exemple, « foreach() » « { » et « }"). En outre, vous pouvez substituer la classe d' AuthoringSink pour prendre en charge l'ID de code, qui est utilisée pour la validation haut des points d'arrêt afin que le débogueur ne doit pas être chargé, et Automatique déboguer la fenêtre, qui affiche les variables locales et des paramètres automatiquement lorsqu'un programme qui est débogué et l'analyseur pour identifier des variables locales appropriées et des paramètres en plus de celles que le débogueur présente.

L'objet d' AuthoringSink est passé à l'analyseur au sein de l'objet d' ParseRequest , et un nouvel objet d' AuthoringSink est créé chaque fois qu'un nouvel objet d' ParseRequest est créé. En outre, la méthode d' ParseSource doit retourner un objet d' AuthoringScope , qui est utilisé pour effectuer différentes opérations Intellisense. L'objet d' AuthoringScope gère une liste pour les déclarations et une liste pour les méthodes, ou dont est rempli, selon la raison pour analyser. La classe d' AuthoringScope doit être implémenté.

Voir aussi

Concepts

Vue d'ensemble du service de langage (managed de package)

Syntaxe Colorizing (managed de package)

Accolades correspondantes (managed de package)

Autres ressources

Implémenter un service de langage à l'aide de managed package