@ -19,6 +19,7 @@
using System ;
using System ;
using System.Collections.Generic ;
using System.Collections.Generic ;
using System.Linq ;
using System.Linq ;
using ICSharpCode.Decompiler.CSharp ;
using ICSharpCode.Decompiler.CSharp ;
using ICSharpCode.Decompiler.CSharp.OutputVisitor ;
using ICSharpCode.Decompiler.CSharp.OutputVisitor ;
using ICSharpCode.Decompiler.CSharp.Resolver ;
using ICSharpCode.Decompiler.CSharp.Resolver ;
@ -26,6 +27,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL ;
using ICSharpCode.Decompiler.IL ;
using ICSharpCode.Decompiler.Semantics ;
using ICSharpCode.Decompiler.Semantics ;
using ICSharpCode.Decompiler.TypeSystem ;
using ICSharpCode.Decompiler.TypeSystem ;
using ICSharpCode.Decompiler.TypeSystem.Implementation ;
namespace ICSharpCode.Decompiler
namespace ICSharpCode.Decompiler
{
{
@ -39,7 +41,7 @@ namespace ICSharpCode.Decompiler
bool inDocumentationComment = false ;
bool inDocumentationComment = false ;
bool firstUsingDeclaration ;
bool firstUsingDeclaration ;
bool lastUsingDeclaration ;
bool lastUsingDeclaration ;
public TextTokenWriter ( ITextOutput output , DecompilerSettings settings , IDecompilerTypeSystem typeSystem )
public TextTokenWriter ( ITextOutput output , DecompilerSettings settings , IDecompilerTypeSystem typeSystem )
{
{
if ( output = = null )
if ( output = = null )
@ -52,13 +54,13 @@ namespace ICSharpCode.Decompiler
this . settings = settings ;
this . settings = settings ;
this . typeSystem = typeSystem ;
this . typeSystem = typeSystem ;
}
}
public override void WriteIdentifier ( Identifier identifier )
public override void WriteIdentifier ( Identifier identifier )
{
{
if ( identifier . IsVerbatim | | CSharpOutputVisitor . IsKeyword ( identifier . Name , identifier ) ) {
if ( identifier . IsVerbatim | | CSharpOutputVisitor . IsKeyword ( identifier . Name , identifier ) ) {
output . Write ( '@' ) ;
output . Write ( '@' ) ;
}
}
var definition = GetCurrentDefinition ( ) ;
var definition = GetCurrentDefinition ( ) ;
string name = TextWriterTokenWriter . EscapeIdentifier ( identifier . Name ) ;
string name = TextWriterTokenWriter . EscapeIdentifier ( identifier . Name ) ;
switch ( definition ) {
switch ( definition ) {
@ -69,7 +71,7 @@ namespace ICSharpCode.Decompiler
output . WriteReference ( m , name , true ) ;
output . WriteReference ( m , name , true ) ;
return ;
return ;
}
}
var member = GetCurrentMemberReference ( ) ;
var member = GetCurrentMemberReference ( ) ;
switch ( member ) {
switch ( member ) {
case IType t :
case IType t :
@ -110,6 +112,7 @@ namespace ICSharpCode.Decompiler
if ( symbol ! = null & & node . Role = = Roles . Type & & node . Parent is ObjectCreateExpression ) {
if ( symbol ! = null & & node . Role = = Roles . Type & & node . Parent is ObjectCreateExpression ) {
symbol = node . Parent . GetSymbol ( ) ;
symbol = node . Parent . GetSymbol ( ) ;
}
}
if ( node is IdentifierExpression & & node . Role = = Roles . TargetExpression & & node . Parent is InvocationExpression & & symbol is IMember member ) {
if ( node is IdentifierExpression & & node . Role = = Roles . TargetExpression & & node . Parent is InvocationExpression & & symbol is IMember member ) {
var declaringType = member . DeclaringType ;
var declaringType = member . DeclaringType ;
if ( declaringType ! = null & & declaringType . Kind = = TypeKind . Delegate )
if ( declaringType ! = null & & declaringType . Kind = = TypeKind . Delegate )
@ -123,10 +126,8 @@ namespace ICSharpCode.Decompiler
if ( symbol = = null )
if ( symbol = = null )
return null ;
return null ;
//if (settings.AutomaticEvents && member is FieldDefinition) {
if ( symbol is LocalFunctionMethod )
// var field = (FieldDefinition)member;
return null ;
// return field.DeclaringType.Events.FirstOrDefault(ev => ev.Name == field.Name) ?? member;
//}
return symbol ;
return symbol ;
}
}
@ -142,14 +143,18 @@ namespace ICSharpCode.Decompiler
if ( letClauseVariable ! = null )
if ( letClauseVariable ! = null )
return letClauseVariable ;
return letClauseVariable ;
var gotoStatement = node as GotoStatement ;
if ( node is GotoStatement gotoStatement ) {
if ( gotoStatement ! = null )
{
var method = nodeStack . Select ( nd = > nd . GetSymbol ( ) as IMethod ) . FirstOrDefault ( mr = > mr ! = null ) ;
var method = nodeStack . Select ( nd = > nd . GetSymbol ( ) as IMethod ) . FirstOrDefault ( mr = > mr ! = null ) ;
if ( method ! = null )
if ( method ! = null )
return method + gotoStatement . Label ;
return method + gotoStatement . Label ;
}
}
if ( node . Role = = Roles . TargetExpression & & node . Parent is InvocationExpression ) {
var symbol = node . Parent . GetSymbol ( ) ;
if ( symbol is LocalFunctionMethod )
return symbol ;
}
return null ;
return null ;
}
}
@ -177,29 +182,29 @@ namespace ICSharpCode.Decompiler
return method + label . Label ;
return method + label . Label ;
}
}
if ( node is LocalFunctionDeclarationStatement ) {
if ( node is MethodDeclaration & & node . Parent is LocalFunctionDeclarationStatement ) {
var localFunction = node . GetResolveResult ( ) as MemberResolveResult ;
var localFunction = node . Parent . GetResolveResult ( ) as MemberResolveResult ;
if ( localFunction ! = null )
if ( localFunction ! = null )
return localFunction . Member ;
return localFunction . Member ;
}
}
return null ;
return null ;
}
}
ISymbol GetCurrentDefinition ( )
ISymbol GetCurrentDefinition ( )
{
{
if ( nodeStack = = null | | nodeStack . Count = = 0 )
if ( nodeStack = = null | | nodeStack . Count = = 0 )
return null ;
return null ;
var node = nodeStack . Peek ( ) ;
var node = nodeStack . Peek ( ) ;
if ( node is Identifier )
if ( node is Identifier )
node = node . Parent ;
node = node . Parent ;
if ( IsDefinition ( ref node ) )
if ( IsDefinition ( ref node ) )
return node . GetSymbol ( ) ;
return node . GetSymbol ( ) ;
return null ;
return null ;
}
}
public override void WriteKeyword ( Role role , string keyword )
public override void WriteKeyword ( Role role , string keyword )
{
{
//To make reference for 'this' and 'base' keywords in the ClassName():this() expression
//To make reference for 'this' and 'base' keywords in the ClassName():this() expression
@ -211,7 +216,7 @@ namespace ICSharpCode.Decompiler
}
}
output . Write ( keyword ) ;
output . Write ( keyword ) ;
}
}
public override void WriteToken ( Role role , string token )
public override void WriteToken ( Role role , string token )
{
{
switch ( token ) {
switch ( token ) {
@ -253,22 +258,22 @@ namespace ICSharpCode.Decompiler
break ;
break ;
}
}
}
}
public override void Space ( )
public override void Space ( )
{
{
output . Write ( ' ' ) ;
output . Write ( ' ' ) ;
}
}
public override void Indent ( )
public override void Indent ( )
{
{
output . Indent ( ) ;
output . Indent ( ) ;
}
}
public override void Unindent ( )
public override void Unindent ( )
{
{
output . Unindent ( ) ;
output . Unindent ( ) ;
}
}
public override void NewLine ( )
public override void NewLine ( )
{
{
if ( ! firstUsingDeclaration & & lastUsingDeclaration ) {
if ( ! firstUsingDeclaration & & lastUsingDeclaration ) {
@ -277,7 +282,7 @@ namespace ICSharpCode.Decompiler
}
}
output . WriteLine ( ) ;
output . WriteLine ( ) ;
}
}
public override void WriteComment ( CommentType commentType , string content )
public override void WriteComment ( CommentType commentType , string content )
{
{
switch ( commentType ) {
switch ( commentType ) {
@ -309,7 +314,7 @@ namespace ICSharpCode.Decompiler
break ;
break ;
}
}
}
}
public override void WritePreProcessorDirective ( PreProcessorDirectiveType type , string argument )
public override void WritePreProcessorDirective ( PreProcessorDirectiveType type , string argument )
{
{
// pre-processor directive must start on its own line
// pre-processor directive must start on its own line
@ -321,7 +326,7 @@ namespace ICSharpCode.Decompiler
}
}
output . WriteLine ( ) ;
output . WriteLine ( ) ;
}
}
public override void WritePrimitiveValue ( object value , LiteralFormat format = LiteralFormat . None )
public override void WritePrimitiveValue ( object value , LiteralFormat format = LiteralFormat . None )
{
{
new TextWriterTokenWriter ( new TextOutputWriter ( output ) ) . WritePrimitiveValue ( value , format ) ;
new TextWriterTokenWriter ( new TextOutputWriter ( output ) ) . WritePrimitiveValue ( value , format ) ;
@ -376,7 +381,7 @@ namespace ICSharpCode.Decompiler
break ;
break ;
}
}
}
}
public override void StartNode ( AstNode node )
public override void StartNode ( AstNode node )
{
{
if ( nodeStack . Count = = 0 ) {
if ( nodeStack . Count = = 0 ) {
@ -390,7 +395,7 @@ namespace ICSharpCode.Decompiler
}
}
nodeStack . Push ( node ) ;
nodeStack . Push ( node ) ;
}
}
private bool IsUsingDeclaration ( AstNode node )
private bool IsUsingDeclaration ( AstNode node )
{
{
return node is UsingDeclaration | | node is UsingAliasDeclaration ;
return node is UsingDeclaration | | node is UsingAliasDeclaration ;
@ -401,10 +406,10 @@ namespace ICSharpCode.Decompiler
if ( nodeStack . Pop ( ) ! = node )
if ( nodeStack . Pop ( ) ! = node )
throw new InvalidOperationException ( ) ;
throw new InvalidOperationException ( ) ;
}
}
public static bool IsDefinition ( ref AstNode node )
public static bool IsDefinition ( ref AstNode node )
{
{
if ( node is EntityDeclaration )
if ( node is EntityDeclaration & & ! ( node . Parent is LocalFunctionDeclarationStatement ) )
return true ;
return true ;
if ( node is VariableInitializer & & node . Parent is FieldDeclaration ) {
if ( node is VariableInitializer & & node . Parent is FieldDeclaration ) {
node = node . Parent ;
node = node . Parent ;