Browse Source

Refactor LocalFunctionDeclarationStatement + LocalFunctionMethod

pull/2077/head
Siegfried Pammer 6 years ago
parent
commit
18ace00266
  1. 41
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 12
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  3. 6
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  4. 14
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  5. 29
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  6. 67
      ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs
  7. 8
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 20
      ICSharpCode.Decompiler/CSharp/Transforms/ContextTrackingVisitor.cs
  9. 2
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  10. 31
      ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs

41
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1345,30 +1345,35 @@ namespace ICSharpCode.Decompiler.CSharp
} }
entityDecl.AddAnnotation(function); entityDecl.AddAnnotation(function);
if (function.IsIterator) { CleanUpMethodDeclaration(entityDecl, body, function, localSettings.DecompileMemberBodies);
if (localSettings.DecompileMemberBodies && !body.Descendants.Any(d => d is YieldReturnStatement || d is YieldBreakStatement)) { } catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
body.Add(new YieldBreakStatement()); throw new DecompilerException(module, method, innerException);
} }
if (function.IsAsync) { }
RemoveAttribute(entityDecl, KnownAttribute.AsyncIteratorStateMachine);
} else { internal static void CleanUpMethodDeclaration(EntityDeclaration entityDecl, BlockStatement body, ILFunction function, bool decompileBody = true)
RemoveAttribute(entityDecl, KnownAttribute.IteratorStateMachine); {
} if (function.IsIterator) {
if (function.StateMachineCompiledWithMono) { if (decompileBody && !body.Descendants.Any(d => d is YieldReturnStatement || d is YieldBreakStatement)) {
RemoveAttribute(entityDecl, KnownAttribute.DebuggerHidden); body.Add(new YieldBreakStatement());
}
} }
if (function.IsAsync) { if (function.IsAsync) {
entityDecl.Modifiers |= Modifiers.Async; RemoveAttribute(entityDecl, KnownAttribute.AsyncIteratorStateMachine);
RemoveAttribute(entityDecl, KnownAttribute.AsyncStateMachine); } else {
RemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough); RemoveAttribute(entityDecl, KnownAttribute.IteratorStateMachine);
} }
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) { if (function.StateMachineCompiledWithMono) {
throw new DecompilerException(module, method, innerException); RemoveAttribute(entityDecl, KnownAttribute.DebuggerHidden);
}
}
if (function.IsAsync) {
entityDecl.Modifiers |= Modifiers.Async;
RemoveAttribute(entityDecl, KnownAttribute.AsyncStateMachine);
RemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough);
} }
} }
bool RemoveAttribute(EntityDeclaration entityDecl, KnownAttribute attributeType) internal static bool RemoveAttribute(EntityDeclaration entityDecl, KnownAttribute attributeType)
{ {
bool found = false; bool found = false;
foreach (var section in entityDecl.Attributes) { foreach (var section in entityDecl.Attributes) {

12
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -197,8 +197,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else if (localFunction != null) { } else if (localFunction != null) {
var ide = new IdentifierExpression(localFunction.Name); var ide = new IdentifierExpression(localFunction.Name);
if (method.TypeArguments.Count > 0) { if (method.TypeArguments.Count > 0) {
int skipCount = localFunction.ReducedMethod.NumberOfCompilerGeneratedTypeParameters; ide.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
ide.TypeArguments.AddRange(method.TypeArguments.Skip(skipCount).Select(expressionBuilder.ConvertType));
} }
ide.AddAnnotation(localFunction); ide.AddAnnotation(localFunction);
target = ide.WithoutILInstruction() target = ide.WithoutILInstruction()
@ -1327,7 +1326,6 @@ namespace ICSharpCode.Decompiler.CSharp
target = default; target = default;
targetType = default; targetType = default;
methodName = localFunction.Name; methodName = localFunction.Name;
// TODO : think about how to handle generic local functions
} else if (method.IsExtensionMethod && invokeMethod != null && method.Parameters.Count - 1 == invokeMethod.Parameters.Count) { } else if (method.IsExtensionMethod && invokeMethod != null && method.Parameters.Count - 1 == invokeMethod.Parameters.Count) {
step = 5; step = 5;
targetType = method.Parameters[0].Type; targetType = method.Parameters[0].Type;
@ -1406,11 +1404,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else { } else {
var ide = new IdentifierExpression(methodName); var ide = new IdentifierExpression(methodName);
if ((step & 2) != 0) { if ((step & 2) != 0) {
int skipCount = 0; ide.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
if (localFunction != null && method.TypeArguments.Count > 0) {
skipCount = localFunction.ReducedMethod.NumberOfCompilerGeneratedTypeParameters;
}
ide.TypeArguments.AddRange(method.TypeArguments.Skip(skipCount).Select(expressionBuilder.ConvertType));
} }
targetExpression = ide.WithRR(result); targetExpression = ide.WithRR(result);
} }
@ -1469,7 +1463,7 @@ namespace ICSharpCode.Decompiler.CSharp
method.DeclaringType, method.DeclaringType,
new IParameterizedMember[] { method } new IParameterizedMember[] { method }
) )
}, method.TypeArguments.Skip(localFunction.ReducedMethod.NumberOfCompilerGeneratedTypeParameters).ToArray() }, method.TypeArguments
); );
} }

