140 lines
4.0 KiB
C#
140 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Immutable;
|
|
using System.ComponentModel;
|
|
using Microsoft.CodeAnalysis.Symbols;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.Emit;
|
|
|
|
public readonly struct SemanticEdit : IEquatable<SemanticEdit>
|
|
{
|
|
public SemanticEditKind Kind { get; }
|
|
|
|
public ISymbol? OldSymbol { get; }
|
|
|
|
public ISymbol? NewSymbol { get; }
|
|
|
|
public Func<SyntaxNode, SyntaxNode?>? SyntaxMap { get; }
|
|
|
|
public bool PreserveLocalVariables { get; }
|
|
|
|
public MethodInstrumentation Instrumentation { get; }
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public SemanticEdit(SemanticEditKind kind, ISymbol? oldSymbol, ISymbol? newSymbol, Func<SyntaxNode, SyntaxNode?>? syntaxMap, bool preserveLocalVariables)
|
|
: this(kind, oldSymbol, newSymbol, syntaxMap, preserveLocalVariables, MethodInstrumentation.Empty)
|
|
{
|
|
}
|
|
|
|
public SemanticEdit(SemanticEditKind kind, ISymbol? oldSymbol, ISymbol? newSymbol, Func<SyntaxNode, SyntaxNode?>? syntaxMap = null, bool preserveLocalVariables = false, MethodInstrumentation instrumentation = default(MethodInstrumentation))
|
|
{
|
|
if (kind <= SemanticEditKind.None || kind > SemanticEditKind.Replace)
|
|
{
|
|
throw new ArgumentOutOfRangeException("kind");
|
|
}
|
|
bool flag = oldSymbol == null;
|
|
if (flag)
|
|
{
|
|
bool flag2 = ((kind == SemanticEditKind.Insert || kind == SemanticEditKind.Replace) ? true : false);
|
|
flag = !flag2;
|
|
}
|
|
if (flag)
|
|
{
|
|
throw new ArgumentNullException("oldSymbol");
|
|
}
|
|
if (newSymbol == null)
|
|
{
|
|
throw new ArgumentNullException("newSymbol");
|
|
}
|
|
if (instrumentation.IsDefault)
|
|
{
|
|
instrumentation = MethodInstrumentation.Empty;
|
|
}
|
|
if (!instrumentation.IsEmpty)
|
|
{
|
|
if (kind != SemanticEditKind.Update)
|
|
{
|
|
throw new ArgumentOutOfRangeException("kind");
|
|
}
|
|
if (!(oldSymbol is IMethodSymbol))
|
|
{
|
|
throw new ArgumentException(CodeAnalysisResources.MethodSymbolExpected, "oldSymbol");
|
|
}
|
|
if (!(newSymbol is IMethodSymbol))
|
|
{
|
|
throw new ArgumentException(CodeAnalysisResources.MethodSymbolExpected, "newSymbol");
|
|
}
|
|
ImmutableArray<InstrumentationKind>.Enumerator enumerator = instrumentation.Kinds.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
InstrumentationKind current = enumerator.Current;
|
|
if (!current.IsValid())
|
|
{
|
|
throw new ArgumentOutOfRangeException("Kinds", string.Format(CodeAnalysisResources.InvalidInstrumentationKind, current));
|
|
}
|
|
}
|
|
}
|
|
Kind = kind;
|
|
OldSymbol = oldSymbol;
|
|
NewSymbol = newSymbol;
|
|
PreserveLocalVariables = preserveLocalVariables;
|
|
SyntaxMap = syntaxMap;
|
|
Instrumentation = instrumentation;
|
|
}
|
|
|
|
internal SemanticEdit(IMethodSymbol oldSymbol, IMethodSymbol newSymbol, ImmutableArray<InstrumentationKind> instrumentationKinds)
|
|
{
|
|
SyntaxMap = null;
|
|
PreserveLocalVariables = false;
|
|
Kind = SemanticEditKind.Update;
|
|
OldSymbol = oldSymbol;
|
|
NewSymbol = newSymbol;
|
|
Instrumentation = new MethodInstrumentation
|
|
{
|
|
Kinds = instrumentationKinds
|
|
};
|
|
}
|
|
|
|
internal static SemanticEdit Create(SemanticEditKind kind, ISymbolInternal oldSymbol, ISymbolInternal newSymbol, Func<SyntaxNode, SyntaxNode>? syntaxMap = null, bool preserveLocalVariables = false)
|
|
{
|
|
return new SemanticEdit(kind, oldSymbol?.GetISymbol(), newSymbol?.GetISymbol(), syntaxMap, preserveLocalVariables, default(MethodInstrumentation));
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return Hash.Combine(OldSymbol, Hash.Combine(NewSymbol, (int)Kind));
|
|
}
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
if (obj is SemanticEdit other)
|
|
{
|
|
return Equals(other);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(SemanticEdit other)
|
|
{
|
|
if (Kind == other.Kind && ((OldSymbol == null) ? (other.OldSymbol == null) : OldSymbol.Equals(other.OldSymbol)))
|
|
{
|
|
if (NewSymbol != null)
|
|
{
|
|
return NewSymbol.Equals(other.NewSymbol);
|
|
}
|
|
return other.NewSymbol == null;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool operator ==(SemanticEdit left, SemanticEdit right)
|
|
{
|
|
return left.Equals(right);
|
|
}
|
|
|
|
public static bool operator !=(SemanticEdit left, SemanticEdit right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
}
|