public Type GetSerializer(XmlSerializer caller, Type t, ref string rootName, ref string rootNamespace) { // start again with clean error list - do NOT return errors from the temporary checker. errors = new ErrorNodeList(); errorHandler = new ErrorHandler(errors); TypeNode type = TypeNode.GetTypeNode(t); string nspace = GetSerializerNamespace(type); string serializerClassName = GetSerializerName(type); string fullName = nspace + ((nspace != "" && nspace != null) ? "." : "") + serializerClassName; // Structural types have no container element name. if (!IsStructuralType(type) && !(type is EnumNode)) { if (rootName == null) { Identifier name = Checker.GetDefaultElementName(type); rootName = name.Name; if (rootNamespace == null && name.Prefix != null) { rootNamespace = name.Prefix.Name; } } } if (caller.GetType().FullName == fullName) return caller.GetType(); AssemblyNode assembly = AssemblyNode.GetAssembly(t.Assembly, cache, false, true); // see if we can find a serializer in the same assembly as the given type. TypeNode serializerType = assembly.GetType(Identifier.For(nspace), Identifier.For(serializerClassName)); if (serializerType != null) { Type result = serializerType.GetRuntimeType(); Debug.Assert(result != null, "GetRuntimeType() failed on " + serializerType.FullName); return result; } System.Reflection.Assembly sasm = (System.Reflection.Assembly)genCache[t]; if (sasm == null) { ComegaCompilerOptions options = new ComegaCompilerOptions(); options.OutputAssembly = type.Name + "Serializer.dll"; options.GenerateExecutable = false; options.ModuleKind = ModuleKindFlags.DynamicallyLinkedLibrary; if (DumpOption == null) { DumpOption = System.Environment.GetEnvironmentVariable("DEBUG_SERIALIZER"); if (DumpOption == null) DumpOption = ""; } options.GenerateInMemory = (DumpOption == ""); options.DumpTree = (DumpOption != ""); options.IncludeDebugInformation = (DumpOption != ""); options.TempFiles = new TempFileCollection(Directory.GetCurrentDirectory(), true); string writerAssembly = typeof(XmlSerializationWriter).Assembly.Location; options.ReferencedAssemblies.Add(writerAssembly); string xmlAssembly = typeof(XmlTextReader).Assembly.Location; options.ReferencedAssemblies.Add(xmlAssembly); Compiler compiler = new Compiler(); Module module = compiler.CreateModule(options, errors); CompilationUnit cu = CreateCompilationUnit(module, type); // so we can find all the structural types already defined in the assembly // associated with the type we are building the serializer for. cu.TargetModule.AssemblyReferences.Add(new AssemblyReference(assembly)); CompilerResults results = compiler.CompileAssemblyFromIR(options, cu, errors); if (errors.Length > 0) { throw new XmlSerializerException(errors[0].GetMessage()); } else if (results.Errors.Count>0) { throw new XmlSerializerException(results.Errors[0].ErrorText); } else { sasm = results.CompiledAssembly; if (sasm == null) throw new XmlSerializerException(RuntimeError.SerializationAssembly); genCache[t] = sasm; } } Type instanceType = sasm.GetType(fullName, false, false); if (instanceType == null) throw new XmlSerializerException(RuntimeError.SerializationClass, fullName); return instanceType; }
public override void ParseAndAnalyzeCompilationUnit(string fname, string text, int line, int col, ErrorNodeList errors, Compilation compilation, AuthoringSink sink) { if (fname == null || text == null || errors == null || compilation == null){Debug.Assert(false); return;} if (compilation != null && compilation.CompilerParameters is SpecSharpCompilerOptions) this.allowSpecSharpExtensions = !((SpecSharpCompilerOptions)compilation.CompilerParameters).Compatibility; CompilationUnitList compilationUnitSnippets = compilation.CompilationUnits; if (compilationUnitSnippets == null){Debug.Assert(false); return;} //Fix up the CompilationUnitSnippet corresponding to fname with the new source text CompilationUnitSnippet cuSnippet = this.GetCompilationUnitSnippet(compilation, fname); if (cuSnippet == null) return; Compiler compiler = new Compiler(); compiler.CurrentCompilation = compilation; cuSnippet.SourceContext.Document = compiler.CreateDocument(fname, 1, new DocumentText(text)); cuSnippet.SourceContext.EndPos = text.Length; //Parse all of the compilation unit snippets Module symbolTable = compilation.TargetModule = compiler.CreateModule(compilation.CompilerParameters, errors); AttributeList assemblyAttributes = symbolTable is AssemblyNode ? symbolTable.Attributes : null; AttributeList moduleAttributes = symbolTable is AssemblyNode ? ((AssemblyNode)symbolTable).ModuleAttributes : symbolTable.Attributes; int n = compilationUnitSnippets.Count; for (int i = 0; i < n; i++){ CompilationUnitSnippet compilationUnitSnippet = compilationUnitSnippets[i] as CompilationUnitSnippet; if (compilationUnitSnippet == null){Debug.Assert(false); continue;} Document doc = compilationUnitSnippet.SourceContext.Document; doc = compilationUnitSnippet.SourceContext.Document; if (doc == null || doc.Text == null){Debug.Assert(false); continue;} IParserFactory factory = compilationUnitSnippet.ParserFactory; if (factory == null) continue; compilationUnitSnippet.Nodes = null; compilationUnitSnippet.PreprocessorDefinedSymbols = null; IParser p = factory.CreateParser(doc.Name, doc.LineNumber, doc.Text, symbolTable, compilationUnitSnippet == cuSnippet ? errors : new ErrorNodeList(), compilation.CompilerParameters); if (p == null){Debug.Assert(false); continue;} if (p is ResgenCompilerStub) continue; Parser specSharpParser = p as Parser; if (specSharpParser == null) p.ParseCompilationUnit(compilationUnitSnippet); else specSharpParser.ParseCompilationUnit(compilationUnitSnippet, compilationUnitSnippet != cuSnippet, false); //TODO: this following is a good idea only if the files will not be frequently reparsed from source //StringSourceText stringSourceText = doc.Text.TextProvider as StringSourceText; //if (stringSourceText != null && stringSourceText.IsSameAsFileContents) // doc.Text.TextProvider = new CollectibleSourceText(doc.Name, doc.Text.Length); } //Construct symbol table for entire project ErrorHandler errorHandler = new ErrorHandler(errors); SpecSharpCompilation ssCompilation = new SpecSharpCompilation(); TrivialHashtable ambiguousTypes = new TrivialHashtable(); TrivialHashtable referencedLabels = new TrivialHashtable(); TrivialHashtable scopeFor = this.scopeFor = new TrivialHashtable(); Scoper scoper = new Scoper(scopeFor); scoper.currentModule = symbolTable; Looker symLooker = new Looker(null, new ErrorHandler(new ErrorNodeList(0)), scopeFor, ambiguousTypes, referencedLabels); symLooker.currentAssembly = (symLooker.currentModule = symbolTable) as AssemblyNode; Looker looker = new Looker(null, errorHandler, scopeFor, ambiguousTypes, referencedLabels); looker.currentAssembly = (looker.currentModule = symbolTable) as AssemblyNode; looker.VisitAttributeList(assemblyAttributes); bool dummyCompilation = compilation.CompilerParameters is SpecSharpCompilerOptions && ((SpecSharpCompilerOptions)compilation.CompilerParameters).DummyCompilation; if (dummyCompilation){ //This happens when there is no project. In this case, semantic errors should be ignored since the references and options are unknown. //But proceed with the full analysis anyway so that some measure of Intellisense can still be provided. errorHandler.Errors = new ErrorNodeList(0); } for (int i = 0; i < n; i++){ CompilationUnit cUnit = compilationUnitSnippets[i]; scoper.VisitCompilationUnit(cUnit); } for (int i = 0; i < n; i++){ CompilationUnit cUnit = compilationUnitSnippets[i]; if (cUnit == cuSnippet) looker.VisitCompilationUnit(cUnit); //Uses real error message list and populate the identifier info lists else symLooker.VisitCompilationUnit(cUnit); //Errors are discarded } //Run resolver over symbol table so that custom attributes on member signatures are known and can be used //to error check the the given file. TypeSystem typeSystem = new TypeSystem(errorHandler); Resolver resolver = new Resolver(errorHandler, typeSystem); resolver.currentAssembly = (resolver.currentModule = symbolTable) as AssemblyNode; Resolver symResolver = new Resolver(new ErrorHandler(new ErrorNodeList(0)), typeSystem); symResolver.currentAssembly = resolver.currentAssembly; symResolver.VisitAttributeList(assemblyAttributes); for (int i = 0; i < n; i++) { CompilationUnit cUnit = compilationUnitSnippets[i]; if (cUnit == cuSnippet) resolver.VisitCompilationUnit(cUnit); //Uses real error message list and populate the identifier info lists else symResolver.VisitCompilationUnit(cUnit); //Errors are discarded } if (dummyCompilation) return; //Now analyze the given file for errors Checker checker = new Checker(ssCompilation, errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels); checker.currentAssembly = (checker.currentModule = symbolTable) as AssemblyNode; checker.VisitAttributeList(assemblyAttributes, checker.currentAssembly); checker.VisitModuleAttributes(moduleAttributes); checker.VisitCompilationUnit(cuSnippet); MemberFinder finder = new MemberFinder(line, col); finder.VisitCompilationUnit(cuSnippet); Node node = finder.Member; if (node == null){ if (line == 0 && col == 0) node = cuSnippet; else return; } SpecSharpCompilerOptions options = (SpecSharpCompilerOptions) compilation.CompilerParameters; if (options.IsContractAssembly) return; ssCompilation.RunPlugins(node, errorHandler); Normalizer normalizer = new Normalizer(typeSystem); normalizer.Visit(node); Analyzer analyzer = new Analyzer(typeSystem, compilation); analyzer.Visit(node); if (options.RunProgramVerifierWhileEditing) ssCompilation.AddProgramVerifierPlugin(typeSystem, compilation); ssCompilation.analyzer = analyzer; // make the analyzer available to plugins for access to method CFGs ssCompilation.RunPlugins(node, errorHandler); ssCompilation.analyzer = null; analyzer = null; }