6
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -92,6 +92,7 @@ namespace ICSharpCode.Decompiler.CSharp
this.astBuilder = new TypeSystemAstBuilder(resolver); this.astBuilder = new TypeSystemAstBuilder(resolver);
this.astBuilder.AlwaysUseShortTypeNames = true; this.astBuilder.AlwaysUseShortTypeNames = true;
this.astBuilder.AddResolveResultAnnotations = true; this.astBuilder.AddResolveResultAnnotations = true;
this.astBuilder.ShowAttributes = true;
this.astBuilder.UseNullableSpecifierForValueTypes = settings.LiftNullables; this.astBuilder.UseNullableSpecifierForValueTypes = settings.LiftNullables;
this.typeInference = new TypeInference(compilation) { Algorithm = TypeInferenceAlgorithm.Improved }; this.typeInference = new TypeInference(compilation) { Algorithm = TypeInferenceAlgorithm.Improved };
} }
@ -1983,7 +1984,7 @@ namespace ICSharpCode.Decompiler.CSharp
return SpecialType.UnknownType; return SpecialType.UnknownType;
} }
internal IEnumerable<ParameterDeclaration> MakeParameters(IReadOnlyList<IParameter> parameters, ILFunction function) IEnumerable<ParameterDeclaration> MakeParameters(IReadOnlyList<IParameter> parameters, ILFunction function)
{ {
var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index); var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);
int i = 0; int i = 0;
@ -1992,9 +1993,6 @@ namespace ICSharpCode.Decompiler.CSharp
if (string.IsNullOrEmpty(pd.Name) && !pd.Type.IsArgList()) { if (string.IsNullOrEmpty(pd.Name) && !pd.Type.IsArgList()) {
// needs to be consistent with logic in ILReader.CreateILVarable(ParameterDefinition) // needs to be consistent with logic in ILReader.CreateILVarable(ParameterDefinition)
pd.Name = "P_" + i; pd.Name = "P_" + i;
// if this is a local function, we have to skip the parameters for closure references
if (settings.LocalFunctions && function.Kind == ILFunctionKind.LocalFunction && IL.Transforms.LocalFunctionDecompiler.IsClosureParameter(parameter, decompilationContext))
break;
} }
if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType()) if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType())
pd.Type = null; pd.Type = null;

