提交 f97fbbef 编写于 作者: C ChuckStoner 提交者: RoslynTeam

ENC: Move ENC implementation to specific namespace (.Emit) and subdirectory...

ENC: Move ENC implementation to specific namespace (.Emit) and subdirectory (Emit\EditAndContinue) within each project (changeset 1214011)
上级 7a599fa3
......@@ -223,7 +223,6 @@
<Compile Include="Compilation\AwaitExpressionInfo.cs" />
<Compile Include="Compilation\BuiltInOperators.cs" />
<Compile Include="Compilation\CSharpCompilation.cs" />
<Compile Include="Compilation\CSharpCompilation.DefinitionMap.cs" />
<Compile Include="Compilation\CSharpCompilationReference.cs" />
<Compile Include="Compilation\CSharpSemanticModel.cs" />
<Compile Include="Compilation\ForEachStatementInfo.cs" />
......@@ -237,7 +236,6 @@
<Compile Include="Compilation\QueryClauseInfo.cs" />
<Compile Include="Compilation\SpeculativeSyntaxTreeSemanticModel.cs" />
<Compile Include="Compilation\SymbolInfoFactory.cs" />
<Compile Include="Compilation\SymbolMatcher.cs" />
<Compile Include="Compilation\SyntaxTreeSemanticModel.cs" />
<Compile Include="Compilation\SyntaxTreeSemanticModel_RegionAnalysisContext.cs" />
<Compile Include="Compilation\TypeInfo.cs" />
......@@ -281,6 +279,10 @@
<Compile Include="DocumentationComments\DocumentationCommentIDVisitor.PartVisitor.cs" />
<Compile Include="DocumentationComments\PEDocumentationCommentUtils.cs" />
<Compile Include="DocumentationComments\SourceDocumentationCommentUtils.cs" />
<Compile Include="Emitter\EditAndContinue\DefinitionMap.cs" />
<Compile Include="Emitter\EditAndContinue\EmitHelpers.cs" />
<Compile Include="Emitter\EditAndContinue\PEDeltaAssemblyBuilder.cs" />
<Compile Include="Emitter\EditAndContinue\SymbolMatcher.cs" />
<Compile Include="Emitter\Model\ArrayTypeSymbolAdapter.cs" />
<Compile Include="Emitter\Model\AssemblyReference.cs" />
<Compile Include="Emitter\Model\AttributeDataAdapter.cs" />
......@@ -304,7 +306,6 @@
</Compile>
<Compile Include="Emitter\Model\ParameterTypeInformation.cs" />
<Compile Include="Emitter\Model\PEAssemblyBuilder.cs" />
<Compile Include="Emitter\Model\PEDeltaAssemblyBuilder.cs" />
<Compile Include="Emitter\Model\PEModuleBuilder.cs" />
<Compile Include="Emitter\Model\PENetModuleBuilder.cs" />
<Compile Include="Emitter\Model\PointerTypeSymbolAdapter.cs" />
......
......@@ -2218,9 +2218,9 @@ internal override FunctionId EmitFunctionId
get { return FunctionId.CSharp_Compilation_Emit; }
}
internal override EmitResult MakeEmitResult(bool success, ImmutableArray<Diagnostic> diagnostics, Microsoft.CodeAnalysis.Emit.EmitBaseline baseline = null)
internal override EmitResult MakeEmitResult(bool success, ImmutableArray<Diagnostic> diagnostics)
{
return new EmitResult(success, diagnostics.Cast<Diagnostic>().AsImmutable(), baseline);
return new EmitResult(success, diagnostics.Cast<Diagnostic>().AsImmutable());
}
/// <summary>
......@@ -2335,9 +2335,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
Func<IAssemblySymbol, AssemblyIdentity> assemblySymbolMapper,
CancellationToken cancellationToken,
CompilationTestData testData,
DiagnosticBag diagnosticBag,
Microsoft.CodeAnalysis.Emit.EmitBaseline previousGeneration,
IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits,
DiagnosticBag diagnostics,
ref bool hasDeclarationErrors)
{
return this.CreateModuleBuilder(
......@@ -2348,9 +2346,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
ImmutableArray<NamedTypeSymbol>.Empty,
cancellationToken,
testData,
diagnosticBag,
previousGeneration,
edits,
diagnostics,
ref hasDeclarationErrors);
}
......@@ -2362,15 +2358,13 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
ImmutableArray<NamedTypeSymbol> additionalTypes,
CancellationToken cancellationToken,
CompilationTestData testData,
DiagnosticBag diagnosticBag,
Microsoft.CodeAnalysis.Emit.EmitBaseline previousGeneration,
IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits,
DiagnosticBag diagnostics,
ref bool hasDeclarationErrors)
{
// The diagnostics should include syntax and declaration errors also. We insert these before calling Emitter.Emit, so that the emitter
// does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...)
if (!FilterAndAppendDiagnostics(
diagnosticBag,
diagnostics,
GetDiagnostics(CompilationStage.Declare, true, cancellationToken),
this.options))
{
......@@ -2384,20 +2378,10 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
return null;
}
string runtimeMDVersion = GetRuntimeMetadataVersion();
string runtimeMDVersion = GetRuntimeMetadataVersion(diagnostics);
if (runtimeMDVersion == null)
{
DiagnosticBag runtimeMDVersionDiagnostics = DiagnosticBag.GetInstance();
runtimeMDVersionDiagnostics.Add(ErrorCode.WRN_NoRuntimeMetadataVersion, NoLocation.Singleton);
if (!FilterAndAppendAndFreeDiagnostics(diagnosticBag, ref runtimeMDVersionDiagnostics))
{
return null;
}
runtimeMDVersion = String.Empty; //prevent emitter from crashing.
return null;
}
var moduleProps = ConstructModuleSerializationProperties(runtimeMDVersion, moduleVersionId);
......@@ -2411,8 +2395,6 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
if (options.OutputKind.IsNetModule())
{
Debug.Assert(additionalTypes.IsEmpty);
Debug.Assert(previousGeneration == null);
Debug.Assert(edits == null);
moduleBeingBuilt = new PENetModuleBuilder(
(SourceModuleSymbol)SourceModule,
......@@ -2423,30 +2405,14 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
else
{
var kind = options.OutputKind.IsValid() ? options.OutputKind : OutputKind.DynamicallyLinkedLibrary;
if (previousGeneration == null)
{
moduleBeingBuilt = new PEAssemblyBuilder(
SourceAssembly,
outputName,
kind,
moduleProps,
manifestResources,
assemblySymbolMapper,
additionalTypes);
}
else
{
moduleBeingBuilt = new PEDeltaAssemblyBuilder(
SourceAssembly,
outputName,
kind,
moduleProps,
manifestResources,
assemblySymbolMapper,
additionalTypes,
previousGeneration,
edits);
}
moduleBeingBuilt = new PEAssemblyBuilder(
SourceAssembly,
outputName,
kind,
moduleProps,
manifestResources,
assemblySymbolMapper,
additionalTypes);
}
// testData is only passed when running tests.
......@@ -2468,7 +2434,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
CancellationToken cancellationToken,
bool metadataOnly,
bool generateDebugInfo,
DiagnosticBag diagnosticBag,
DiagnosticBag diagnostics,
Predicate<ISymbol> filter,
bool hasDeclarationErrors)
{
......@@ -2513,7 +2479,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
// If there are clashes with debug documents that came from actual trees, ignore the pragma.
foreach (var tree in this.syntaxTrees)
{
AddDebugSourceDocumentsForChecksumDirectives(moduleBeingBuilt, tree, diagnosticBag);
AddDebugSourceDocumentsForChecksumDirectives(moduleBeingBuilt, tree, diagnostics);
}
}
......@@ -2541,7 +2507,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
AddedModulesResourceNames(methodBodyDiagnosticBag),
methodBodyDiagnosticBag);
bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnosticBag, ref methodBodyDiagnosticBag);
bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag);
if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError)
{
......@@ -2555,7 +2521,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance();
DocumentationCommentCompiler.WriteDocumentationCommentXml(this, outputName, xmlDocStream, xmlDiagnostics, cancellationToken);
if (!FilterAndAppendAndFreeDiagnostics(diagnosticBag, ref xmlDiagnostics))
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics))
{
return false;
}
......@@ -2564,7 +2530,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
DiagnosticBag importDiagnostics = DiagnosticBag.GetInstance();
this.ReportUnusedImports(importDiagnostics, cancellationToken);
if (!FilterAndAppendAndFreeDiagnostics(diagnosticBag, ref importDiagnostics))
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref importDiagnostics))
{
Debug.Assert(false, "Should never produce an error");
return false;
......@@ -2599,102 +2565,44 @@ private IEnumerable<string> AddedModulesResourceNames(DiagnosticBag diagnostics)
}
}
internal override Microsoft.CodeAnalysis.Emit.EmitBaseline MapToCompilation(
CommonPEModuleBuilder moduleBeingBuilt)
internal override EmitDifferenceResult EmitDifference(
EmitBaseline baseline,
IEnumerable<SemanticEdit> edits,
Stream metadataStream,
Stream ilStream,
Stream pdbStream,
ICollection<uint> updatedMethodTokens,
CompilationTestData testData,
CancellationToken cancellationToken)
{
var previousGeneration = moduleBeingBuilt.PreviousGeneration;
Debug.Assert(previousGeneration.Compilation != this);
if (previousGeneration.Ordinal == 0)
{
// Initial generation, nothing to map. (Since the initial generation
// is always loaded from metadata in the context of the current
// compilation, there's no separate mapping step.)
return previousGeneration;
}
var map = new SymbolMatcher(
moduleBeingBuilt.GetAnonymousTypeMap(),
((CSharpCompilation)previousGeneration.Compilation).SourceAssembly,
new Microsoft.CodeAnalysis.Emit.Context((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag()),
this.SourceAssembly,
new Microsoft.CodeAnalysis.Emit.Context((Cci.IModule)moduleBeingBuilt, null, new DiagnosticBag()));
// Map all definitions to this compilation.
var typesAdded = MapDefinitions(map, previousGeneration.TypesAdded);
var eventsAdded = MapDefinitions(map, previousGeneration.EventsAdded);
var fieldsAdded = MapDefinitions(map, previousGeneration.FieldsAdded);
var methodsAdded = MapDefinitions(map, previousGeneration.MethodsAdded);
var propertiesAdded = MapDefinitions(map, previousGeneration.PropertiesAdded);
return EmitHelpers.EmitDifference(
this,
baseline,
edits,
metadataStream,
ilStream,
pdbStream,
updatedMethodTokens,
testData,
cancellationToken);
}
// Map anonymous types to this compilation.
var anonymousTypeMap = new Dictionary<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue>();
foreach (var pair in previousGeneration.AnonymousTypeMap)
internal string GetRuntimeMetadataVersion(DiagnosticBag diagnostics)
{
string runtimeMDVersion = GetRuntimeMetadataVersion();
if (runtimeMDVersion != null)
{
var key = pair.Key;
var value = pair.Value;
var type = (Cci.ITypeDefinition)map.MapDefinition(value.Type);
Debug.Assert(type != null);
anonymousTypeMap.Add(key, new Microsoft.CodeAnalysis.Emit.AnonymousTypeValue(value.Name, value.UniqueIndex, type));
return runtimeMDVersion;
}
// Map locals (specifically, local types) to this compilation.
var locals = new Dictionary<uint, ImmutableArray<Microsoft.CodeAnalysis.Emit.EncLocalInfo>>();
foreach (var pair in previousGeneration.LocalsForMethodsAddedOrChanged)
DiagnosticBag runtimeMDVersionDiagnostics = DiagnosticBag.GetInstance();
runtimeMDVersionDiagnostics.Add(ErrorCode.WRN_NoRuntimeMetadataVersion, NoLocation.Singleton);
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref runtimeMDVersionDiagnostics))
{
locals.Add(pair.Key, pair.Value.SelectAsArray((l, m) => MapLocalInfo(m, l), map));
}
return previousGeneration.With(
this,
moduleBeingBuilt,
previousGeneration.Ordinal,
previousGeneration.EncId,
typesAdded,
eventsAdded,
fieldsAdded,
methodsAdded,
propertiesAdded,
previousGeneration.EventMapAdded,
previousGeneration.PropertyMapAdded,
previousGeneration.TableEntriesAdded,
blobStreamLengthAdded: previousGeneration.BlobStreamLengthAdded,
stringStreamLengthAdded: previousGeneration.StringStreamLengthAdded,
userStringStreamLengthAdded: previousGeneration.UserStringStreamLengthAdded,
guidStreamLengthAdded: previousGeneration.GuidStreamLengthAdded,
anonymousTypeMap: anonymousTypeMap,
localsForMethodsAddedOrChanged: locals,
localNames: previousGeneration.LocalNames);
}
private static IReadOnlyDictionary<K, V> MapDefinitions<K, V>(
SymbolMatcher map,
IReadOnlyDictionary<K, V> items)
where K : Cci.IDefinition
{
var result = new Dictionary<K, V>();
foreach (var pair in items)
{
var key = (K)map.MapDefinition(pair.Key);
// Result may be null if the definition was deleted, or if the definition
// was synthesized (e.g.: an iterator type) and the method that generated
// the synthesized definition was unchanged and not recompiled.
if (key != null)
{
result.Add(key, pair.Value);
}
return null;
}
return result;
}
private static Microsoft.CodeAnalysis.Emit.EncLocalInfo MapLocalInfo(
SymbolMatcher map,
Microsoft.CodeAnalysis.Emit.EncLocalInfo localInfo)
{
Debug.Assert(!localInfo.IsDefault);
var type = map.MapReference(localInfo.Type);
Debug.Assert(type != null);
return new Microsoft.CodeAnalysis.Emit.EncLocalInfo(localInfo.Offset, type, localInfo.Constraints, localInfo.TempKind);
return string.Empty; //prevent emitter from crashing.
}
private string GetRuntimeMetadataVersion()
......@@ -2712,7 +2620,7 @@ private string GetRuntimeMetadataVersion()
private static void AddDebugSourceDocumentsForChecksumDirectives(
PEModuleBuilder moduleBeingBuilt,
SyntaxTree tree,
DiagnosticBag diagnosticBag)
DiagnosticBag diagnostics)
{
var checksumDirectives = tree.GetRoot().GetDirectives(d => d.Kind == SyntaxKind.PragmaChecksumDirectiveTrivia &&
!d.ContainsDiagnostics);
......@@ -2751,7 +2659,7 @@ private string GetRuntimeMetadataVersion()
// did not match to an existing document
// produce a warning and ignore the pragma
diagnosticBag.Add(ErrorCode.WRN_ConflictingChecksum, new SourceLocation(checkSumDirective), path);
diagnostics.Add(ErrorCode.WRN_ConflictingChecksum, new SourceLocation(checkSumDirective), path);
}
else
{
......
......@@ -164,25 +164,7 @@ internal static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModu
bool emitSequencePoints = !namespaceScopes.IsDefault && !method.IsAsync;
var module = compilationState.ModuleBuilder;
var compilation = module.Compilation;
LocalSlotManager localSlotManager;
var previousGeneration = module.PreviousGeneration;
if (previousGeneration == null)
{
localSlotManager = new FullLocalSlotManager();
}
else
{
var previousDefinitions = module.PreviousDefinitions;
ImmutableArray<Microsoft.CodeAnalysis.Emit.EncLocalInfo> previousLocals;
GetPreviousLocalSlot getPreviousLocalSlot;
if (!previousDefinitions.TryGetPreviousLocals(previousGeneration, method, out previousLocals, out getPreviousLocalSlot))
{
previousLocals = ImmutableArray<Microsoft.CodeAnalysis.Emit.EncLocalInfo>.Empty;
}
Debug.Assert(getPreviousLocalSlot != null);
localSlotManager = new EncLocalSlotManager(previousLocals, getPreviousLocalSlot);
}
var localSlotManager = module.CreateLocalSlotManager(method);
ILBuilder builder = new ILBuilder(module, localSlotManager, optimize);
DiagnosticBag diagnosticsForThisMethod = DiagnosticBag.GetInstance();
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace Microsoft.CodeAnalysis.CSharp.Emit
{
internal static class EmitHelpers
{
internal static EmitDifferenceResult EmitDifference(
CSharpCompilation compilation,
EmitBaseline baseline,
IEnumerable<SemanticEdit> edits,
Stream metadataStream,
Stream ilStream,
Stream pdbStream,
ICollection<uint> updatedMethodTokens,
CompilationTestData testData,
CancellationToken cancellationToken)
{
Guid moduleVersionId;
try
{
moduleVersionId = baseline.OriginalMetadata.GetModuleVersionId();
}
catch (BadImageFormatException)
{
// return MakeEmitResult(success: false, diagnostics: ..., baseline: null);
throw;
}
var pdbName = PathUtilities.ChangeExtension(compilation.SourceModule.Name, "pdb");
using (var pdbWriter = new Cci.PdbWriter(pdbName, new ComStreamWrapper(pdbStream)))
{
var diagnostics = DiagnosticBag.GetInstance();
string runtimeMDVersion = compilation.GetRuntimeMetadataVersion(diagnostics);
var serializationProperties = compilation.ConstructModuleSerializationProperties(runtimeMDVersion, moduleVersionId);
var manifestResources = SpecializedCollections.EmptyEnumerable<ResourceDescription>();
var moduleBeingBuilt = new PEDeltaAssemblyBuilder(
compilation.SourceAssembly,
outputName: null,
outputKind: compilation.Options.OutputKind,
serializationProperties: serializationProperties,
manifestResources: manifestResources,
assemblySymbolMapper: null,
previousGeneration: baseline,
edits: edits);
if (testData != null)
{
moduleBeingBuilt.SetMethodTestData(testData.Methods);
testData.Module = moduleBeingBuilt;
}
baseline = moduleBeingBuilt.PreviousGeneration;
var definitionMap = moduleBeingBuilt.PreviousDefinitions;
var changes = moduleBeingBuilt.Changes;
if (compilation.Compile(
moduleBeingBuilt,
outputName: null,
manifestResources: manifestResources,
win32Resources: null,
xmlDocStream: null,
cancellationToken: cancellationToken,
metadataOnly: false,
generateDebugInfo: true,
diagnostics: diagnostics,
filter: changes.HasChanged,
hasDeclarationErrors: false))
{
var context = new Context((Cci.IModule)moduleBeingBuilt, null, diagnostics);
// Map the definitions from the previous compilation to the current compilation.
// This must be done after compiling above since synthesized definitions
// (generated when compiling method bodies) may be required.
baseline = MapToCompilation(compilation, moduleBeingBuilt);
var encId = Guid.NewGuid();
var writer = new DeltaPeWriter(
context,
compilation.MessageProvider,
pdbWriter,
baseline,
encId,
definitionMap,
changes,
cancellationToken);
writer.WriteMetadataAndIL(metadataStream, ilStream);
writer.GetMethodTokens(updatedMethodTokens);
return new EmitDifferenceResult(
success: true,
diagnostics: diagnostics.ToReadOnlyAndFree(),
baseline: writer.GetDelta(baseline, compilation, encId));
}
return new EmitDifferenceResult(success: false, diagnostics: diagnostics.ToReadOnlyAndFree(), baseline: null);
}
}
/// <summary>
/// Return a version of the baseline with all definitions mapped to this compilation.
/// Definitions from the initial generation, from metadata, are not mapped since
/// the initial generation is always included as metadata. That is, the symbols from
/// types, methods, ... in the TypesAdded, MethodsAdded, ... collections are replaced
/// by the corresponding symbols from the current compilation.
/// </summary>
private static EmitBaseline MapToCompilation(
CSharpCompilation compilation,
PEDeltaAssemblyBuilder moduleBeingBuilt)
{
var previousGeneration = moduleBeingBuilt.PreviousGeneration;
Debug.Assert(previousGeneration.Compilation != compilation);
if (previousGeneration.Ordinal == 0)
{
// Initial generation, nothing to map. (Since the initial generation
// is always loaded from metadata in the context of the current
// compilation, there's no separate mapping step.)
return previousGeneration;
}
var map = new SymbolMatcher(
moduleBeingBuilt.GetAnonymousTypeMap(),
((CSharpCompilation)previousGeneration.Compilation).SourceAssembly,
new Context((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag()),
compilation.SourceAssembly,
new Context((Cci.IModule)moduleBeingBuilt, null, new DiagnosticBag()));
// Map all definitions to this compilation.
var typesAdded = MapDefinitions(map, previousGeneration.TypesAdded);
var eventsAdded = MapDefinitions(map, previousGeneration.EventsAdded);
var fieldsAdded = MapDefinitions(map, previousGeneration.FieldsAdded);
var methodsAdded = MapDefinitions(map, previousGeneration.MethodsAdded);
var propertiesAdded = MapDefinitions(map, previousGeneration.PropertiesAdded);
// Map anonymous types to this compilation.
var anonymousTypeMap = new Dictionary<AnonymousTypeKey, AnonymousTypeValue>();
foreach (var pair in previousGeneration.AnonymousTypeMap)
{
var key = pair.Key;
var value = pair.Value;
var type = (Cci.ITypeDefinition)map.MapDefinition(value.Type);
Debug.Assert(type != null);
anonymousTypeMap.Add(key, new AnonymousTypeValue(value.Name, value.UniqueIndex, type));
}
// Map locals (specifically, local types) to this compilation.
var locals = new Dictionary<uint, ImmutableArray<EncLocalInfo>>();
foreach (var pair in previousGeneration.LocalsForMethodsAddedOrChanged)
{
locals.Add(pair.Key, pair.Value.SelectAsArray((l, m) => MapLocalInfo(m, l), map));
}
return previousGeneration.With(
compilation,
moduleBeingBuilt,
previousGeneration.Ordinal,
previousGeneration.EncId,
typesAdded,
eventsAdded,
fieldsAdded,
methodsAdded,
propertiesAdded,
previousGeneration.EventMapAdded,
previousGeneration.PropertyMapAdded,
previousGeneration.TableEntriesAdded,
blobStreamLengthAdded: previousGeneration.BlobStreamLengthAdded,
stringStreamLengthAdded: previousGeneration.StringStreamLengthAdded,
userStringStreamLengthAdded: previousGeneration.UserStringStreamLengthAdded,
guidStreamLengthAdded: previousGeneration.GuidStreamLengthAdded,
anonymousTypeMap: anonymousTypeMap,
localsForMethodsAddedOrChanged: locals,
localNames: previousGeneration.LocalNames);
}
private static IReadOnlyDictionary<K, V> MapDefinitions<K, V>(
SymbolMatcher map,
IReadOnlyDictionary<K, V> items)
where K : Cci.IDefinition
{
var result = new Dictionary<K, V>();
foreach (var pair in items)
{
var key = (K)map.MapDefinition(pair.Key);
// Result may be null if the definition was deleted, or if the definition
// was synthesized (e.g.: an iterator type) and the method that generated
// the synthesized definition was unchanged and not recompiled.
if (key != null)
{
result.Add(key, pair.Value);
}
}
return result;
}
private static EncLocalInfo MapLocalInfo(
SymbolMatcher map,
EncLocalInfo localInfo)
{
Debug.Assert(!localInfo.IsDefault);
var type = map.MapReference(localInfo.Type);
Debug.Assert(type != null);
return new EncLocalInfo(localInfo.Offset, type, localInfo.Constraints, localInfo.TempKind);
}
}
}
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Symbols;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.Emit;
namespace Microsoft.CodeAnalysis.CSharp.Emit
{
internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase
internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase, IPEDeltaAssemblyBuilder
{
private readonly Microsoft.CodeAnalysis.Emit.EmitBaseline previousGeneration;
private readonly CSharpCompilation.DefinitionMap previousDefinitions;
private readonly Microsoft.CodeAnalysis.Emit.SymbolChanges changes;
private readonly EmitBaseline previousGeneration;
private readonly DefinitionMap previousDefinitions;
private readonly SymbolChanges changes;
public PEDeltaAssemblyBuilder(
SourceAssemblySymbol sourceAssembly,
......@@ -23,12 +25,11 @@ internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase
ModulePropertiesForSerialization serializationProperties,
IEnumerable<ResourceDescription> manifestResources,
Func<AssemblySymbol, AssemblyIdentity> assemblySymbolMapper,
ImmutableArray<NamedTypeSymbol> additionalTypes,
Microsoft.CodeAnalysis.Emit.EmitBaseline previousGeneration,
IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits)
: base(sourceAssembly, outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper, additionalTypes)
EmitBaseline previousGeneration,
IEnumerable<SemanticEdit> edits)
: base(sourceAssembly, outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper, additionalTypes: ImmutableArray<NamedTypeSymbol>.Empty)
{
var context = new Microsoft.CodeAnalysis.Emit.Context(this, null, new DiagnosticBag());
var context = new Context(this, null, new DiagnosticBag());
var module = previousGeneration.OriginalMetadata;
var compilation = sourceAssembly.DeclaringCompilation;
var metadataAssembly = compilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(module), MetadataImportOptions.All);
......@@ -42,20 +43,20 @@ internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase
if (previousGeneration.Ordinal > 0)
{
var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
var previousContext = new Microsoft.CodeAnalysis.Emit.Context((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());
var previousContext = new Context((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());
matchToPrevious = new SymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, previousAssembly, previousContext);
}
this.previousDefinitions = new CSharpCompilation.DefinitionMap(previousGeneration.OriginalMetadata.Module, metadataDecoder, matchToMetadata, matchToPrevious, GenerateMethodMap(edits));
this.previousDefinitions = new DefinitionMap(previousGeneration.OriginalMetadata.Module, metadataDecoder, matchToMetadata, matchToPrevious, GenerateMethodMap(edits));
this.previousGeneration = previousGeneration;
this.changes = new Microsoft.CodeAnalysis.Emit.SymbolChanges(this.previousDefinitions, edits);
this.changes = new SymbolChanges(this.previousDefinitions, edits);
}
private static IReadOnlyDictionary<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue> GetAnonymousTypeMap(
private static IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMap(
MetadataReader reader,
Symbols.Metadata.PE.MetadataDecoder metadataDecoder)
{
var result = new Dictionary<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue>();
var result = new Dictionary<AnonymousTypeKey, AnonymousTypeValue>();
foreach (var handle in reader.TypeDefinitions)
{
var def = reader.GetTypeDefinition(handle);
......@@ -77,8 +78,8 @@ internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase
if (TryGetAnonymousTypeKey(reader, def, builder))
{
var type = (NamedTypeSymbol)metadataDecoder.GetTypeOfToken(handle);
var key = new Microsoft.CodeAnalysis.Emit.AnonymousTypeKey(builder.ToImmutable());
var value = new Microsoft.CodeAnalysis.Emit.AnonymousTypeValue(name, index, type);
var key = new AnonymousTypeKey(builder.ToImmutable());
var value = new AnonymousTypeValue(name, index, type);
result.Add(key, value);
}
builder.Free();
......@@ -105,8 +106,8 @@ internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase
return true;
}
private static Microsoft.CodeAnalysis.Emit.EmitBaseline EnsureInitialized(
Microsoft.CodeAnalysis.Emit.EmitBaseline previousGeneration,
private static EmitBaseline EnsureInitialized(
EmitBaseline previousGeneration,
Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.MetadataDecoder metadataDecoder)
{
if (previousGeneration.AnonymousTypeMap != null)
......@@ -137,12 +138,12 @@ internal sealed class PEDeltaAssemblyBuilder : PEAssemblyBuilderBase
localNames: previousGeneration.LocalNames);
}
internal override Microsoft.CodeAnalysis.Emit.EmitBaseline PreviousGeneration
internal EmitBaseline PreviousGeneration
{
get { return this.previousGeneration; }
}
internal override Microsoft.CodeAnalysis.Emit.DefinitionMap PreviousDefinitions
internal DefinitionMap PreviousDefinitions
{
get { return this.previousDefinitions; }
}
......@@ -157,7 +158,7 @@ internal override bool SupportsPrivateImplClass
}
}
internal override IReadOnlyDictionary<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue> GetAnonymousTypeMap()
public IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMap()
{
var anonymousTypes = this.Compilation.AnonymousTypeManager.GetAnonymousTypeMap();
// Should contain all entries in previous generation.
......@@ -165,23 +166,45 @@ internal override bool SupportsPrivateImplClass
return anonymousTypes;
}
internal override LocalSlotManager CreateLocalSlotManager(MethodSymbol method)
{
ImmutableArray<EncLocalInfo> previousLocals;
GetPreviousLocalSlot getPreviousLocalSlot;
if (!this.previousDefinitions.TryGetPreviousLocals(this.previousGeneration, method, out previousLocals, out getPreviousLocalSlot))
{
previousLocals = ImmutableArray<EncLocalInfo>.Empty;
}
Debug.Assert(getPreviousLocalSlot != null);
return new EncLocalSlotManager(previousLocals, getPreviousLocalSlot);
}
internal override ImmutableArray<AnonymousTypeKey> GetPreviousAnonymousTypes()
{
return ImmutableArray.CreateRange(this.previousGeneration.AnonymousTypeMap.Keys);
}
internal override int GetNextAnonymousTypeIndex()
{
return this.previousGeneration.GetNextAnonymousTypeIndex();
}
internal override bool TryGetAnonymousTypeName(NamedTypeSymbol template, out string name, out int index)
{
Debug.Assert(this.Compilation == template.DeclaringCompilation);
return this.previousDefinitions.TryGetAnonymousTypeName(template, out name, out index);
}
internal override Microsoft.CodeAnalysis.Emit.SymbolChanges Changes
internal SymbolChanges Changes
{
get { return this.changes; }
}
internal override IEnumerable<Cci.INamespaceTypeDefinition> GetTopLevelTypesCore(Microsoft.CodeAnalysis.Emit.Context context)
internal override IEnumerable<Cci.INamespaceTypeDefinition> GetTopLevelTypesCore(Context context)
{
return this.changes.GetTopLevelTypes(context);
}
internal override void OnCreatedIndices(DiagnosticBag diagnostics)
public void OnCreatedIndices(DiagnosticBag diagnostics)
{
var embeddedTypesManager = this.EmbeddedTypesManagerOpt;
if (embeddedTypesManager != null)
......@@ -198,9 +221,9 @@ internal override bool IsENCDelta
get { return true; }
}
private static IReadOnlyDictionary<MethodSymbol, CSharpCompilation.MethodDefinitionEntry> GenerateMethodMap(IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits)
private static IReadOnlyDictionary<MethodSymbol, MethodDefinitionEntry> GenerateMethodMap(IEnumerable<SemanticEdit> edits)
{
var methodMap = new Dictionary<MethodSymbol, CSharpCompilation.MethodDefinitionEntry>();
var methodMap = new Dictionary<MethodSymbol, MethodDefinitionEntry>();
foreach (var edit in edits)
{
if (edit.Kind == CodeAnalysis.Emit.SemanticEditKind.Update)
......@@ -208,7 +231,7 @@ internal override bool IsENCDelta
var method = edit.NewSymbol as MethodSymbol;
if ((object)method != null)
{
methodMap.Add(method, new CSharpCompilation.MethodDefinitionEntry(
methodMap.Add(method, new MethodDefinitionEntry(
(MethodSymbol)edit.OldSymbol,
edit.PreserveLocalVariables,
edit.SyntaxMap));
......
......@@ -12,7 +12,7 @@
using System.Linq;
using System.Threading;
namespace Microsoft.CodeAnalysis.CSharp
namespace Microsoft.CodeAnalysis.CSharp.Emit
{
internal sealed class SymbolMatcher
{
......
......@@ -5,7 +5,6 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
......
......@@ -297,6 +297,21 @@ private Location GetSmallestSourceLocationOrNull(Symbol symbol)
return result;
}
internal virtual LocalSlotManager CreateLocalSlotManager(MethodSymbol method)
{
return new FullLocalSlotManager();
}
internal virtual ImmutableArray<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey> GetPreviousAnonymousTypes()
{
return ImmutableArray<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey>.Empty;
}
internal virtual int GetNextAnonymousTypeIndex()
{
return 0;
}
internal virtual bool TryGetAnonymousTypeName(NamedTypeSymbol template, out string name, out int index)
{
Debug.Assert(Compilation == template.DeclaringCompilation);
......@@ -310,13 +325,6 @@ internal override IEnumerable<Cci.INamespaceTypeDefinition> GetAnonymousTypes()
return Compilation.AnonymousTypeManager.GetAllCreatedTemplates();
}
internal override IReadOnlyDictionary<CodeAnalysis.Emit.AnonymousTypeKey, CodeAnalysis.Emit.AnonymousTypeValue> GetAnonymousTypeMap()
{
// Should only be called when emitting delta PE.
// See PEDeltaAssemblyBuilder implementation.
throw ExceptionUtilities.Unreachable;
}
/// <summary>
/// True if this module is an ENC update.
/// </summary>
......
......@@ -275,17 +275,12 @@ private AnonymousTypeTemplateSymbol CreatePlaceholderTemplate(Microsoft.CodeAnal
/// </summary>
public void AssignTemplatesNamesAndCompile(MethodBodyCompiler compiler, PEModuleBuilder moduleBeingBuilt, DiagnosticBag diagnostics)
{
var previousGeneration = moduleBeingBuilt.PreviousGeneration;
if (previousGeneration != null)
// Ensure all previous anonymous type templates are included so the
// types are available for subsequent edit and continue generations.
foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes())
{
// Ensure all previous anonymous type templates are included so the
// types are available for subsequent edit and continue generations.
foreach (var key in previousGeneration.AnonymousTypeMap.Keys)
{
var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, f => f);
this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key));
}
var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, f => f);
this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key));
}
// Get all anonymous types owned by this manager
......@@ -334,7 +329,7 @@ public void AssignTemplatesNamesAndCompile(MethodBodyCompiler compiler, PEModule
moduleId = string.Empty;
}
int nextIndex = (previousGeneration == null) ? 0 : previousGeneration.GetNextAnonymousTypeIndex();
int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex();
foreach (var template in builder)
{
string name;
......
......@@ -7,6 +7,7 @@
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
......
......@@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
......
......@@ -53,7 +53,6 @@
<Compile Include="CodeGen\CompilationTestData.cs" />
<Compile Include="CodeGen\DebugDocumentProvider.cs" />
<Compile Include="CodeGen\EmitState.cs" />
<Compile Include="CodeGen\EncLocalSlotManager.cs" />
<Compile Include="CodeGen\ExternNamespace.cs" />
<Compile Include="CodeGen\FullLocalSlotManager.cs" />
<Compile Include="CodeGen\ILBuilder.cs" />
......@@ -186,9 +185,14 @@
<Compile Include="Emit\AnonymousTypeKey.cs" />
<Compile Include="Emit\AnonymousTypeValue.cs" />
<Compile Include="Emit\Context.cs" />
<Compile Include="Emit\DefinitionMap.cs" />
<Compile Include="Emit\EmitBaseline.cs" />
<Compile Include="Emit\EncLocalInfo.cs" />
<Compile Include="Emit\EditAndContinue\DefinitionMap.cs" />
<Compile Include="Emit\EditAndContinue\DeltaPeWriter.cs" />
<Compile Include="Emit\EditAndContinue\EmitBaseline.cs" />
<Compile Include="Emit\EditAndContinue\EmitDifferenceResult.cs" />
<Compile Include="Emit\EditAndContinue\EncLocalInfo.cs" />
<Compile Include="Emit\EditAndContinue\EncLocalSlotManager.cs" />
<Compile Include="Emit\EditAndContinue\IPEDeltaAssemblyBuilder.cs" />
<Compile Include="Emit\EditAndContinue\SymbolChanges.cs" />
<Compile Include="Emit\ErrorType.cs" />
<Compile Include="Emit\ModulePropertiesForSerialization.cs" />
<Compile Include="Emit\NoPia\CommonEmbeddedEvent.cs" />
......@@ -203,7 +207,6 @@
<Compile Include="Emit\NoPia\VtblGap.cs" />
<Compile Include="Emit\PEModuleBuilder.cs" />
<Compile Include="Emit\SemanticEdit.cs" />
<Compile Include="Emit\SymbolChanges.cs" />
<Compile Include="EnumConstantHelper.cs" />
<Compile Include="Instrumentation\FunctionId.cs" />
<Compile Include="Instrumentation\Logger.cs" />
......@@ -349,7 +352,6 @@
<Compile Include="PEWriter\Constants.cs" />
<Compile Include="PEWriter\Core.cs" />
<Compile Include="PEWriter\DebugSourceDocument.cs" />
<Compile Include="PEWriter\DeltaPeWriter.cs" />
<Compile Include="PEWriter\DirectoryEntry.cs" />
<Compile Include="PEWriter\ExceptionHandlerRegion.cs" />
<Compile Include="PEWriter\Expressions.cs" />
......
......@@ -1186,7 +1186,7 @@ protected bool ShouldBeSigned
internal abstract bool IsDelaySign { get; }
internal abstract StrongNameKeys StrongNameKeys { get; }
internal abstract FunctionId EmitFunctionId { get; }
internal abstract EmitResult MakeEmitResult(bool success, ImmutableArray<Diagnostic> diagnostics, Microsoft.CodeAnalysis.Emit.EmitBaseline baseline = null);
internal abstract EmitResult MakeEmitResult(bool success, ImmutableArray<Diagnostic> diagnostics);
internal abstract CommonPEModuleBuilder CreateModuleBuilder(
string outputName,
......@@ -1196,8 +1196,6 @@ protected bool ShouldBeSigned
CancellationToken cancellationToken,
CompilationTestData testData,
DiagnosticBag diagnostics,
Microsoft.CodeAnalysis.Emit.EmitBaseline previousGeneration,
IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits,
ref bool hasDeclarationErrors);
internal abstract bool Compile(
......@@ -1236,8 +1234,6 @@ protected bool ShouldBeSigned
cancellationToken,
testData,
diagnostics,
previousGeneration: null,
edits: null,
hasDeclarationErrors: ref hasDeclarationErrors);
if (moduleBeingBuilt == null)
......@@ -1264,16 +1260,6 @@ protected bool ShouldBeSigned
return moduleBeingBuilt;
}
/// <summary>
/// Return a version of the baseline with all definitions mapped to this compilation.
/// Definitions from the initial generation, from metadata, are not mapped since
/// the initial generation is always included as metadata. That is, the symbols from
/// types, methods, ... in the TypesAdded, MethodsAdded, ... collections are replaced
/// by the corresponding symbols from the current compilation.
/// </summary>
internal abstract Microsoft.CodeAnalysis.Emit.EmitBaseline MapToCompilation(
CommonPEModuleBuilder moduleBeingBuilt);
/// <summary>
/// Emit the IL for the compiled source code into the specified stream.
/// </summary>
......@@ -1408,7 +1394,7 @@ protected bool ShouldBeSigned
/// of the current compilation is returned as an EmitBaseline for use in a
/// subsequent Edit and Continue.
/// </summary>
public EmitResult EmitDifference(
public EmitDifferenceResult EmitDifference(
Microsoft.CodeAnalysis.Emit.EmitBaseline baseline,
IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits,
Stream metadataStream,
......@@ -1448,7 +1434,7 @@ protected bool ShouldBeSigned
return this.EmitDifference(baseline, edits, metadataStream, ilStream, pdbStream, updatedMethodTokens, null, cancellationToken);
}
internal EmitResult EmitDifference(
internal abstract EmitDifferenceResult EmitDifference(
Microsoft.CodeAnalysis.Emit.EmitBaseline baseline,
IEnumerable<Microsoft.CodeAnalysis.Emit.SemanticEdit> edits,
Stream metadataStream,
......@@ -1456,89 +1442,7 @@ protected bool ShouldBeSigned
Stream pdbStream,
ICollection<uint> updatedMethodTokens,
CompilationTestData testData,
CancellationToken cancellationToken)
{
Guid mvid;
try
{
mvid = baseline.OriginalMetadata.GetModuleVersionId();
}
catch (BadImageFormatException)
{
// TODO (tomat): report diagnostic
// return MakeEmitResult(success: false, diagnostics: ... , generation: writer.ToGeneration());
throw;
}
// TODO:
var pdbName = PathUtilities.ChangeExtension(this.SourceModule.Name, "pdb");
using (var pdbWriter = new Cci.PdbWriter(pdbName, new ComStreamWrapper(pdbStream)))
{
var diagnostics = DiagnosticBag.GetInstance();
// TODO: reuse code in SerializeToPeStream to report pdb diagnostics, etc.
bool hasDeclarationErrors = false;
CommonPEModuleBuilder moduleBeingBuilt = this.CreateModuleBuilder(
outputName: null,
moduleVersionId: mvid,
manifestResources: null,
assemblySymbolMapper: null,
cancellationToken: cancellationToken,
testData: testData,
diagnostics: diagnostics,
previousGeneration: baseline,
edits: edits,
hasDeclarationErrors: ref hasDeclarationErrors);
if (moduleBeingBuilt != null)
{
var definitionMap = moduleBeingBuilt.PreviousDefinitions;
var changes = moduleBeingBuilt.Changes;
if (this.Compile(
moduleBeingBuilt,
outputName: null,
manifestResources: null,
win32Resources: null,
xmlDocStream: null,
cancellationToken: cancellationToken,
metadataOnly: false,
generateDebugInfo: true,
diagnostics: diagnostics,
filter: changes.HasChanged,
hasDeclarationErrors: hasDeclarationErrors))
{
var context = new Microsoft.CodeAnalysis.Emit.Context((Cci.IModule)moduleBeingBuilt, null, diagnostics);
// Map the definitions from the previous compilation to the current compilation.
// This must be done after compiling above since synthesized definitions
// (generated when compiling method bodies) may be required.
baseline = this.MapToCompilation(moduleBeingBuilt);
var encId = Guid.NewGuid();
var writer = new Cci.DeltaPeWriter(
context,
this.MessageProvider,
pdbWriter,
baseline,
encId,
definitionMap,
changes,
cancellationToken);
writer.WriteMetadataAndIL(metadataStream, ilStream);
writer.GetMethodTokens(updatedMethodTokens);
return MakeEmitResult(
success: true,
diagnostics: diagnostics.ToReadOnlyAndFree(),
baseline: writer.GetDelta(baseline, this, encId));
}
}
return MakeEmitResult(success: false, diagnostics: diagnostics.ToReadOnlyAndFree());
}
}
CancellationToken cancellationToken);
/// <summary>
/// This overload is only intended to be directly called by tests that want to pass <paramref name="testData"/>.
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Emit;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.Emit
......@@ -14,7 +13,6 @@ public class EmitResult
{
private readonly bool success;
private readonly ImmutableArray<Diagnostic> diagnostics;
private readonly EmitBaseline baseline;
/// <summary>
/// True if the compilation successfully produced an executable.
......@@ -35,21 +33,10 @@ public ImmutableArray<Diagnostic> Diagnostics
get { return this.diagnostics; }
}
/// <summary>
/// A representation of the compilation that can be used as a baseline
/// for emitting differences later in edit and continue. Only generated
/// when emitting differences from the previous generation.
/// </summary>
public EmitBaseline Baseline
{
get { return this.baseline; }
}
internal EmitResult(bool success, ImmutableArray<Diagnostic> diagnostics, EmitBaseline generation)
internal EmitResult(bool success, ImmutableArray<Diagnostic> diagnostics)
{
this.success = success;
this.diagnostics = diagnostics;
this.baseline = generation;
}
protected virtual string GetDebuggerDisplay()
......
......@@ -8,14 +8,14 @@
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Threading;
using Microsoft.Cci;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
namespace Microsoft.Cci
namespace Microsoft.CodeAnalysis.Emit
{
internal class DeltaPeWriter : PeWriter
internal sealed class DeltaPeWriter : PeWriter
{
private readonly EmitBaseline previousGeneration;
private readonly Guid encId;
......@@ -162,7 +162,7 @@ private ImmutableArray<int> GetDeltaTableSizes()
userStringStreamLengthAdded: (int)this.userStringWriter.BaseStream.Length + this.previousGeneration.UserStringStreamLengthAdded,
// Guid stream is always aligned (the size if a multiple of 16 = sizeof(Guid))
guidStreamLengthAdded: (int)this.guidWriter.BaseStream.Length + this.previousGeneration.GuidStreamLengthAdded,
anonymousTypeMap: moduleBuilder.GetAnonymousTypeMap(),
anonymousTypeMap: ((IPEDeltaAssemblyBuilder)moduleBuilder).GetAnonymousTypeMap(),
localsForMethodsAddedOrChanged: AddRange(locals, this.previousGeneration.LocalsForMethodsAddedOrChanged, replace: true),
localNames: baseline.LocalNames);
}
......@@ -418,7 +418,7 @@ protected override IEnumerable<INamespaceTypeDefinition> GetTopLevelTypes(IModul
protected override void CreateIndicesForModule()
{
base.CreateIndicesForModule();
var module = (CommonPEModuleBuilder)this.module;
var module = (IPEDeltaAssemblyBuilder)this.module;
module.OnCreatedIndices(this.Context.Diagnostics);
}
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Emit
{
public sealed class EmitDifferenceResult : EmitResult
{
private readonly EmitBaseline baseline;
internal EmitDifferenceResult(bool success, ImmutableArray<Diagnostic> diagnostics, EmitBaseline baseline) :
base(success, diagnostics)
{
this.baseline = baseline;
}
public EmitBaseline Baseline
{
get { return this.baseline; }
}
}
}
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.CodeGen;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CodeGen
namespace Microsoft.CodeAnalysis.Emit
{
internal delegate int GetPreviousLocalSlot(object identity, Microsoft.Cci.ITypeReference type, LocalSlotConstraints constraints);
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis.Emit
{
interface IPEDeltaAssemblyBuilder
{
void OnCreatedIndices(DiagnosticBag diagnostics);
IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMap();
}
}
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CodeGen;
using Roslyn.Utilities;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Security;
namespace Microsoft.CodeAnalysis
{
......@@ -18,13 +16,8 @@ internal abstract class CommonPEModuleBuilder
internal abstract Cci.IAssemblyReference Translate(IAssemblySymbol symbol, DiagnosticBag diagnostics);
internal abstract Cci.ITypeReference Translate(ITypeSymbol symbol, SyntaxNode syntaxOpt, DiagnosticBag diagnostics);
internal abstract Cci.IMethodReference EntryPoint { get; }
internal virtual Microsoft.CodeAnalysis.Emit.EmitBaseline PreviousGeneration { get { return null; } }
internal virtual Microsoft.CodeAnalysis.Emit.DefinitionMap PreviousDefinitions { get { return null; } }
internal virtual Microsoft.CodeAnalysis.Emit.SymbolChanges Changes { get { return null; } }
internal abstract bool SupportsPrivateImplClass { get; }
internal virtual void OnCreatedIndices(DiagnosticBag diagnostics) { }
internal abstract IEnumerable<Cci.INamespaceTypeDefinition> GetAnonymousTypes();
internal abstract IReadOnlyDictionary<Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue> GetAnonymousTypeMap();
internal abstract Compilation CommonCompilation { get; }
}
......
......@@ -344,11 +344,9 @@
<Compile Include="Compilation\SemanticModel.vb" />
<Compile Include="Compilation\SpeculativeSyntaxTreeSemanticModel.vb" />
<Compile Include="Compilation\SymbolInfo.vb" />
<Compile Include="Compilation\SymbolMatcher.vb" />
<Compile Include="Compilation\SyntaxTreeSemanticModel.vb" />
<Compile Include="Compilation\TypeCompilationState.vb" />
<Compile Include="Compilation\TypeInfo.vb" />
<Compile Include="Compilation\VisualBasicCompilation.DefinitionMap.vb" />
<Compile Include="Compilation\VisualBasicCompilation.MethodCompiler.vb" />
<Compile Include="Compilation\VisualBasicCompilation.SynthesizedMetadataCompiler.vb" />
<Compile Include="Compilation\VisualBasicCompilation.vb" />
......@@ -375,6 +373,10 @@
<Compile Include="Emit\AssemblyReference.vb" />
<Compile Include="Emit\AttributeDataAdapter.vb" />
<Compile Include="Emit\CustomModifierAdapter.vb" />
<Compile Include="Emit\EditAndContinue\DefinitionMap.vb" />
<Compile Include="Emit\EditAndContinue\EmitHelpers.vb" />
<Compile Include="Emit\EditAndContinue\PEDeltaAssemblyBuilder.vb" />
<Compile Include="Emit\EditAndContinue\SymbolMatcher.vb" />
<Compile Include="Emit\EventSymbolAdapter.vb" />
<Compile Include="Emit\FieldSymbolAdapter.vb" />
<Compile Include="Emit\GenericMethodInstanceReference.vb" />
......@@ -398,7 +400,6 @@
<Compile Include="Emit\ParameterSymbolAdapter.vb" />
<Compile Include="Emit\ParameterTypeInformation.vb" />
<Compile Include="Emit\PEAssemblyBuilder.vb" />
<Compile Include="Emit\PEDeltaAssemblyBuilder.vb" />
<Compile Include="Emit\PEModuleBuilder.vb" />
<Compile Include="Emit\PENetModuleBuilder.vb" />
<Compile Include="Emit\PropertySymbolAdapter.vb" />
......
......@@ -1204,21 +1204,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
diagsForThisMethod As DiagnosticBag,
namespaceScopes As ImmutableArray(Of NamespaceScope)) As MethodBody
Dim previousGeneration = [module].PreviousGeneration
Dim localSlotManager As LocalSlotManager
If previousGeneration Is Nothing Then
localSlotManager = New FullLocalSlotManager()
Else
Dim previousDefinitions = [module].PreviousDefinitions
Dim previousLocals As ImmutableArray(Of EncLocalInfo) = Nothing
Dim getPreviousLocalSlot As GetPreviousLocalSlot = Nothing
If Not previousDefinitions.TryGetPreviousLocals(previousGeneration, method, previousLocals, getPreviousLocalSlot) Then
previousLocals = ImmutableArray(Of EncLocalInfo).Empty
End If
Debug.Assert(getPreviousLocalSlot IsNot Nothing)
localSlotManager = New EncLocalSlotManager(previousLocals, getPreviousLocalSlot)
End If
Dim localSlotManager = [module].CreateLocalSlotManager(method)
Dim builder As ILBuilder = New ILBuilder([module], localSlotManager, optimize)
Dim emitSequencePoints = Not namespaceScopes.IsDefault
......
......@@ -2044,8 +2044,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Friend Overrides Function MakeEmitResult(success As Boolean, diagnostics As ImmutableArray(Of Diagnostic), Optional baseline As Microsoft.CodeAnalysis.Emit.EmitBaseline = Nothing) As EmitResult
Return New EmitResult(success, diagnostics, baseline)
Friend Overrides Function MakeEmitResult(success As Boolean, diagnostics As ImmutableArray(Of Diagnostic)) As EmitResult
Return New EmitResult(success, diagnostics)
End Function
''' <summary>
......@@ -2185,8 +2185,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
cancellationToken As CancellationToken,
testData As CompilationTestData,
diagnosticBag As DiagnosticBag,
previousGeneration As Microsoft.CodeAnalysis.Emit.EmitBaseline,
edits As IEnumerable(Of Microsoft.CodeAnalysis.Emit.SemanticEdit),
ByRef hasDeclarationErrors As Boolean) As CommonPEModuleBuilder
Debug.Assert(diagnosticBag.IsEmptyWithoutResolution) ' True, but not required.
......@@ -2207,8 +2205,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
' Get the runtime metadata version from the cor library. If this fails we have no reasonable value to give.
Dim corLibrary = TryCast(Assembly.CorLibrary, Symbols.Metadata.PE.PEAssemblySymbol)
Dim runtimeMetadataVersion As String = If(corLibrary Is Nothing, String.Empty, corLibrary.Assembly.ManifestModule.MetadataVersion)
Dim runtimeMetadataVersion = GetRuntimeMetadataVersion()
Dim moduleSerializationProperties = ConstructModuleSerializationProperties(runtimeMetadataVersion, moduleVersionId)
If manifestResources Is Nothing Then
......@@ -2218,7 +2215,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' if there is no stream to write to, then there is no need for a module
Dim moduleBeingBuilt As PEModuleBuilder
If Options.OutputKind.IsNetModule() Then
Debug.Assert(previousGeneration Is Nothing)
moduleBeingBuilt = New PENetModuleBuilder(
DirectCast(Me.SourceModule, SourceModuleSymbol),
outputName,
......@@ -2226,25 +2222,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
manifestResources)
Else
Dim kind = If(Options.OutputKind.IsValid(), Options.OutputKind, OutputKind.DynamicallyLinkedLibrary)
If previousGeneration Is Nothing Then
moduleBeingBuilt = New PEAssemblyBuilder(
moduleBeingBuilt = New PEAssemblyBuilder(
SourceAssembly,
outputName,
kind,
moduleSerializationProperties,
manifestResources,
assemblySymbolMapper)
Else
moduleBeingBuilt = New PEDeltaAssemblyBuilder(
SourceAssembly,
outputName,
kind,
moduleSerializationProperties,
manifestResources,
assemblySymbolMapper,
previousGeneration,
edits)
End If
End If
If testData IsNot Nothing Then
......@@ -2360,90 +2344,31 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Next
End Function
Friend Overrides Function MapToCompilation(
moduleBeingBuilt As CommonPEModuleBuilder) As EmitBaseline
Dim previousGeneration = moduleBeingBuilt.PreviousGeneration
Debug.Assert(previousGeneration.Compilation IsNot Me)
If previousGeneration.Ordinal = 0 Then
' Initial generation, nothing to map. (Since the initial generation
' Is always loaded from metadata in the context of the current
' compilation, there's no separate mapping step.)
Return previousGeneration
End If
Dim map = New SymbolMatcher(
moduleBeingBuilt.GetAnonymousTypeMap(),
(DirectCast(previousGeneration.Compilation, VisualBasicCompilation)).SourceAssembly,
New Microsoft.CodeAnalysis.Emit.Context(DirectCast(previousGeneration.PEModuleBuilder, PEModuleBuilder), Nothing, New DiagnosticBag()),
Me.SourceAssembly,
New Microsoft.CodeAnalysis.Emit.Context(DirectCast(moduleBeingBuilt, Cci.IModule), Nothing, New DiagnosticBag()))
' Map all definitions to this compilation.
Dim typesAdded = MapDefinitions(map, previousGeneration.TypesAdded)
Dim eventsAdded = MapDefinitions(map, previousGeneration.EventsAdded)
Dim fieldsAdded = MapDefinitions(map, previousGeneration.FieldsAdded)
Dim methodsAdded = MapDefinitions(map, previousGeneration.MethodsAdded)
Dim propertiesAdded = MapDefinitions(map, previousGeneration.PropertiesAdded)
' Map anonymous types to this compilation.
Dim anonymousTypeMap As New Dictionary(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue)
For Each pair In previousGeneration.AnonymousTypeMap
Dim key = pair.Key
Dim value = pair.Value
Dim type = DirectCast(map.MapDefinition(value.Type), Cci.ITypeDefinition)
Debug.Assert(type IsNot Nothing)
anonymousTypeMap.Add(key, New Microsoft.CodeAnalysis.Emit.AnonymousTypeValue(value.Name, value.UniqueIndex, type))
Next
' Map locals (specifically, local types) to this compilation.
Dim locals As New Dictionary(Of UInt32, ImmutableArray(Of Microsoft.CodeAnalysis.Emit.EncLocalInfo))
For Each pair In previousGeneration.LocalsForMethodsAddedOrChanged
locals.Add(pair.Key, pair.Value.SelectAsArray(Function(l, m) MapLocalInfo(m, l), map))
Next
Friend Overrides Function EmitDifference(
baseline As EmitBaseline,
edits As IEnumerable(Of SemanticEdit),
metadataStream As Stream,
ilStream As Stream,
pdbStream As Stream,
updatedMethodTokens As ICollection(Of UInteger),
testData As CompilationTestData,
cancellationToken As CancellationToken) As EmitDifferenceResult
Return previousGeneration.With(
Return EmitHelpers.EmitDifference(
Me,
moduleBeingBuilt,
previousGeneration.Ordinal,
previousGeneration.EncId,
typesAdded,
eventsAdded,
fieldsAdded,
methodsAdded,
propertiesAdded,
previousGeneration.EventMapAdded,
previousGeneration.PropertyMapAdded,
previousGeneration.TableEntriesAdded,
blobStreamLengthAdded:=previousGeneration.BlobStreamLengthAdded,
stringStreamLengthAdded:=previousGeneration.StringStreamLengthAdded,
userStringStreamLengthAdded:=previousGeneration.UserStringStreamLengthAdded,
guidStreamLengthAdded:=previousGeneration.GuidStreamLengthAdded,
anonymousTypeMap:=anonymousTypeMap,
localsForMethodsAddedOrChanged:=locals,
localNames:=previousGeneration.LocalNames)
End Function
Private Shared Function MapDefinitions(Of K As Cci.IDefinition, V)(map As SymbolMatcher, items As IReadOnlyDictionary(Of K, V)) As IReadOnlyDictionary(Of K, V)
Dim result As New Dictionary(Of K, V)
For Each pair In items
Dim key = DirectCast(map.MapDefinition(pair.Key), K)
' Result may be null if the definition was deleted, or if the definition
' was synthesized (e.g.: an iterator type) and the method that generated
' the synthesized definition was unchanged and not recompiled.
If key IsNot Nothing Then
result.Add(key, pair.Value)
End If
Next
Return result
baseline,
edits,
metadataStream,
ilStream,
pdbStream,
updatedMethodTokens,
testData,
cancellationToken)
End Function
Private Shared Function MapLocalInfo(map As SymbolMatcher, localInfo As Microsoft.CodeAnalysis.Emit.EncLocalInfo) As Microsoft.CodeAnalysis.Emit.EncLocalInfo
Debug.Assert(Not localInfo.IsDefault)
Dim type = map.MapReference(localInfo.Type)
Debug.Assert(type IsNot Nothing)
Return New Microsoft.CodeAnalysis.Emit.EncLocalInfo(localInfo.Offset, type, localInfo.Constraints, localInfo.TempKind)
Friend Function GetRuntimeMetadataVersion() As String
Dim corLibrary = TryCast(Assembly.CorLibrary, Symbols.Metadata.PE.PEAssemblySymbol)
Return If(corLibrary Is Nothing, String.Empty, corLibrary.Assembly.ManifestModule.MetadataVersion)
End Function
Private Shared Sub AddDebugSourceDocumentsForChecksumDirectives(
......
' Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports System.IO
Imports System.Threading
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.Emit
Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Module EmitHelpers
Friend Function EmitDifference(
compilation As VisualBasicCompilation,
baseline As EmitBaseline,
edits As IEnumerable(Of SemanticEdit),
metadataStream As Stream,
ilStream As Stream,
pdbStream As Stream,
updatedMethodTokens As ICollection(Of UInteger),
testData As CompilationTestData,
cancellationToken As CancellationToken) As EmitDifferenceResult
Dim moduleVersionId As Guid
Try
moduleVersionId = baseline.OriginalMetadata.GetModuleVersionId()
Catch ex As BadImageFormatException
' Return MakeEmitResult(success:=False, diagnostics:= ..., baseline:=Nothing)
Throw
End Try
Dim pdbName = PathUtilities.ChangeExtension(compilation.SourceModule.Name, "pdb")
Using pdbWriter = New Cci.PdbWriter(pdbName, New ComStreamWrapper(pdbStream))
Dim diagnostics = DiagnosticBag.GetInstance()
Dim runtimeMDVersion = compilation.GetRuntimeMetadataVersion()
Dim serializationProperties = compilation.ConstructModuleSerializationProperties(runtimeMDVersion, moduleVersionId)
Dim manifestResources = SpecializedCollections.EmptyEnumerable(Of ResourceDescription)()
Dim moduleBeingBuilt = New PEDeltaAssemblyBuilder(
compilation.SourceAssembly,
outputName:=Nothing,
outputKind:=compilation.Options.OutputKind,
serializationProperties:=serializationProperties,
manifestResources:=manifestResources,
assemblySymbolMapper:=Nothing,
previousGeneration:=baseline,
edits:=edits)
If testData IsNot Nothing Then
moduleBeingBuilt.SetMethodTestData(testData.Methods)
testData.Module = moduleBeingBuilt
End If
baseline = moduleBeingBuilt.PreviousGeneration
Dim definitionMap = moduleBeingBuilt.PreviousDefinitions
Dim changes = moduleBeingBuilt.Changes
If compilation.Compile(
moduleBeingBuilt,
outputName:=Nothing,
manifestResources:=manifestResources,
win32Resources:=Nothing,
xmlDocStream:=Nothing,
cancellationToken:=cancellationToken,
metadataOnly:=False,
generateDebugInfo:=True,
diagnosticBag:=diagnostics,
filter:=AddressOf changes.HasChanged,
hasDeclarationErrors:=False) Then
Dim context = New Context(DirectCast(moduleBeingBuilt, Cci.IModule), Nothing, diagnostics)
' Map the definitions from the previous compilation to the current compilation.
' This must be done after compiling above since synthesized definitions
' (generated when compiling method bodies) may be required.
baseline = MapToCompilation(compilation, moduleBeingBuilt)
Dim encId = Guid.NewGuid()
Dim writer = New DeltaPeWriter(
context,
compilation.MessageProvider,
pdbWriter,
baseline,
encId,
definitionMap,
changes,
cancellationToken)
writer.WriteMetadataAndIL(metadataStream, ilStream)
writer.GetMethodTokens(updatedMethodTokens)
Return New EmitDifferenceResult(
success:=True,
diagnostics:=diagnostics.ToReadOnlyAndFree(),
baseline:=writer.GetDelta(baseline, compilation, encId))
End If
Return New EmitDifferenceResult(success:=False, diagnostics:=diagnostics.ToReadOnlyAndFree(), baseline:=Nothing)
End Using
End Function
Friend Function MapToCompilation(
compilation As VisualBasicCompilation,
moduleBeingBuilt As PEDeltaAssemblyBuilder) As EmitBaseline
Dim previousGeneration = moduleBeingBuilt.PreviousGeneration
Debug.Assert(previousGeneration.Compilation IsNot compilation)
If previousGeneration.Ordinal = 0 Then
' Initial generation, nothing to map. (Since the initial generation
' is always loaded from metadata in the context of the current
' compilation, there's no separate mapping step.)
Return previousGeneration
End If
Dim map = New SymbolMatcher(
moduleBeingBuilt.GetAnonymousTypeMap(),
(DirectCast(previousGeneration.Compilation, VisualBasicCompilation)).SourceAssembly,
New Context(DirectCast(previousGeneration.PEModuleBuilder, PEModuleBuilder), Nothing, New DiagnosticBag()),
compilation.SourceAssembly,
New Context(DirectCast(moduleBeingBuilt, Cci.IModule), Nothing, New DiagnosticBag()))
' Map all definitions to this compilation.
Dim typesAdded = MapDefinitions(map, previousGeneration.TypesAdded)
Dim eventsAdded = MapDefinitions(map, previousGeneration.EventsAdded)
Dim fieldsAdded = MapDefinitions(map, previousGeneration.FieldsAdded)
Dim methodsAdded = MapDefinitions(map, previousGeneration.MethodsAdded)
Dim propertiesAdded = MapDefinitions(map, previousGeneration.PropertiesAdded)
' Map anonymous types to this compilation.
Dim anonymousTypeMap As New Dictionary(Of AnonymousTypeKey, AnonymousTypeValue)
For Each pair In previousGeneration.AnonymousTypeMap
Dim key = pair.Key
Dim value = pair.Value
Dim type = DirectCast(map.MapDefinition(value.Type), Cci.ITypeDefinition)
Debug.Assert(type IsNot Nothing)
anonymousTypeMap.Add(key, New AnonymousTypeValue(value.Name, value.UniqueIndex, type))
Next
' Map locals (specifically, local types) to this compilation.
Dim locals As New Dictionary(Of UInt32, ImmutableArray(Of EncLocalInfo))
For Each pair In previousGeneration.LocalsForMethodsAddedOrChanged
locals.Add(pair.Key, pair.Value.SelectAsArray(Function(l, m) MapLocalInfo(m, l), map))
Next
Return previousGeneration.With(
compilation,
moduleBeingBuilt,
previousGeneration.Ordinal,
previousGeneration.EncId,
typesAdded,
eventsAdded,
fieldsAdded,
methodsAdded,
propertiesAdded,
previousGeneration.EventMapAdded,
previousGeneration.PropertyMapAdded,
previousGeneration.TableEntriesAdded,
blobStreamLengthAdded:=previousGeneration.BlobStreamLengthAdded,
stringStreamLengthAdded:=previousGeneration.StringStreamLengthAdded,
userStringStreamLengthAdded:=previousGeneration.UserStringStreamLengthAdded,
guidStreamLengthAdded:=previousGeneration.GuidStreamLengthAdded,
anonymousTypeMap:=anonymousTypeMap,
localsForMethodsAddedOrChanged:=locals,
localNames:=previousGeneration.LocalNames)
End Function
Private Function MapDefinitions(Of K As Cci.IDefinition, V)(
map As SymbolMatcher,
items As IReadOnlyDictionary(Of K, V)) As IReadOnlyDictionary(Of K, V)
Dim result As New Dictionary(Of K, V)
For Each pair In items
Dim key = DirectCast(map.MapDefinition(pair.Key), K)
' Result may be null if the definition was deleted, or if the definition
' was synthesized (e.g.: an iterator type) and the method that generated
' the synthesized definition was unchanged and not recompiled.
If key IsNot Nothing Then
result.Add(key, pair.Value)
End If
Next
Return result
End Function
Private Function MapLocalInfo(
map As SymbolMatcher,
localInfo As EncLocalInfo) As EncLocalInfo
Debug.Assert(Not localInfo.IsDefault)
Dim type = map.MapReference(localInfo.Type)
Debug.Assert(type IsNot Nothing)
Return New EncLocalInfo(localInfo.Offset, type, localInfo.Constraints, localInfo.TempKind)
End Function
End Module
End Namespace
\ No newline at end of file
......@@ -3,16 +3,20 @@
Imports System.Collections.Immutable
Imports System.Reflection.Metadata
Imports System.Runtime.InteropServices
Imports Microsoft.Cci
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.Emit
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Friend NotInheritable Class PEDeltaAssemblyBuilder
Inherits PEAssemblyBuilderBase
Implements IPEDeltaAssemblyBuilder
Private ReadOnly m_PreviousGeneration As Microsoft.CodeAnalysis.Emit.EmitBaseline
Private ReadOnly m_PreviousDefinitions As VisualBasicCompilation.DefinitionMap
Private ReadOnly m_Changes As Microsoft.CodeAnalysis.Emit.SymbolChanges
Private ReadOnly m_PreviousGeneration As EmitBaseline
Private ReadOnly m_PreviousDefinitions As DefinitionMap
Private ReadOnly m_Changes As SymbolChanges
Public Sub New(sourceAssembly As SourceAssemblySymbol,
outputName As String,
......@@ -20,12 +24,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
serializationProperties As ModulePropertiesForSerialization,
manifestResources As IEnumerable(Of ResourceDescription),
assemblySymbolMapper As Func(Of AssemblySymbol, AssemblyIdentity),
previousGeneration As Microsoft.CodeAnalysis.Emit.EmitBaseline,
edits As IEnumerable(Of Microsoft.CodeAnalysis.Emit.SemanticEdit))
previousGeneration As EmitBaseline,
edits As IEnumerable(Of SemanticEdit))
MyBase.New(sourceAssembly, outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper)
Dim context = New Microsoft.CodeAnalysis.Emit.Context(Me, Nothing, New DiagnosticBag())
Dim context = New Context(Me, Nothing, New DiagnosticBag())
Dim [module] = previousGeneration.OriginalMetadata
Dim compilation = sourceAssembly.DeclaringCompilation
Dim metadataAssembly = compilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create([module]), MetadataImportOptions.All)
......@@ -38,19 +42,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Dim matchToPrevious As SymbolMatcher = Nothing
If previousGeneration.Ordinal > 0 Then
Dim previousAssembly = DirectCast(previousGeneration.Compilation, VisualBasicCompilation).SourceAssembly
Dim previousContext = New Microsoft.CodeAnalysis.Emit.Context(DirectCast(previousGeneration.PEModuleBuilder, PEModuleBuilder), Nothing, New DiagnosticBag())
Dim previousContext = New Context(DirectCast(previousGeneration.PEModuleBuilder, PEModuleBuilder), Nothing, New DiagnosticBag())
matchToPrevious = New SymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, previousAssembly, previousContext)
End If
Me.m_PreviousDefinitions = New VisualBasicCompilation.DefinitionMap(previousGeneration.OriginalMetadata.Module, metadataDecoder, matchToMetadata, matchToPrevious, GenerateMethodMap(edits))
Me.m_PreviousDefinitions = New DefinitionMap(previousGeneration.OriginalMetadata.Module, metadataDecoder, matchToMetadata, matchToPrevious, GenerateMethodMap(edits))
Me.m_PreviousGeneration = previousGeneration
Me.m_Changes = New Microsoft.CodeAnalysis.Emit.SymbolChanges(m_PreviousDefinitions, edits)
Me.m_Changes = New SymbolChanges(m_PreviousDefinitions, edits)
End Sub
Private Overloads Shared Function GetAnonymousTypeMap(
reader As MetadataReader,
metadataDecoder As Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE.MetadataDecoder) As IReadOnlyDictionary(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue)
Dim result = New Dictionary(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue)
metadataDecoder As Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE.MetadataDecoder) As IReadOnlyDictionary(Of AnonymousTypeKey, AnonymousTypeValue)
Dim result = New Dictionary(Of AnonymousTypeKey, AnonymousTypeValue)
For Each handle In reader.TypeDefinitions
Dim def = reader.GetTypeDefinition(handle)
If Not def.Namespace.IsNil Then
......@@ -65,13 +69,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Dim index As Integer = 0
If GeneratedNames.TryParseAnonymousTypeTemplateName(GeneratedNames.AnonymousTypeTemplateNamePrefix, name, index) Then
Dim type = DirectCast(metadataDecoder.GetTypeOfToken(handle), NamedTypeSymbol)
Dim key = New Microsoft.CodeAnalysis.Emit.AnonymousTypeKey(GetAnonymousTypeKeyFields(type))
Dim value = New Microsoft.CodeAnalysis.Emit.AnonymousTypeValue(name, index, type)
Dim key = New AnonymousTypeKey(GetAnonymousTypeKeyFields(type))
Dim value = New AnonymousTypeValue(name, index, type)
result.Add(key, value)
ElseIf GeneratedNames.TryParseAnonymousTypeTemplateName(GeneratedNames.AnonymousDelegateTemplateNamePrefix, name, index) Then
Dim type = DirectCast(metadataDecoder.GetTypeOfToken(handle), NamedTypeSymbol)
Dim key = GetAnonymousDelegateKey(type)
Dim value = New Microsoft.CodeAnalysis.Emit.AnonymousTypeValue(name, index, type)
Dim value = New AnonymousTypeValue(name, index, type)
result.Add(key, value)
End If
Next
......@@ -108,7 +112,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Return ImmutableArray.Create(propertyNames)
End Function
Private Shared Function GetAnonymousDelegateKey(type As NamedTypeSymbol) As Microsoft.CodeAnalysis.Emit.AnonymousTypeKey
Private Shared Function GetAnonymousDelegateKey(type As NamedTypeSymbol) As AnonymousTypeKey
Debug.Assert(type.BaseTypeNoUseSiteDiagnostics.SpecialType = SpecialType.System_MulticastDelegate)
' The key is the set of parameter names to the Invoke method,
......@@ -120,12 +124,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Dim parameterNames = ArrayBuilder(Of String).GetInstance()
parameterNames.AddRange(method.Parameters.SelectAsArray(Function(p) p.Name))
parameterNames.Add(AnonymousTypeDescriptor.GetReturnParameterName(Not method.IsSub))
Return New Microsoft.CodeAnalysis.Emit.AnonymousTypeKey(parameterNames.ToImmutableAndFree(), isDelegate:=True)
Return New AnonymousTypeKey(parameterNames.ToImmutableAndFree(), isDelegate:=True)
End Function
Private Shared Function EnsureInitialized(
previousGeneration As Microsoft.CodeAnalysis.Emit.EmitBaseline,
metadataDecoder As Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE.MetadataDecoder) As Microsoft.CodeAnalysis.Emit.EmitBaseline
previousGeneration As EmitBaseline,
metadataDecoder As Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE.MetadataDecoder) As EmitBaseline
If previousGeneration.AnonymousTypeMap IsNot Nothing Then
Return previousGeneration
End If
......@@ -153,13 +157,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
localNames:=previousGeneration.LocalNames)
End Function
Friend Overrides ReadOnly Property PreviousGeneration As Microsoft.CodeAnalysis.Emit.EmitBaseline
Friend ReadOnly Property PreviousGeneration As EmitBaseline
Get
Return m_PreviousGeneration
End Get
End Property
Friend Overrides ReadOnly Property PreviousDefinitions As Microsoft.CodeAnalysis.Emit.DefinitionMap
Friend ReadOnly Property PreviousDefinitions As DefinitionMap
Get
Return m_PreviousDefinitions
End Get
......@@ -173,29 +177,47 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Get
End Property
Friend Overrides Function GetAnonymousTypeMap() As IReadOnlyDictionary(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue)
Friend Overloads Function GetAnonymousTypeMap() As IReadOnlyDictionary(Of AnonymousTypeKey, AnonymousTypeValue) Implements IPEDeltaAssemblyBuilder.GetAnonymousTypeMap
Dim anonymousTypes = Compilation.AnonymousTypeManager.GetAnonymousTypeMap()
' Should contain all entries in previous generation.
Debug.Assert(m_PreviousGeneration.AnonymousTypeMap.All(Function(p) anonymousTypes.ContainsKey(p.Key)))
Return anonymousTypes
End Function
Friend Overrides Function CreateLocalSlotManager(method As MethodSymbol) As LocalSlotManager
Dim previousLocals As ImmutableArray(Of EncLocalInfo) = Nothing
Dim getPreviousLocalSlot As GetPreviousLocalSlot = Nothing
If Not m_PreviousDefinitions.TryGetPreviousLocals(m_PreviousGeneration, method, previousLocals, getPreviousLocalSlot) Then
previousLocals = ImmutableArray(Of EncLocalInfo).Empty
End If
Debug.Assert(getPreviousLocalSlot IsNot Nothing)
Return New EncLocalSlotManager(previousLocals, getPreviousLocalSlot)
End Function
Friend Overrides Function GetPreviousAnonymousTypes() As ImmutableArray(Of AnonymousTypeKey)
Return ImmutableArray.CreateRange(m_PreviousGeneration.AnonymousTypeMap.Keys)
End Function
Friend Overrides Function GetNextAnonymousTypeIndex(fromDelegates As Boolean) As Integer
Return m_PreviousGeneration.GetNextAnonymousTypeIndex(fromDelegates)
End Function
Friend Overrides Function TryGetAnonymousTypeName(template As NamedTypeSymbol, <Out()> ByRef name As String, <Out()> ByRef index As Integer) As Boolean
Debug.Assert(Compilation Is template.DeclaringCompilation)
Return m_PreviousDefinitions.TryGetAnonymousTypeName(template, name, index)
End Function
Friend Overrides ReadOnly Property Changes As Microsoft.CodeAnalysis.Emit.SymbolChanges
Friend ReadOnly Property Changes As SymbolChanges
Get
Return m_Changes
End Get
End Property
Friend Overrides Function GetTopLevelTypesCore(context As Microsoft.CodeAnalysis.Emit.Context) As IEnumerable(Of Cci.INamespaceTypeDefinition)
Friend Overrides Function GetTopLevelTypesCore(context As Context) As IEnumerable(Of Cci.INamespaceTypeDefinition)
Return m_Changes.GetTopLevelTypes(context)
End Function
Friend Overrides Sub OnCreatedIndices(diagnostics As DiagnosticBag)
Friend Sub OnCreatedIndices(diagnostics As DiagnosticBag) Implements IPEDeltaAssemblyBuilder.OnCreatedIndices
Dim embeddedTypesManager = Me.EmbeddedTypesManagerOpt
If embeddedTypesManager IsNot Nothing Then
For Each embeddedType In embeddedTypesManager.EmbeddedTypesMap.Keys
......@@ -204,13 +226,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End If
End Sub
Private Shared Function GenerateMethodMap(edits As IEnumerable(Of Microsoft.CodeAnalysis.Emit.SemanticEdit)) As IReadOnlyDictionary(Of MethodSymbol, VisualBasicCompilation.MethodDefinitionEntry)
Dim methodMap = New Dictionary(Of MethodSymbol, VisualBasicCompilation.MethodDefinitionEntry)
Private Shared Function GenerateMethodMap(edits As IEnumerable(Of SemanticEdit)) As IReadOnlyDictionary(Of MethodSymbol, MethodDefinitionEntry)
Dim methodMap = New Dictionary(Of MethodSymbol, MethodDefinitionEntry)
For Each edit In edits
If edit.Kind = CodeAnalysis.Emit.SemanticEditKind.Update Then
Dim method = TryCast(edit.NewSymbol, MethodSymbol)
If method IsNot Nothing Then
methodMap.Add(method, New VisualBasicCompilation.MethodDefinitionEntry(
methodMap.Add(method, New MethodDefinitionEntry(
DirectCast(edit.OldSymbol, MethodSymbol),
edit.PreserveLocalVariables,
edit.SyntaxMap))
......@@ -219,7 +241,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Next
Return methodMap
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -11,7 +11,7 @@ Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports System.Threading
Namespace Microsoft.CodeAnalysis.VisualBasic
Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Friend NotInheritable Class SymbolMatcher
Private Shared ReadOnly NameComparer As StringComparer = IdentifierComparison.Comparer
......
......@@ -270,6 +270,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Return result
End Function
Friend Overridable Function CreateLocalSlotManager(method As MethodSymbol) As LocalSlotManager
Return New FullLocalSlotManager()
End Function
Friend Overridable Function GetPreviousAnonymousTypes() As ImmutableArray(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey)
Return ImmutableArray(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey).Empty
End Function
Friend Overridable Function GetNextAnonymousTypeIndex(fromDelegates As Boolean) As Integer
Return 0
End Function
Friend Overridable Function TryGetAnonymousTypeName(template As NamedTypeSymbol, <Out()> ByRef name As String, <Out()> ByRef index As Integer) As Boolean
Debug.Assert(Compilation Is template.DeclaringCompilation)
name = Nothing
......@@ -281,12 +293,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Return SourceModule.ContainingSourceAssembly.DeclaringCompilation.AnonymousTypeManager.AllCreatedTemplates
End Function
Friend Overrides Function GetAnonymousTypeMap() As IReadOnlyDictionary(Of Microsoft.CodeAnalysis.Emit.AnonymousTypeKey, Microsoft.CodeAnalysis.Emit.AnonymousTypeValue)
' Should only be called when emitting delta PE.
' See PEDeltaAssemblyBuilder implementation.
Throw ExceptionUtilities.Unreachable
End Function
Friend Overrides Iterator Function GetTopLevelTypesCore(context As Microsoft.CodeAnalysis.Emit.Context) As IEnumerable(Of INamespaceTypeDefinition)
Dim embeddedSymbolManager As EmbeddedSymbolManager = SourceModule.ContainingSourceAssembly.DeclaringCompilation.EmbeddedSymbolManager
Dim stack As New Stack(Of NamespaceOrTypeSymbol)()
......
......@@ -183,19 +183,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
''' </summary>
Public Sub AssignTemplatesNamesAndCompile(compiler As VisualBasicCompilation.MethodCompiler, moduleBeingBuilt As Emit.PEModuleBuilder, diagnostics As DiagnosticBag)
Dim previousGeneration = moduleBeingBuilt.PreviousGeneration
If previousGeneration IsNot Nothing Then
' Ensure all previous anonymous type templates are included so the
' types are available for subsequent edit and continue generations.
For Each key In previousGeneration.AnonymousTypeMap.Keys
Dim templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, Function(f) f, Function(f) False)
If key.IsDelegate Then
AnonymousDelegateTemplates.GetOrAdd(templateKey, Function(k) AnonymousDelegateTemplateSymbol.Create(Me, CreatePlaceholderTypeDescriptor(key)))
Else
AnonymousTypeTemplates.GetOrAdd(templateKey, Function(k) New AnonymousTypeTemplateSymbol(Me, CreatePlaceholderTypeDescriptor(key)))
End If
Next
End If
' Ensure all previous anonymous type templates are included so the
' types are available for subsequent edit and continue generations.
For Each key In moduleBeingBuilt.GetPreviousAnonymousTypes()
Dim templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, Function(f) f, Function(f) False)
If key.IsDelegate Then
AnonymousDelegateTemplates.GetOrAdd(templateKey, Function(k) AnonymousDelegateTemplateSymbol.Create(Me, CreatePlaceholderTypeDescriptor(key)))
Else
AnonymousTypeTemplates.GetOrAdd(templateKey, Function(k) New AnonymousTypeTemplateSymbol(Me, CreatePlaceholderTypeDescriptor(key)))
End If
Next
' Get all anonymous types owned by this manager
Dim builder = ArrayBuilder(Of AnonymousTypeOrDelegateTemplateSymbol).GetInstance()
......@@ -225,8 +222,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
moduleId = String.Empty
End If
Dim typeIndex = If(previousGeneration Is Nothing, 0, previousGeneration.GetNextAnonymousTypeIndex(fromDelegates:=False))
Dim delegateIndex = If(previousGeneration Is Nothing, 0, previousGeneration.GetNextAnonymousTypeIndex(fromDelegates:=True))
Dim typeIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex(fromDelegates:=False)
Dim delegateIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex(fromDelegates:=True)
For Each template In builder
Dim name As String = Nothing
Dim index As Integer = 0
......
......@@ -7,6 +7,7 @@ Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.Emit
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.VisualBasic.Emit
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
......@@ -3644,7 +3645,7 @@ End Module
End Function
Private Shared Function GetAllLocals(method As MethodSymbol) As ImmutableArray(Of VisualBasicSyntaxNode)
Dim names = From name In VisualBasicCompilation.GetLocalVariableDeclaratorsVisitor.GetDeclarators(method).OfType(Of ModifiedIdentifierSyntax)
Dim names = From name In GetLocalVariableDeclaratorsVisitor.GetDeclarators(method).OfType(Of ModifiedIdentifierSyntax)
Select DirectCast(name, VisualBasicSyntaxNode)
Return names.AsImmutableOrEmpty
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册