Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,12 @@ private SynthesizedHotReloadExceptionSymbol GetOrCreateSynthesizedHotReloadExcep
}

var exceptionType = Compilation.GetWellKnownType(WellKnownType.System_Exception);
var actionOfTType = Compilation.GetWellKnownType(WellKnownType.System_Action_T);
var stringType = Compilation.GetSpecialType(SpecialType.System_String);
var intType = Compilation.GetSpecialType(SpecialType.System_Int32);

var containingNamespace = GetOrSynthesizeNamespace(SynthesizedHotReloadExceptionSymbol.NamespaceName);
symbol = new SynthesizedHotReloadExceptionSymbol(containingNamespace, exceptionType, stringType, intType);
symbol = new SynthesizedHotReloadExceptionSymbol(containingNamespace, exceptionType, actionOfTType, stringType, intType);

Interlocked.CompareExchange(ref _lazyHotReloadExceptionType, symbol, comparand: null);
return _lazyHotReloadExceptionType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,47 @@ internal override void GenerateMethodBody(TypeCompilationState compilationState,
return;
}

var delegateInvoke = (containingType.CreatedActionField.Type as NamedTypeSymbol)?.DelegateInvokeMethod;
if (delegateInvoke is null ||
delegateInvoke.ReturnType.SpecialType != SpecialType.System_Void ||
delegateInvoke.GetParameters() is not [{ RefKind: RefKind.None } parameter] ||
!parameter.Type.Equals(exceptionConstructor.ContainingType))
{
diagnostics.Add(ErrorCode.ERR_EncUpdateFailedMissingSymbol,
Location.None,
CodeAnalysisResources.Method,
"void System.Action<T>.Invoke(T arg)");

factory.CloseMethod(factory.Block());
return;
}

var actionTemp = factory.StoreToTemp(
factory.Field(receiver: null, containingType.CreatedActionField),
out var storeAction);

var block = factory.Block(
ImmutableArray.Create<BoundStatement>(
factory.ExpressionStatement(factory.Call(
factory.This(),
exceptionConstructor,
factory.Parameter(MessageParameter))),
factory.Assignment(factory.Field(factory.This(), containingType.CodeField), factory.Parameter(CodeParameter)),
factory.Return()
));
[actionTemp.LocalSymbol],

// base(message)
factory.ExpressionStatement(factory.Call(
factory.This(),
exceptionConstructor,
factory.Parameter(MessageParameter))),

// this.CodeField = code;
factory.Assignment(factory.Field(factory.This(), containingType.CodeField), factory.Parameter(CodeParameter)),

// s_created?.Invoke(this);
factory.If(
factory.IsNotNullReference(storeAction),
factory.ExpressionStatement(
factory.Call(
actionTemp,
delegateInvoke,
factory.This()))),

factory.Return());

factory.CloseMethod(block);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ internal sealed class SynthesizedHotReloadExceptionSymbol : NamedTypeSymbol
public const string TypeName = "HotReloadException";
public const string CodeFieldName = "Code";

/// <summary>
/// The Hot Reload agent that's injected into the application needs to intercept creation of a runtime rude edit.
/// It uses reflection to set this action field.
/// </summary>
public const string CreatedActionFieldName = "Created";

private readonly NamedTypeSymbol _baseType;
private readonly NamespaceSymbol _namespace;

Expand All @@ -31,6 +37,7 @@ internal sealed class SynthesizedHotReloadExceptionSymbol : NamedTypeSymbol
public SynthesizedHotReloadExceptionSymbol(
NamespaceSymbol containingNamespace,
NamedTypeSymbol exceptionType,
NamedTypeSymbol actionOfTType,
TypeSymbol stringType,
TypeSymbol intType)
{
Expand All @@ -40,7 +47,8 @@ public SynthesizedHotReloadExceptionSymbol(
_members =
[
new SynthesizedHotReloadExceptionConstructorSymbol(this, stringType, intType),
new SynthesizedFieldSymbol(this, intType, CodeFieldName, DeclarationModifiers.Public, isReadOnly: true, isStatic: false)
new SynthesizedFieldSymbol(this, intType, CodeFieldName, DeclarationModifiers.Public, isReadOnly: true, isStatic: false),
new SynthesizedFieldSymbol(this, actionOfTType.Construct(exceptionType), CreatedActionFieldName, DeclarationModifiers.Private, isReadOnly: false, isStatic: true)
];
}

Expand All @@ -50,6 +58,9 @@ public MethodSymbol Constructor
public FieldSymbol CodeField
=> (FieldSymbol)_members[1];

public FieldSymbol CreatedActionField
=> (FieldSymbol)_members[2];

public override ImmutableArray<Symbol> GetMembers()
=> _members;

Expand All @@ -58,14 +69,15 @@ public override ImmutableArray<Symbol> GetMembers(string name)
{
WellKnownMemberNames.InstanceConstructorName => [Constructor],
CodeFieldName => [CodeField],
CreatedActionFieldName => [CreatedActionField],
_ => []
};

public override IEnumerable<string> MemberNames
=> _members.Select(static m => m.Name);

internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
=> [CodeField];
=> [CodeField, CreatedActionField];

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers() => [];
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name) => [];
Expand Down
Loading