14
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1876,19 +1876,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
public virtual void VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement) public virtual void VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement)
{ {
StartNode(localFunctionDeclarationStatement); StartNode(localFunctionDeclarationStatement);
localFunctionDeclarationStatement.Declaration.AcceptVisitor(this);
WriteModifiers(localFunctionDeclarationStatement.ModifierTokens);
localFunctionDeclarationStatement.ReturnType.AcceptVisitor(this);
Space();
WriteIdentifier(localFunctionDeclarationStatement.NameToken);
WriteTypeParameters(localFunctionDeclarationStatement.TypeParameters);
Space(policy.SpaceBeforeMethodDeclarationParentheses);
WriteCommaSeparatedListInParenthesis(localFunctionDeclarationStatement.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
foreach (Constraint constraint in localFunctionDeclarationStatement.Constraints) {
constraint.AcceptVisitor(this);
}
WriteMethodBody(localFunctionDeclarationStatement.Body, policy.MethodBraceStyle);
EndNode(localFunctionDeclarationStatement); EndNode(localFunctionDeclarationStatement);
} }

29
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -1002,34 +1002,19 @@ namespace ICSharpCode.Decompiler.CSharp
LocalFunctionDeclarationStatement TranslateFunction(ILFunction function) LocalFunctionDeclarationStatement TranslateFunction(ILFunction function)
{ {
var stmt = new LocalFunctionDeclarationStatement();
var nestedBuilder = new StatementBuilder(typeSystem, exprBuilder.decompilationContext, function, settings, cancellationToken); var nestedBuilder = new StatementBuilder(typeSystem, exprBuilder.decompilationContext, function, settings, cancellationToken);
stmt.Name = function.Name; var astBuilder = exprBuilder.astBuilder;
stmt.Parameters.AddRange(exprBuilder.MakeParameters(function.Parameters, function)); var method = (MethodDeclaration)astBuilder.ConvertEntity(function.ReducedMethod);
stmt.ReturnType = exprBuilder.ConvertType(function.Method.ReturnType); method.Body = nestedBuilder.ConvertAsBlock(function.Body);
stmt.Body = nestedBuilder.ConvertAsBlock(function.Body);
Comment prev = null; Comment prev = null;
foreach (string warning in function.Warnings) { foreach (string warning in function.Warnings) {
stmt.Body.InsertChildAfter(prev, prev = new Comment(warning), Roles.Comment); method.Body.InsertChildAfter(prev, prev = new Comment(warning), Roles.Comment);
} }
if (function.Method.TypeParameters.Count > 0) { CSharpDecompiler.CleanUpMethodDeclaration(method, method.Body, function);
var astBuilder = exprBuilder.astBuilder; CSharpDecompiler.RemoveAttribute(method, KnownAttribute.CompilerGenerated);
if (astBuilder.ShowTypeParameters) { var stmt = new LocalFunctionDeclarationStatement(method);
int skipCount = function.ReducedMethod.NumberOfCompilerGeneratedTypeParameters;
stmt.TypeParameters.AddRange(function.Method.TypeParameters.Skip(skipCount).Select(t => astBuilder.ConvertTypeParameter(t)));
if (astBuilder.ShowTypeParameterConstraints) {
stmt.Constraints.AddRange(function.Method.TypeParameters.Skip(skipCount).Select(t => astBuilder.ConvertTypeParameterConstraint(t)).Where(c => c != null));
}
}
}
if (function.IsAsync) {
stmt.Modifiers |= Modifiers.Async;
}
if (settings.StaticLocalFunctions && function.ReducedMethod.IsStaticLocalFunction) {
stmt.Modifiers |= Modifiers.Static;
}
stmt.AddAnnotation(new MemberResolveResult(null, function.ReducedMethod)); stmt.AddAnnotation(new MemberResolveResult(null, function.ReducedMethod));
stmt.WithILInstruction(function); stmt.WithILInstruction(function);
return stmt; return stmt;

67
ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs

@ -16,69 +16,22 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
namespace ICSharpCode.Decompiler.CSharp.Syntax namespace ICSharpCode.Decompiler.CSharp.Syntax
{ {
public class LocalFunctionDeclarationStatement : Statement public class LocalFunctionDeclarationStatement : Statement
{ {
public AstNodeCollection<TypeParameterDeclaration> TypeParameters { public static readonly Role<MethodDeclaration> MethodDeclarationRole = new Role<MethodDeclaration>("Method");
get { return GetChildrenByRole(Roles.TypeParameter); }
}
public CSharpTokenNode LParToken {
get { return GetChildByRole(Roles.LPar); }
}
public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole(Roles.Parameter); }
}
public CSharpTokenNode RParToken { public MethodDeclaration Declaration {
get { return GetChildByRole(Roles.RPar); } get { return GetChildByRole(MethodDeclarationRole); }
set { SetChildByRole(MethodDeclarationRole, value); }
} }
public AstNodeCollection<Constraint> Constraints { public LocalFunctionDeclarationStatement(MethodDeclaration methodDeclaration)
get { return GetChildrenByRole(Roles.Constraint); }
}
public BlockStatement Body {
get { return GetChildByRole(Roles.Body); }
set { SetChildByRole(Roles.Body, value); }
}
public Modifiers Modifiers {
get { return EntityDeclaration.GetModifiers(this); }
set { EntityDeclaration.SetModifiers(this, value); }
}
public bool HasModifier(Modifiers mod)
{ {
return (Modifiers & mod) == mod; AddChild(methodDeclaration, MethodDeclarationRole);
}
public IEnumerable<CSharpModifierToken> ModifierTokens {
get { return GetChildrenByRole(EntityDeclaration.ModifierRole); }
}
public virtual string Name {
get {
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value, TextLocation.Empty));
}
}
public virtual Identifier NameToken {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public virtual AstType ReturnType {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
} }
public override void AcceptVisitor(IAstVisitor visitor) public override void AcceptVisitor(IAstVisitor visitor)
@ -98,13 +51,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
protected internal override bool DoMatch(AstNode other, Match match) protected internal override bool DoMatch(AstNode other, Match match)
{ {
LocalFunctionDeclarationStatement o = other as LocalFunctionDeclarationStatement; return other is LocalFunctionDeclarationStatement o && Declaration.DoMatch(o.Declaration, match);
return o != null && MatchString(this.Name, o.Name)
&& (this.Modifiers == Modifiers.Any || this.Modifiers == o.Modifiers)
&& this.ReturnType.DoMatch(o.ReturnType, match)
&& this.TypeParameters.DoMatch(o.TypeParameters, match)
&& this.Parameters.DoMatch(o.Parameters, match) && this.Constraints.DoMatch(o.Constraints, match)
&& this.Body.DoMatch(o.Body, match);
} }
} }
} }

