ArticleDirectory
- Start step by step
- Run debugging
Review
In the previous two articles, we have studiedCodeStructure, understanding the basic components of a language service and how managed Babel works in language service. In the next two articles, I will start with an empty integration mode package and create a simple language service step by step: in this language, there is no syntax, the coloring tool is used to distinguish numbers and letters. The service defines the file suffix ". SLS ".
Step 1. Create an empty package
The carrier of language service is package, so we need to create an empty package to carry. You can use the Wizard to create an empty package. For more information, see learnvsxnow! -#2 create an empty vs package. I will name this packageSimplelshost.
Ii. Establishment of code structure
1. modeledManagedpc3Create a directory structure for the project, which helps to better manage the code. You can create a directory structure like this:
2. Add Babel code. Go to c: \ Program Files \ Microsoft Visual Studio 2008 SDK \ visualstudiointegration \ common \ source \ CSHARP \ babel to view the Babel code file. If the installation path of your SDK is different from that of mine, you need to find it by yourself. Copy all these CS files to the managedbabel folder in the current project, and add these. CS files under managedbabel in the project. The reason for this is that, based on my experience, Babel code is often changed, so we simply copy it out.
3. Add two. CS under the usersupplied directory:Configuration. CSAndLanguageservice. CSSimplelshostpackage. CSTransferUsersupplied.
4. find the directory where managedacc is located. My directory is :... \ appdata \ Local \ vssdk_9.0_1.1 \ example. managedmyc_f3d35f91 \, copy the files in generated to our own generated and add them to generated in the project. After completing the preceding steps, the directory structure is as follows:
Iii. Quick language service
OpenUsersupplied \ languageservice. CS, Add the following code:
Using system; using system. collections. generic; using system. LINQ; using system. text; using system. runtime. interopservices; namespace company. simplelshost. usersupplied {[GUID ("EDA0749C-7AA5-43b8-97CC-FBD21040AD7A")] class extends ageservice: Babel. babellanguageservice {public override string getformatfilterlist () {return "SLS file (*. SLS) \ n *. SLS ";}}}
The code here is our ls class. We can see that we inheritedBabel. babellanguageserviceAnd specifyGuidYou can use the IDE tool-> Create guid to generate a guid:
4. Add registration information for the package
IsSimplelshostpackageAdd the following attribute definitions and inherit fromBabel. babelpackageTo delete automatically generated constructor and initialization function.
[Provideservice (typeof (company. simplelshost. usersupplied. languageservice)] [providelanguageextension (typeof (company. simplelshost. usersupplied. languageservice ),". SLS ")] [providelanguageservice (typeof (company. simplelshost. usersupplied. languageservice), "simple ls", 0, codesense = true, enablecommenting = true, matchbraces = true, showcompletion = true, showmatchingbrace = true, autooutlining = true, enableasynccompletion = true, codesensedelay = 0)] [GUID (guidlist. guidsimplelshostpkgstring)]
5. Supplement Program Set Reference
Add the following Assembly: Microsoft. visualstudio. Package. languageservice.9.0, Microsoft. visualstudio. textmanager. interop.8.0
6. Edit Project Settings
Previously we mentioned lexer. Lex and parser. Y. These two formats are defined by Microsoft. You can edit these two files in special languages of lex and YACC syntax. The originator of the two was Lex and YACC, which first appeared in Unix. Later, Linux showed two tools, flex and bison, which compile files defined by Lex and YACCCCode. In vs2008sdk, Microsoft provides two similar toolsMplex,MppgUsed to compile lexer. Lex and parser. Y (you can find them in the SDK tool). The output files areLexer. CSAndParser. CS, They are allC #Code, so they can be compiled and run together with other C # code by the C # compiler. However, IDE does not know lexer. Lex and parser. Y. We need to manually set the compiler for these two files. However, Microsoft made a mistake here:
For example, in the optional compilation behavior, we cannot findMplexcompileAndMppgcompileAnd manual input is invalid. Therefore, we can only manually modify the project configuration file: Save the project, right-clickSimplelshostProject, selectUnload Project, Right-click the project, and selectEdit simplelshost. csprojFind the following code snippet:
<Itemgroup> <none include = "generated \ lexer. Lex"/> <none include = "generated \ parser. Y"/> </itemgroup>
To:
<Itemgroup> <mplexcompile include = "generated \ lexer. Lex"/> <mppgcompile include = "generated \ parser. Y"/> </itemgroup>
After saving, right-click the project and selectReload Project. Let's look at the properties of lexer. Lex and parser. Y-> build action, which are set to mplexcompile and mppgcompile respectively. In this wayMplexAndMppgCompile them, and the output files can be seen in the OBJ folder.
VII. Check compilation errors
Now Let's rebuild it and check the results. There are a bunch of errors! It doesn't matter. Let's take a look.
The most common problem is that the language service class cannot be found. This problem is caused by a disadvantage of the babelpackage I mentioned in the previous article. The babelpackage Code specifies thatBabel. languageserviceHowever, our elastic ageservice isCompany. simplelshost. usersupplied. Your ageservice! Of course not found! Change Babel. languageservice to company. simplelshost. usersupplied. languageservice. The remaining problem is: we have not edited configuration. CS, and we have not implementedIastresolverInterfaceResolver. FirstUsersuppliedDirectory, addResolver. CSWe are still secretly lazy. We copied the resolver. CS code in managedmc. Note that as long as the class part is copied, The namespace does not need to be the same. FinallyAuthoringscope. CSAdd the namespace using company. simplelshost. usersupplied. Finally, overwrite the code in configuration. CS with the code of configuration. CS in managedyy. Note,All copies are required, including the namespace.. Compile until there is no error. In general, if there is an error, it is basically because the namespace does not match. You can check it yourself.
8. slightly changed
Now we wantUsersupplied \ configuration. CSWith a slight modification, the following code overwrites the original code:
Public const string name = "simple ls"; Public const string extension = ". SLS ";
Then, you can replace the constants in the package registration information with these two constants:
[Providelanguageextension (typeof (company. simplelshost. usersupplied. languageservice), Babel. configuration. extension)] [providelanguageservice (typeof (company. simplelshost. usersupplied. languageservice), Babel. configuration. name, 0,
Run debugging
Recompile and press F5 to open a test file 1.sls. the result is as follows:
As you can see, the results of this language service are the same as those of manage. Because our core lexer and parser are copied from managedacc. configuration also uses managedy. Of course, the results are the same, the only difference is that we have registered different suffixes for this package!
Summary
In this article, we build a language service framework from an empty package step by step, and apply the lexer and parser of managedyy to perform a simple test. The steps mentioned in this article are the basis for building language services in the future. You can also refer to "How do I ?" Video content. In the next article, we will try to modify lexer, parser, and configuration.