在舊版語言服務中的成員完成
發行︰ 2016年7月
如需 Visual Studio 2017 的最新文件請參閱 Visual Studio 2017 文件。
完成 IntelliSense 成員是會顯示一份可能的成員,例如類別、 結構、 列舉型別或命名空間的特定範圍的工具提示。 比方說,在 C# 中,如果使用者輸入"this",後面接著句點,類別或結構,在目前範圍內的所有成員的清單會顯示使用者可以從中選取的清單中。
受管理的封裝架構 (MPF) 提供支援的工具提示和管理清單中的工具提示。所需要的全部是由剖析器來提供資料出現在清單中的合作。
舊版的語言服務會實作成,VSPackage 的一部分,但實作語言服務功能的較新的方法是使用 MEF 延伸模組。 若要深入了解,請參閱擴充編輯器和語言服務。
注意
我們建議您開始使用新的編輯器 API 儘速。 這會改善語言服務的效能,並可讓您充分利用新編輯器功能。
它的運作方式
以下是在其成員清單會顯示使用 MPF 類別的兩種方法︰
識別項 (含) 之後成員完成字元位置插入號,然後選取列出成員從IntelliSense功能表。
IScanner掃描器會偵測成員完成字元,並設定權杖觸發程序的MemberSelect ,該字元。
成員完成字元表示的類別、 結構或列舉型別成員是遵循。 例如,在 C# 或 Visual Basic 成員完成字元是.
,而 c + + 中的字元是其中.
或->
。 成員選取字元會掃描時,會設定觸發程序的值。
IntelliSense 成員 List 命令
SHOWMEMBERLIST命令開始呼叫完成方法來源類別和完成方法,接著呼叫ParseSource方法剖析器剖析原因為DisplayMemberList。
剖析器會判斷目前的位置,以及在或之前的目前位置的語彙基元的內容。 根據這個語彙基元,會顯示宣告的清單。 例如,在 C# 中,如果您的類別成員,然後選取插入號列出成員,取得類別的所有成員的清單。 如果您插入號後面物件變數的句點之後,您會取得類別的物件所代表的所有成員的清單。 請注意,是否插入號位於成員顯示成員的清單時,從清單中選取的成員會取代插入號是一個清單中的成員。
語彙基元的觸發程序
MemberSelect觸發程序開始呼叫完成方法來源類別和完成方法,轉而呼叫的剖析器剖析原因為MemberSelect (如果語彙基元的觸發程序也包含MatchBraces旗標,剖析的原因是MemberSelectAndHighlightBraces其中結合了成員選取範圍和大括號反白顯示)。
剖析器會判斷目前的內容以及成員選取字元之前具有已輸入位置。 這項資訊,從剖析器會建立要求的範圍中的所有成員的清單。 此宣告的清單儲存在AuthoringScope所傳回的物件ParseSource方法。 如果傳回的任何宣告,則會顯示成員完成工具提示。 執行個體所管理的工具提示CompletionSet類別。
啟用支援成員完成
您必須擁有CodeSense
登錄項目設為 1,以支援 IntelliSense 的任何作業。 此登錄項目可以設定具名參數,傳遞至ProvideLanguageServiceAttribute語言套件相關聯的使用者屬性。 語言服務類別會讀取此登錄項目的值從EnableCodeSense屬性LanguagePreferences類別。
如果您的掃描器傳回的語彙基元的觸發程序MemberSelect,和您剖析器會傳回一份宣告,就不會顯示成員的完成清單。
掃描器的支援成員完成
掃描器必須能夠偵測成員完成字元及設定的語彙基元的觸發程序MemberSelect剖析該字元時。
範例
以下是一個簡單的例子,偵測成員完成字元,並設定適當的TokenTriggers旗標。 這個範例是僅供示範用途。 它會假設您的掃描器都包含一種方法GetNextToken
,識別,並傳回權杖,從一行文字。 每當它看見正確類型的字元時,範例程式碼只需設定觸發程序。
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;
}
}
}
剖析器中支援成員完成
成員完成來源類別會呼叫GetDeclarations方法。 您必須從衍生類別中實作清單宣告類別。 請參閱宣告類別必須實作的方法的相關詳細資料。
剖析器會以呼叫MemberSelect或MemberSelectAndHighlightBraces成員選取的字元型別。 指定位置ParseRequest物件後立即成員選取字元。 剖析器必須收集可以在原始程式碼中的特定點的成員清單中出現的所有成員的名稱。 然後,剖析器必須剖析目前這一行來決定使用者想要的成員選取字元相關聯的範圍。
成員選取字元之前,此範圍根據識別項的類型。 例如,在 C# 中,指定的成員變數languageService
具有一種LanguageService
,輸入languageService。 產生的所有成員的清單LanguageService
類別。 也在 C# 中,輸入這。 產生目前範圍中類別的所有成員的清單。
範例
下列範例將示範一種方式填入宣告清單。 此程式碼假設剖析器建構宣告,並將它加入至清單中,藉由呼叫AddDeclaration
方法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;
}
}
}