8
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1799,6 +1799,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return !member.IsStatic; return !member.IsStatic;
case SymbolKind.Destructor: case SymbolKind.Destructor:
return false; return false;
case SymbolKind.Method:
return !((IMethod)member).IsLocalFunction;
default: default:
return true; return true;
} }
@ -1811,7 +1813,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
m |= ModifierFromAccessibility (member.Accessibility); m |= ModifierFromAccessibility (member.Accessibility);
} }
if (this.ShowModifiers) { if (this.ShowModifiers) {
if (member.IsStatic) { if (member is LocalFunctionMethod localFunction) {
if (localFunction.IsStaticLocalFunction) {
m |= Modifiers.Static;
}
} else if (member.IsStatic) {
m |= Modifiers.Static; m |= Modifiers.Static;
} else { } else {
var declaringType = member.DeclaringType; var declaringType = member.DeclaringType;

20
ICSharpCode.Decompiler/CSharp/Transforms/ContextTrackingVisitor.cs

@ -55,56 +55,56 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public override TResult VisitMethodDeclaration(MethodDeclaration methodDeclaration) public override TResult VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{ {
Debug.Assert(currentMethod == null); var oldMethod = currentMethod;
try { try {
currentMethod = methodDeclaration.GetSymbol() as IMethod; currentMethod = methodDeclaration.GetSymbol() as IMethod;
return base.VisitMethodDeclaration(methodDeclaration); return base.VisitMethodDeclaration(methodDeclaration);
} finally { } finally {
currentMethod = null; currentMethod = oldMethod;
} }
} }
public override TResult VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) public override TResult VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
{ {
Debug.Assert(currentMethod == null); var oldMethod = currentMethod;
try { try {
currentMethod = constructorDeclaration.GetSymbol() as IMethod; currentMethod = constructorDeclaration.GetSymbol() as IMethod;
return base.VisitConstructorDeclaration(constructorDeclaration); return base.VisitConstructorDeclaration(constructorDeclaration);
} finally { } finally {
currentMethod = null; currentMethod = oldMethod;
} }
} }
public override TResult VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) public override TResult VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
{ {
Debug.Assert(currentMethod == null); var oldMethod = currentMethod;
try { try {
currentMethod = destructorDeclaration.GetSymbol() as IMethod; currentMethod = destructorDeclaration.GetSymbol() as IMethod;
return base.VisitDestructorDeclaration(destructorDeclaration); return base.VisitDestructorDeclaration(destructorDeclaration);
} finally { } finally {
currentMethod = null; currentMethod = oldMethod;
} }
} }
public override TResult VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) public override TResult VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
{ {
Debug.Assert(currentMethod == null); var oldMethod = currentMethod;
try { try {
currentMethod = operatorDeclaration.GetSymbol() as IMethod; currentMethod = operatorDeclaration.GetSymbol() as IMethod;
return base.VisitOperatorDeclaration(operatorDeclaration); return base.VisitOperatorDeclaration(operatorDeclaration);
} finally { } finally {
currentMethod = null; currentMethod = oldMethod;
} }
} }
public override TResult VisitAccessor(Accessor accessor) public override TResult VisitAccessor(Accessor accessor)
{ {
Debug.Assert(currentMethod == null); var oldMethod = currentMethod;
try { try {
currentMethod = accessor.GetSymbol() as IMethod; currentMethod = accessor.GetSymbol() as IMethod;
return base.VisitAccessor(accessor); return base.VisitAccessor(accessor);
} finally { } finally {
currentMethod = null; currentMethod = oldMethod;
} }
} }
} }

2
ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

