public virtual void ConstructSymbolTable(Compilation compilation, ErrorNodeList errors, TrivialHashtable scopeFor){ if (compilation == null || scopeFor == null){Debug.Assert(false); return;} this.CurrentCompilation = compilation; Module symbolTable = compilation.TargetModule = this.CreateModule(compilation.CompilerParameters, errors, compilation); Scoper scoper = new Scoper(scopeFor); scoper.currentModule = symbolTable; ErrorHandler errorHandler = new ErrorHandler(errors); Looker looker = new Looker(this.GetGlobalScope(symbolTable), errorHandler, scopeFor); // begin change by drunje SpecSharpCompilerOptions options = compilation.CompilerParameters as SpecSharpCompilerOptions; if (options != null) looker.AllowPointersToManagedStructures = options.AllowPointersToManagedStructures; // end change by drunje looker.currentAssembly = (looker.currentModule = symbolTable) as AssemblyNode; looker.ignoreMethodBodies = true; Scope globalScope = compilation.GlobalScope = this.GetGlobalScope(symbolTable); CompilationUnitList sources = compilation.CompilationUnits; if (sources == null) return; int n = sources.Count; for (int i = 0; i < n; i++){ CompilationUnitSnippet compilationUnitSnippet = sources[i] as CompilationUnitSnippet; if (compilationUnitSnippet == null){Debug.Assert(false); continue;} compilationUnitSnippet.ChangedMethod = null; Document doc = compilationUnitSnippet.SourceContext.Document; if (doc == null || doc.Text == null){Debug.Assert(false); continue;} IParserFactory factory = compilationUnitSnippet.ParserFactory; if (factory == null){Debug.Assert(false); return;} IParser p = factory.CreateParser(doc.Name, doc.LineNumber, doc.Text, symbolTable, errors, compilation.CompilerParameters); if (p is ResgenCompilerStub) continue; if (p == null){Debug.Assert(false); continue;} Parser specSharpParser = p as Parser; if (specSharpParser == null) p.ParseCompilationUnit(compilationUnitSnippet); else specSharpParser.ParseCompilationUnit(compilationUnitSnippet, true, 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); //else if (doc.Text.TextProvider != null) // doc.Text.TextProvider.MakeCollectible(); } CompilationUnitList compilationUnits = new CompilationUnitList(); for (int i = 0; i < n; i++){ CompilationUnit cUnit = sources[i]; compilationUnits.Add(scoper.VisitCompilationUnit(cUnit)); } for (int i = 0; i < n; i++){ CompilationUnit cUnit = compilationUnits[i]; if (cUnit == null) continue; looker.VisitCompilationUnit(cUnit); } //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; for (int i = 0; i < n; i++) { CompilationUnit cUnit = compilationUnits[i]; if (cUnit == null) continue; resolver.VisitCompilationUnit(cUnit); } this.CurrentCompilation = null; }
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; }