IEnumerable <EmbeddedText> CollectAdditionalEmbeddedTexts() { // TODO: if (EmbedPharContentIntoPdb): foreach (var f in this.SourceSymbolCollection.GetFiles()) { var tree = f.SyntaxTree; var fname = tree.FilePath; if (f.SyntaxTree.IsPharEntry) // embed phar entry { // ok, fname is already a virtual file path of the phar entry } else if (fname.IsPharFile()) // embed phar stub { fname = PhpFileUtilities.BuildPharStubFileName(fname); // virtual file name for the phar stub entry } else { continue; // not embedded into PDB } yield return(EmbeddedText.FromSource(fname, tree.GetText())); } }
/// <summary> /// Generates method body that calls another method. /// Used for wrapping a method call into a method, e.g. an entry point. /// </summary> internal static MethodBody GenerateMethodBody( PEModuleBuilder moduleBuilder, MethodSymbol routine, Action <ILBuilder> builder, VariableSlotAllocator variableSlotAllocatorOpt, DiagnosticBag diagnostics, bool emittingPdb) { var compilation = moduleBuilder.Compilation; var localSlotManager = new LocalSlotManager(variableSlotAllocatorOpt); var optimizations = compilation.Options.OptimizationLevel; DebugDocumentProvider debugDocumentProvider = null; if (emittingPdb) { debugDocumentProvider = (path, basePath) => { if (path.IsPharFile()) { path = PhpFileUtilities.BuildPharStubFileName(path); } return(moduleBuilder.DebugDocumentsBuilder.GetOrAddDebugDocument( path, basePath, normalizedPath => CreateDebugSourceDocument(normalizedPath, routine))); }; } ILBuilder il = new ILBuilder(moduleBuilder, localSlotManager, optimizations.AsOptimizationLevel()); try { StateMachineMoveNextBodyDebugInfo stateMachineMoveNextDebugInfo = null; builder(il); // il.Realize(); // var localVariables = il.LocalSlotManager.LocalsInOrder(); if (localVariables.Length > 0xFFFE) { //diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First()); } //if (diagnosticsForThisMethod.HasAnyErrors()) //{ // // we are done here. Since there were errors we should not emit anything. // return null; //} //// We will only save the IL builders when running tests. //if (moduleBuilder.SaveTestData) //{ // moduleBuilder.SetMethodTestData(method, builder.GetSnapshot()); //} // Only compiler-generated MoveNext methods have iterator scopes. See if this is one. var stateMachineHoistedLocalScopes = default(ImmutableArray <StateMachineHoistedLocalScope>); //if (isStateMachineMoveNextMethod) //{ // stateMachineHoistedLocalScopes = builder.GetHoistedLocalScopes(); //} var stateMachineHoistedLocalSlots = default(ImmutableArray <EncHoistedLocalInfo>); var stateMachineAwaiterSlots = default(ImmutableArray <Cci.ITypeReference>); //if (optimizations == OptimizationLevel.Debug && stateMachineTypeOpt != null) //{ // Debug.Assert(method.IsAsync || method.IsIterator); // GetStateMachineSlotDebugInfo(moduleBuilder, moduleBuilder.GetSynthesizedFields(stateMachineTypeOpt), variableSlotAllocatorOpt, diagnosticsForThisMethod, out stateMachineHoistedLocalSlots, out stateMachineAwaiterSlots); // Debug.Assert(!diagnostics.HasAnyErrors()); //} return(new MethodBody( il.RealizedIL, il.MaxStack, (Cci.IMethodDefinition)routine.PartialDefinitionPart ?? routine, variableSlotAllocatorOpt?.MethodId ?? new DebugId(0, moduleBuilder.CurrentGenerationOrdinal), localVariables, il.RealizedSequencePoints, debugDocumentProvider, il.RealizedExceptionHandlers, il.GetAllScopes(), il.HasDynamicLocal, null, // importScopeOpt, ImmutableArray <LambdaDebugInfo> .Empty, // lambdaDebugInfo, ImmutableArray <ClosureDebugInfo> .Empty, // closureDebugInfo, null, //stateMachineTypeOpt?.Name, stateMachineHoistedLocalScopes, stateMachineHoistedLocalSlots, stateMachineAwaiterSlots, stateMachineMoveNextDebugInfo, null)); // dynamicAnalysisDataOpt } finally { // Basic blocks contain poolable builders for IL and sequence points. Free those back // to their pools. il.FreeBasicBlocks(); //// Remember diagnostics. //diagnostics.AddRange(diagnosticsForThisMethod); //diagnosticsForThisMethod.Free(); } }
/// <summary> /// Gets file path for the debug document and embedded text feature. /// In most cases it is equivalent to <see cref="FilePath"/>, /// in synthesized stubs (phar stub) it may be a generated file name. /// </summary> public string GetDebugSourceDocumentPath() => IsPharStub?PhpFileUtilities.BuildPharStubFileName(FilePath) : FilePath;