C# 通用智能感知的全新完整实现
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9556026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
A New and Full Implementation of Generic Intellisense
提问by MoonKnight
I am interested in writing a generic Intellisense enabled editor for SQL and C# (et al. if possible!). I would like to do this in C# as an overridden or extended WPF richTextBox-type control. I know there are many example projects available and I have implemented a basicversion of my own; but most of the examples that I have come across (and indeed my own) are just that, basic.
我有兴趣为 SQL 和 C# 编写一个通用的启用 Intellisense 的编辑器(等,如果可能的话!)。我想在 C# 中将其作为覆盖或扩展的 WPF richTextBox 类型控件来执行。我知道有很多示例项目可用,并且我已经实现了自己的基本版本;但是我遇到的大多数示例(实际上也是我自己的)只是基本的.
A couple of code examples are:
几个代码示例是:
I have however, found a great example of an SQL editor with Intellisense QueryCommander SQL Editor By Mikael H?kanssonwhich seems to work well. Microsoft must use a XML library of command keywords, but my question is: How (in detail) do Microsoft implement their Intellisense (as-you-type Intellisense) and how hard would it be for me to create my own of the same standard?
然而,我发现了一个很好的 SQL 编辑器示例,其中包含Mikael H?kansson 的Intellisense QueryCommander SQL 编辑器,它似乎运行良好。Microsoft 必须使用命令关键字的 XML 库,但我的问题是:Microsoft 如何(详细地)实现他们的 Intellisense(as-you-type Intellisense)以及我创建自己的相同标准有多难?
Edit A: A year on and I have managed to develop my own editor control with basic intellisense mainly for my own "enjoyment". I thought I would come back provide a list of freely available .NET projects that helped me with my own development and can be used out-of-the-box and free of charge:
编辑 A:一年过去了,我已经设法开发了我自己的带有基本智能感知的编辑器控件,主要是为了我自己的“享受”。我想我会回来提供一份免费可用的 .NET 项目列表,这些项目帮助我进行了自己的开发,并且可以开箱即用且免费:
Edit B: 15 months after the question was asked I am still looking for new improved editors. This one is nice...
编辑 B:提出问题 15 个月后,我仍在寻找新的改进编辑器。这个不错。。。
- RoslynPADis cool!
- RoslynPAD很酷!
Edit C: 2 years+ on from the question, I have found the following projects, both using WPF and backed by AvalonEdit.
编辑 C:从问题开始 2 年以上,我发现了以下项目,均使用 WPF 并由 AvalonEdit 支持。
CodeCompletion for AvalonEditusing NRefactory. This project is really nice and has a full implementation of intellisense using NRefactory.
ScriptCSScriptCS makes it easy to write and execute C# with a simple text editor.
使用 NRefactory进行 AvalonEdit 的 CodeCompletion。这个项目非常好,并且使用 NRefactory 完整实现了智能感知。
ScriptCSScriptCS 使使用简单的文本编辑器编写和执行 C# 变得容易。
采纳答案by Eric Lippert
How (in detail) do Microsoft implement their as-you-type Intellisense?
Microsoft 如何(详细地)实现他们的 as-you-type Intellisense?
I candescribe it to any level of detail you care to name, but I don't have the time for more than a brief explanation. I'll explain how we do it in Roslyn.
我可以将它描述到您想命名的任何详细程度,但我没有时间进行简短的解释。我将解释我们如何在 Roslyn 中做到这一点。
First, we build an immutable model of the token stream using a data structure that can efficiently represent edits, since obviously edits are precisely what there are going to be a lot of.
首先,我们使用可以有效表示编辑的数据结构构建令牌流的不可变模型,因为显然编辑正是将有很多的。
The key insight to making it efficient for persistent reuse is to represent the character lengthsof the tokens but not their character positionsin the edit buffer; remember, a token at the end of the file is going to change position on every edit but the length of the token does not change. You must at all costs minimize the number of total re-lexings if you want to be efficient on extremely large files.
使其持久重用高效的关键在于表示标记的字符长度,而不是它们在编辑缓冲区中的字符位置;请记住,文件末尾的标记将在每次编辑时更改位置,但标记的长度不会改变。如果你想在极大的文件上有效率,你必须不惜一切代价最小化总重新词法的数量。
Once you have an immutable model that can handle inserts and deletions to build up an immutable token stream without re-lexing the entire file every time, you then have to do the samething, but for grammatical analysis. This is in practice a considerably harder problem. I recommend that you obtain an undergraduate or graduate degree in computer science with an emphasis on parser theory if you have not already. We obtained the help of people with PhDs who did their theses on parser theory to design this particular bit of the algorithm.
一旦你有一个不可变的模型可以处理插入和删除来构建一个不可变的标记流,而不必每次都重新对整个文件进行词法分析,那么你就必须做同样的事情,但要进行语法分析。这实际上是一个相当困难的问题。如果您还没有,我建议您获得计算机科学的本科或研究生学位,重点是解析器理论。我们得到了博士的帮助,他们在解析器理论方面做了论文,以设计算法的这一特定部分。
Then, obviously, build a grammatical analyzer that can analyze C#. Remember, it has to analyze brokenC#, not correctC#; IntelliSense has to work while the program is in a non-compiling state. So start by coming up with modifications to the grammar that have good error-recovery characteristics.
然后,显然,构建一个可以分析 C# 的语法分析器。请记住,它必须分析损坏的C#,而不是正确的C#;IntelliSense 必须在程序处于非编译状态时工作。因此,首先要对具有良好错误恢复特性的语法进行修改。
OK, so now you've got a parser that can efficiently do grammatical analysis without re-lexing or re-parsing anything but the edited region, most of the time, which means that you can do the work between keystrokes. I forgot to mention, of course you will need to come up with some mechanism to not block the UI threadwhile doing all of these analyses should the analysis happen to take longer than the time between two keystrokes. The new "async/await" feature of C# 5 should help with that. (I can tell you from personal experience: be careful with the proliferation of tasks and cancellation tokens. If you are careless, it is possible to get into a state where there are tens of thousands of cancelled tasks pending, and that is not fast.)
好的,现在您有了一个解析器,它可以有效地进行语法分析,而无需重新词法分析或重新解析除编辑区域以外的任何内容,大多数情况下,这意味着您可以在击键之间进行工作。我忘了提及,当然,如果分析发生的时间比两次击键之间的时间长,您需要想出一些机制来在执行所有这些分析时不阻塞 UI 线程。C# 5 的新“async/await”特性应该会对此有所帮助。(我可以从个人经验告诉你:小心任务和取消令牌的扩散。如果你不小心,可能会进入有数以万计的取消任务待处理的状态,而且速度并不快。 )
Now that you've got a grammatical analysis you need to build a semantic analyzer. Since you are only doing IntelliSense, it does not need to be a particularly sophisticated semantic analyzer. (Our semantic analyzer must do an analysis suitable for generating code from correct programs and correct error analysis from incorrect programs.) But of course, again it has to do good semantic analysis on broken programs, which does increase the complexity considerably.
现在您已经有了语法分析,您需要构建一个语义分析器。由于您只是在执行 IntelliSense,因此它不需要是一个特别复杂的语义分析器。(我们的语义分析器必须进行适合从正确程序生成代码的分析,以及从错误程序中纠正错误分析。)但当然,它也必须对损坏的程序进行良好的语义分析,这确实大大增加了复杂性。
My advice is to start by building a "top level" semantic analyzer, again using an immutable model that can persist the state of the declared-in-source-code types from edit to edit. The top level analyzer deals with anything that is nota statement or expression: type declarations, directives, namespaces, method declarations, constructors, destructors, and so on. The stuff that makes up the "shape" of the program when the compiler generates metadata.
我的建议是首先构建一个“顶级”语义分析器,再次使用一个不可变模型,该模型可以从编辑到编辑保持源代码中声明类型的状态。顶级分析器处理任何不是语句或表达式的内容:类型声明、指令、命名空间、方法声明、构造函数、析构函数等等。当编译器生成元数据时,构成程序“形状”的东西。
Metadata! I forgot about metadata. You'll need a metadata reader. You need to be able to produce IntelliSense on expressions that refer to types in libraries, obviously. I recommend using the CCI libraries as your metadata reader, and not Reflection. Since you are only doing IntelliSense, obviously you don't need a metadata writer.
元数据!我忘记了元数据。您需要一个元数据阅读器。显然,您需要能够在引用库中类型的表达式上生成 IntelliSense。我建议使用 CCI 库作为元数据阅读器,而不是 Reflection。由于您只使用 IntelliSense,显然您不需要元数据编写器。
Anyway, once you have a top-level semantic analyzer, then you can write a statement-and-expression semantic analyzer that analyzes the types of the expressions in a given statement. Pay particular attention to name lookupand overload resolutionalgorithms. Method type inference will be particularly tricky, especially inside LINQ queries.
无论如何,一旦有了顶级语义分析器,就可以编写语句和表达式语义分析器来分析给定语句中的表达式类型。特别注意名称查找和重载解析算法。方法类型推断将特别棘手,尤其是在 LINQ 查询中。
Once you've got all that, an IntelliSense engine should be easy; just work out the type of the expression at the current cursor position and display a dropdown appropriately.
一旦你掌握了所有这些,IntelliSense 引擎应该很容易;只需计算当前光标位置的表达式类型并适当显示下拉列表。
how hard would it be for me to create my own of the same standard?
创建自己的相同标准对我来说有多难?
Well, we've got a team of, call it ten people, and it'll probably take, call it five years all together to get the whole thing done from start to finish. But we have lots more to do than just the IntelliSense engine. That's maybe only 40% of the work. Oh, and half those people work on VB, now that I think about it. But those people have on average probably five or ten years experience in doing this sort of work, so they're faster at it than you will be if you've never done this before.
好吧,我们有一个团队,称其为十人,可能需要花费五年的时间才能从头到尾完成整个事情。但是,除了 IntelliSense 引擎之外,我们还有很多工作要做。这可能只是工作的 40%。哦,现在我想起来了,其中一半的人都在研究 VB。但是这些人平均可能有五到十年从事此类工作的经验,因此如果您以前从未这样做过,他们会比您更快地完成这项工作。
So let's say it should take you about ten to twenty years of full time work, working alone, to build a Roslyn-quality IntelliSense engine for C# that can do acceptably-close-to-correct analysis of large programs in the time between keystrokes.
因此,假设您需要花费大约 10 到 20 年的全职工作,单独工作,才能为 C# 构建 Roslyn 质量的 IntelliSense 引擎,该引擎可以在两次击键之间的时间内对大型程序进行可接受的接近正确的分析。
Longer if you need to do that PhD first, obviously.
显然,如果您需要先攻读博士学位,则需要更长的时间。
Or, you could simply use Roslyn, since that's what it's for. That'll take you probably a few hours, but you don't get the fun of doing it yourself. And it is fun!
或者,您可以简单地使用 Roslyn,因为这就是. 这可能会花费您几个小时,但您不会从中获得乐趣。这很有趣!
You can download the preview release here:
您可以在此处下载预览版:
回答by Ajs
This is an area where Microsoft typically produces great results - Microsoft developer tools really are awesome. And there is a clear commercial advantage for sales of their developer tools and for sales of Windows to having the best intellisense so it makes sense for Microsoft to devote the kind of resources Eric describes in his wonderfully detailed answer. Still, I think it's worth pointing out a few of things:
这是 Microsoft 通常会产生出色成果的领域 - Microsoft 开发人员工具确实很棒。并且对于他们的开发人员工具的销售和 Windows 的销售来说,拥有最好的智能感知具有明显的商业优势,因此微软将 Eric 在其精彩详细的回答中描述的那种资源投入使用是有道理的。不过,我认为有必要指出以下几点:
Your customers may not actually need all the features that Microsoft's implementation provides. The Microsoft solution might be incredibly over-engineered in terms of the features that youneed to provide to yourcustomers/users. Unless you're actually implementing a generic coding environment that is intended to be competitive with Visual Studio, it is likely that there are aspects of your intended use that either simplify the problem, or that allow you to make compromises on the solution that Microsoft feels they cannot make. Microsoft will likely spend resources decreasing response times that are already measured in hundreds of milliseconds. That may not be something you need to do. Microsoft is spending time on providing an API for others to use for code analysis. That's likely not part of your plan. Prioritize your features and decide what "good enough" looks like for you and your customers then estimate the cost of implementing that.
In addition to bearing the obvious costs of implementing requirements that you may not actually have, Microsoft also carries some costs that may not be obvious if you haven't worked in a team. There are huge communication costs associated with teams. It's actually incredibly easy to have five smart people take longer to produce a solution than it takes for a single smart person to produce the equivalent solution. There are aspects of Microsoft's hiring practices and organizational structure that make this scenario more likely. If you hire a bunch of smart people with egos and then empower all of them to make decisions, you too can get a 5% better solution for 500% of the cost. That 5% better solution might be profitable for Microsoft, but it could be deadly for a small company.
Going from a 1 person solution to a 5 person solution increases the costs, but that's just the intra-team development costs. Microsoft has separateteams that are devoted to (roughly) design, development, and testing even for a single feature. The project-related communication between peers across these boundaries has higher friction than within each of the disciplines. This not only increases communication costs between individuals, but it also results in larger team sizes. And more than that - since it's not a single team of 12 individuals, but is instead 3 teams of 5 individuals, there is 3x the upward communication cost. More costs that Microsoft has chosen to carry that may not translate to similar costs for other companies.
您的客户实际上可能并不需要 Microsoft 实施提供的所有功能。就您需要提供给您的功能而言,Microsoft 解决方案可能过度设计得令人难以置信。客户/用户。除非您实际上正在实施旨在与 Visual Studio 竞争的通用编码环境,否则您的预期用途的某些方面可能会简化问题,或者允许您对 Microsoft 认为的解决方案做出妥协他们做不到。Microsoft 可能会花费资源来减少已经以数百毫秒为单位的响应时间。这可能不是您需要做的事情。微软正在花时间为其他人提供用于代码分析的 API。这可能不是您计划的一部分。优先考虑您的功能并确定对您和您的客户来说“足够好”是什么样的,然后估算实现该功能的成本。
除了承担实施需求的明显成本外,您可能实际上并没有,Microsoft 还承担了一些成本,如果您没有在团队中工作,这些成本可能并不明显。与团队相关的沟通成本很高。实际上,让五个聪明人产生一个解决方案所花费的时间比一个聪明人产生同等解决方案所花费的时间要容易得多。Microsoft 的招聘实践和组织结构的某些方面使这种情况更有可能发生。如果你雇佣了一群自负的聪明人,然后授权他们做决定,你也可以用 500% 的成本获得 5% 更好的解决方案。提高 5% 的解决方案对微软来说可能是有利可图的,但对小公司来说可能是致命的。
从 1 人解决方案到 5 人解决方案会增加成本,但这只是团队内部开发成本。Microsoft 有独立的团队,专门负责(粗略地)设计、开发和测试,即使是针对单个功能也是如此。跨这些边界的同行之间与项目相关的交流比每个学科内的摩擦都更大。这不仅会增加个人之间的沟通成本,还会导致团队规模扩大。更重要的是——因为它不是一个 12 人的团队,而是 3 个 5 人的团队,向上沟通的成本是 3 倍。微软选择承担的更多成本可能不会转化为其他公司的类似成本。
My point here is not to describe Microsoft as an inefficient company. My point is that Microsoft makes a ton of decisions about everything from hiring, to team organization, to design and implementation that start from assumptions about profitability and risk that simply do not apply to companies that are not Microsoft.
我的意思不是将微软描述为一家效率低下的公司。我的观点是,微软从招聘、团队组织、设计和实施等各个方面做出了大量决策,这些决策都是从对盈利能力和风险的假设开始的,这些假设根本不适用于非微软公司。
In terms of the intellisense thing, there are various ways of thinking about the problem. Microsoft is producing a very generic, reusable solution that doesn't just solve intellisense, but also targets code navigation, refactoring, and various other uses for code analysis. You don't need to do things the same way if your sole goal is to make it easy for developers to enter code without having to type much. Targeting that feature doesn't take years of effort and there are all sorts of creative things you can do if you're not just providing an API, but you actually control the UI too.
就智能感知而言,有多种思考问题的方式。Microsoft 正在开发一个非常通用的、可重用的解决方案,它不仅解决了智能感知,而且还针对代码导航、重构和代码分析的各种其他用途。如果您的唯一目标是让开发人员无需输入太多内容就可以轻松输入代码,那么您不需要以相同的方式做事。定位该功能不需要花费数年的努力,如果您不仅提供 API,而且还实际控制 UI,那么您可以做各种有创意的事情。