@ -484,7 +484,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
break; break;
parametersToRemove++; parametersToRemove++;
} }
return new LocalFunctionMethod(method, parametersToRemove, typeParametersToRemove); return new LocalFunctionMethod(method, method.Name, parametersToRemove, typeParametersToRemove);
} }
static void TransformToLocalFunctionReference(ILFunction function, CallInstruction useSite) static void TransformToLocalFunctionReference(ILFunction function, CallInstruction useSite)

31
ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs

@ -31,11 +31,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
readonly IMethod baseMethod; readonly IMethod baseMethod;
public LocalFunctionMethod(IMethod baseMethod, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters) public LocalFunctionMethod(IMethod baseMethod, string name, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters)
{ {
if (baseMethod == null) if (baseMethod == null)
throw new ArgumentNullException(nameof(baseMethod)); throw new ArgumentNullException(nameof(baseMethod));
this.baseMethod = baseMethod; this.baseMethod = baseMethod;
this.Name = name;
this.NumberOfCompilerGeneratedParameters = numberOfCompilerGeneratedParameters; this.NumberOfCompilerGeneratedParameters = numberOfCompilerGeneratedParameters;
this.NumberOfCompilerGeneratedTypeParameters = numberOfCompilerGeneratedTypeParameters; this.NumberOfCompilerGeneratedTypeParameters = numberOfCompilerGeneratedTypeParameters;
} }
@ -65,7 +66,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override string ToString() public override string ToString()
{ {
return string.Format("[LocalFunctionMethod: ReducedFrom={0}, NumberOfGeneratedParameters={1}, NumberOfCompilerGeneratedTypeParameters={2}]", ReducedFrom, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters); return string.Format("[LocalFunctionMethod: ReducedFrom={0}, Name={1}, NumberOfGeneratedParameters={2}, NumberOfCompilerGeneratedTypeParameters={3}]", ReducedFrom, Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);
} }
internal int NumberOfCompilerGeneratedParameters { get; } internal int NumberOfCompilerGeneratedParameters { get; }
@ -88,7 +89,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
return new LocalFunctionMethod( return new LocalFunctionMethod(
baseMethod.Specialize(substitution), baseMethod.Specialize(substitution),
NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters); Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);
} }
IMember IMember.Specialize(TypeParameterSubstitution substitution) IMember IMember.Specialize(TypeParameterSubstitution substitution)
@ -96,7 +97,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return Specialize(substitution); return Specialize(substitution);
} }
public IReadOnlyList<ITypeParameter> TypeParameters => baseMethod.TypeParameters;
public bool IsExtensionMethod => baseMethod.IsExtensionMethod; public bool IsExtensionMethod => baseMethod.IsExtensionMethod;
public bool IsLocalFunction => true; public bool IsLocalFunction => true;
public bool IsConstructor => baseMethod.IsConstructor; public bool IsConstructor => baseMethod.IsConstructor;
@ -107,7 +107,24 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IMember AccessorOwner => baseMethod.AccessorOwner; public IMember AccessorOwner => baseMethod.AccessorOwner;
public MethodSemanticsAttributes AccessorKind => baseMethod.AccessorKind; public MethodSemanticsAttributes AccessorKind => baseMethod.AccessorKind;
public IMethod ReducedFrom => baseMethod; public IMethod ReducedFrom => baseMethod;
public IReadOnlyList<IType> TypeArguments => baseMethod.TypeArguments;
List<ITypeParameter> typeParameters;
public IReadOnlyList<ITypeParameter> TypeParameters {
get {
if (typeParameters == null)
typeParameters = new List<ITypeParameter>(baseMethod.TypeParameters.Skip(NumberOfCompilerGeneratedTypeParameters));
return typeParameters;
}
}
List<IType> typeArguments;
public IReadOnlyList<IType> TypeArguments {
get {
if (typeArguments == null)
typeArguments = new List<IType>(baseMethod.TypeArguments.Skip(NumberOfCompilerGeneratedTypeParameters));
return typeArguments;
}
}
List<IParameter> parameters; List<IParameter> parameters;
public IReadOnlyList<IParameter> Parameters { public IReadOnlyList<IParameter> Parameters {
@ -137,8 +154,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public Accessibility Accessibility => baseMethod.Accessibility; public Accessibility Accessibility => baseMethod.Accessibility;
public string FullName => baseMethod.FullName; public string FullName => Name;
public string Name => baseMethod.Name; public string Name { get; set; }
public string ReflectionName => baseMethod.ReflectionName; public string ReflectionName => baseMethod.ReflectionName;
public string Namespace => baseMethod.Namespace; public string Namespace => baseMethod.Namespace;

Loading…
Cancel
Save