错误(Errors)甚至当源文本含有句法错误时,都能表明完整的句法树是可往返于源的。当解析器遇到无法确定该语言定义的句法代码时,它将使用两种技术中的一种来创建句法树。 第一种,假如解析器需要一种特殊标记,但是却找不到时,它将在句法树该特殊标记应该存在的地方插入一个丢失标记。丢失标记描述需要的实际标记,但是它是一个空区,并且它的IsMissing属性将返回真。 第二种,解析器可能跳过标记直到它找到了能够让它继续解析一个标记。这种情况下,被跳过的标记将附加上一个有SkippedTokens的杂项节点。 语义方面(Working with Semantics) 句法树表达的是源代码的词法和句法结构。虽然仅靠信息就足以描述源代码中的所有声明和逻辑,但不足以表示哪些东西正在被引用。 这些是源代码中的程序元素,而且程序也可以引用打包成程序集的编译好的类库。虽然程序集中不存在源代码,因此也就不存在句法节点或者树,但程序仍可以引用其中的元素。 在源代码的句法模型之外,语义模型封装了语言规则,让你有个简单的方法来对上面的情况作出区别。
合辑( compilation )合辑 就是编译 C#或VB 程序所需的所有东西,包括所有引用的程序集、编译器选项及源文件。 由于这些信息保存在同一个地方,因此源代码中所包含的元素可以得到更加详细的说明。合辑用符号表示每一个声明的类型、成员或变量。它还提供多种方法,以帮助你找到相关符号,无论该符号是在源代码中声明的,还是作为元数据从程序集中导入的。 与句法树一样,合辑是不可变的。当你创建了合辑,你或者你想共享的其他人都不能改变它。不过,你可以从一个已存在的合辑中做出修改以此来创建一个新的合辑。比如,你可以创建一个 除了包含额外的源文件或程序集引用以外,其他所有的地方都和一个已存在合辑一样的新合辑,符号(Symbols)符号就是在源代码中声明的或者从程序集中导入的元数据的独特元素。每个命名空间、类型、方法、属性、字段、事件、参数或局部变量都可用符号表示。在 Compilation 这个类型中有各种各样的方法和属性来帮你查找符号。比如你可以通过公用元数据名称来查找声明的类型的符号。你也可以以符号树的形式来访问整个符号表,这些符号以全局命名空间为根节点。 符号也包含编译器从源代码或者元数据中得到的附加信息,例如其他被引用的符号。每种符号都是用从ISymbol派生的接口来表示,每个接口都有自己的方法和属性来详细说明编译器收集到的信息。其中的许多属性直接引用其他符号。比如,IMethodSymbol 类的 ReturnType 属性,告诉你方法声明所引用的实际类型符号。 符号是命名空间、类型和成员在源代码和元数据之间的通用表示。例如,在源代码中声明的方法和从元数据导入的方法,均表示为有相同属性的 IMethodSymbol。 用System.Reflection API表示的符号在概念上与CLT类型系统相似,但它们是模型而不仅仅是类型,因此要更丰富些。命名空间、本地变量和标签都是符号。此外,符号表现为语言概念而非 CLR 概念。它们有很多重叠的地方,但也有很多有意义的区别。比如,在 C# 或 Visual Basic 中的迭代器方法(iterator)是单一符号。但是当迭代器方法转换为 CLR 元数据,它是一个类型和多个方法。 语义模型 语义模型 展示了单个源文件的所有语义信息。使用它你能发现如下内容:
工作区方面(Working with a Workspace)工作区层是对整个解决方案做代码分析和重构的起点。在该层内,工作区API将协助你组织一个解决方案中有关项目的所有信息到一个单独对象模型中,提供你直接访问如源文本、句法树、语义模型和合辑的编译器层对象模型,而不需要解析文件、配置选项或管理内部项目依赖。 宿主环境,比如IDE,提供了一个工作区让你打开解决方案。也可以简单的通过载入一个解决方案文件在IDE外部来使用该模型。 工作区(Workspace)工作区作为项目的一个集合,是解决方案的活跃展现,每一个都是文档的集合。典型的,工作区会被绑定一个宿主环境,作为一种用户类型或操作性能是经常变化的。 工作区提供了访问解决方案的当前模型。当宿主环境发生变化时,工作区就好触发相应的事件,并且更新CurrentSolution属性。例如,当一个文本编辑器中的用户类型与源文档中的其中一个相关联时,工作区将用事件像整个解决方案的模型发送已变更信号,且告知是哪一个文档被修改。你可以从正确性、高亮内容的意义或对代码的更改提出建议来分析新模型,从而对这些变化做出反应。 你也可以创建单独的工作区,前提是断开宿主环境,或者用在一个没有宿主环境的应用中。 解决方案(Solutions),项目(Projects),文档(Documents)虽然每按一次键都可能改变工作区,你也可以在隔离的解决方案模型中工作。 解决方案是工程和文档的固定模型。这意味着模型无需加锁或复制就可以被共享。在你从工作区的CurrentSolution属性中获取一个解决方案实例后,该实例就不会再变了。不过,像语法树和合辑,你可以在已存在的解决方案和特定修改上通过构造新实例来更改解决方案。要在工作区中看到你做的更改,你必须明确的将更改的解决方案应用到工作区。 文档也是整体不变的解决方案模型的一部分。文档呈现了一个单个源文件,从中你可以访问文件、语法树和语义模型的文本。下面的图显示了与宿主环境、工具和怎样做的更改有关的工作区。 总结.NET编译器平台(“Roslyn”)公开了一组编译器API和工作区API,它们提供了关于你的源代码的丰富信息,并且完全忠于C#和Visual Basic语言。让编译器作为平台的过渡,为集中创建代码工具和应用程序大大降低了进入门槛。它创造了许多革新,如:meta-Programming、代码生成和转换,交互使用C#和VB语言,和某些特殊领域的嵌入式C#和VB语言。
|