Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
d0827ae8c3
  1. 33
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 8
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  3. 1
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  4. 27
      ICSharpCode.Decompiler/Tests/MultidimensionalArray.cs
  5. 3
      ILSpy/AboutPage.cs
  6. 74
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs
  7. 17
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/InsertParenthesesVisitor.cs
  8. 4
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

33
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -273,7 +273,7 @@ namespace Decompiler
// Do branches first because TransformExpressionArguments does not work on arguments that are branches themselfs // Do branches first because TransformExpressionArguments does not work on arguments that are branches themselfs
// TODO: We should probably have virtual instructions for these and not abuse branch codes as expressions // TODO: We should probably have virtual instructions for these and not abuse branch codes as expressions
switch(opCode) { switch(opCode) {
case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name); case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
case ILCode.Brfalse: case ILCode.Brfalse:
case ILCode.Brtrue: case ILCode.Brtrue:
case ILCode.Beq: case ILCode.Beq:
@ -293,7 +293,7 @@ namespace Decompiler
TrueStatement = new BlockStatement() { TrueStatement = new BlockStatement() {
new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name) new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
} }
}; };
} }
List<Ast.Expression> args = TransformExpressionArguments(byteCode); List<Ast.Expression> args = TransformExpressionArguments(byteCode);
@ -361,14 +361,13 @@ namespace Decompiler
case Code.Stelem_R4: case Code.Stelem_R4:
case Code.Stelem_R8: case Code.Stelem_R8:
case Code.Stelem_Ref: case Code.Stelem_Ref:
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
case Code.Stelem_Any: case Code.Stelem_Any:
return InlineAssembly(byteCode, args); return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
#endregion #endregion
#region Comparison #region Comparison
case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2); case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
case Code.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2); case Code.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
case Code.Cgt_Un: case Code.Cgt_Un:
// can also mean Inequality, when used with object references // can also mean Inequality, when used with object references
{ {
TypeReference arg1Type = byteCode.Arguments[0].InferredType; TypeReference arg1Type = byteCode.Arguments[0].InferredType;
@ -568,14 +567,18 @@ namespace Decompiler
case Code.Newobj: case Code.Newobj:
{ {
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
// TODO: Ensure that the corrent overloaded constructor is called
/*if (declaringType is ArrayType) { shouldn't this be newarr? if (declaringType is ArrayType) {
return new Ast.ArrayCreateExpression { ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
Type = AstBuilder.ConvertType((ArrayType)declaringType), if (ct != null && ct.ArraySpecifiers.Count >= 1) {
Arguments = args var ace = new Ast.ArrayCreateExpression();
}; ct.ArraySpecifiers.First().Remove();
}*/ ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
ace.Type = ct;
ace.Arguments.AddRange(args);
return ace;
}
}
var oce = new Ast.ObjectCreateExpression(); var oce = new Ast.ObjectCreateExpression();
oce.Type = AstBuilder.ConvertType(declaringType); oce.Type = AstBuilder.ConvertType(declaringType);
oce.Arguments.AddRange(args); oce.Arguments.AddRange(args);
@ -639,6 +642,12 @@ namespace Decompiler
} }
} }
if (cecilMethod.Name == "Get" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 1) {
return target.Indexer(methodArgs);
} else if (cecilMethod.Name == "Set" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 2) {
return new AssignmentExpression(target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)), methodArgs.Last());
}
// Resolve the method to figure out whether it is an accessor: // Resolve the method to figure out whether it is an accessor:
Cecil.MethodDefinition cecilMethodDef = cecilMethod.Resolve(); Cecil.MethodDefinition cecilMethodDef = cecilMethod.Resolve();
if (cecilMethodDef != null) { if (cecilMethodDef != null) {

8
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -116,7 +116,7 @@ namespace Decompiler
case ILCode.BrLogicOr: case ILCode.BrLogicOr:
if (forceInferChildren) { if (forceInferChildren) {
InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean); InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean);
InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean); InferTypeForExpression(expr.Arguments[1], typeSystem.Boolean);
} }
return null; return null;
#endregion #endregion
@ -524,7 +524,11 @@ namespace Decompiler
if (gp.Owner.GenericParameterType == GenericParameterType.Method) { if (gp.Owner.GenericParameterType == GenericParameterType.Method) {
return ((GenericInstanceMethod)member).GenericArguments[gp.Position]; return ((GenericInstanceMethod)member).GenericArguments[gp.Position];
} else { } else {
return ((GenericInstanceType)member.DeclaringType).GenericArguments[gp.Position]; if (member.DeclaringType is ArrayType) {
return ((ArrayType)member.DeclaringType).ElementType;
} else {
return ((GenericInstanceType)member.DeclaringType).GenericArguments[gp.Position];
}
} }
} }
return type; return type;

1
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -50,6 +50,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="DelegateConstruction.cs" /> <Compile Include="DelegateConstruction.cs" />
<Compile Include="ExceptionHandling.cs" /> <Compile Include="ExceptionHandling.cs" />
<Compile Include="MultidimensionalArray.cs" />
<Compile Include="Loops.cs" /> <Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" /> <Compile Include="PropertiesAndEvents.cs" />
<Compile Include="TestRunner.cs" /> <Compile Include="TestRunner.cs" />

27
ICSharpCode.Decompiler/Tests/MultidimensionalArray.cs

@ -0,0 +1,27 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
public static class MultidimensionalArray
{
internal class Generic<T, S> where T : new()
{
private T[,] a = new T[20, 20];
private S[,][] b = new S[20, 20][];
public T this[int i, int j]
{
get { return a[i, j]; }
set { a[i, j] = value; }
}
public void TestB(S x, ref S y)
{
b[5, 3] = new S[10];
b[5, 3][0] = default(S);
b[5, 3][1] = x;
b[5, 3][2] = y;
}
}
}

3
ILSpy/AboutPage.cs

@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy
delegate (Task<AvailableVersionInfo> task) { delegate (Task<AvailableVersionInfo> task) {
try { try {
stackPanel.Children.Clear(); stackPanel.Children.Clear();
ShowAvailableVersion(latestAvailableVersion, stackPanel); ShowAvailableVersion(task.Result, stackPanel);
} catch (Exception ex) { } catch (Exception ex) {
AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput(); AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput();
exceptionOutput.WriteLine(ex.ToString()); exceptionOutput.WriteLine(ex.ToString());
@ -128,6 +128,7 @@ namespace ICSharpCode.ILSpy
{ {
var tcs = new TaskCompletionSource<AvailableVersionInfo>(); var tcs = new TaskCompletionSource<AvailableVersionInfo>();
WebClient wc = new WebClient(); WebClient wc = new WebClient();
wc.Proxy = new WebProxy() { UseDefaultCredentials = true };
wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) { wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
if (e.Error != null) { if (e.Error != null) {
tcs.SetException(e.Error); tcs.SetException(e.Error);

74
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs

@ -159,7 +159,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void MethodCallOnQueryExpression() public void MethodCallOnQueryExpression()
{ {
Expression expr = new QueryExpression { Expression expr = new QueryExpression {
Clauses = new QueryClause[] { Clauses = {
new QueryFromClause { new QueryFromClause {
Identifier = "a", Identifier = "a",
Expression = new IdentifierExpression("b") Expression = new IdentifierExpression("b")
@ -178,7 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void SumOfQueries() public void SumOfQueries()
{ {
QueryExpression query = new QueryExpression { QueryExpression query = new QueryExpression {
Clauses = new QueryClause[] { Clauses = {
new QueryFromClause { new QueryFromClause {
Identifier = "a", Identifier = "a",
Expression = new IdentifierExpression("b") Expression = new IdentifierExpression("b")
@ -206,7 +206,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void QueryInTypeTest() public void QueryInTypeTest()
{ {
Expression expr = new QueryExpression { Expression expr = new QueryExpression {
Clauses = new QueryClause[] { Clauses = {
new QueryFromClause { new QueryFromClause {
Identifier = "a", Identifier = "a",
Expression = new IdentifierExpression("b") Expression = new IdentifierExpression("b")
@ -252,5 +252,73 @@ namespace ICSharpCode.NRefactory.CSharp
Assert.AreEqual("(++a)++", InsertRequired(expr)); Assert.AreEqual("(++a)++", InsertRequired(expr));
Assert.AreEqual("(++a)++", InsertReadable(expr)); Assert.AreEqual("(++a)++", InsertReadable(expr));
} }
[Test]
public void Logical1()
{
Expression expr = new BinaryOperatorExpression(
new BinaryOperatorExpression(
new IdentifierExpression("a"),
BinaryOperatorType.ConditionalAnd,
new IdentifierExpression("b")
),
BinaryOperatorType.ConditionalAnd,
new IdentifierExpression("c")
);
Assert.AreEqual("a && b && c", InsertRequired(expr));
Assert.AreEqual("a && b && c", InsertReadable(expr));
}
[Test]
public void Logical2()
{
Expression expr = new BinaryOperatorExpression(
new IdentifierExpression("a"),
BinaryOperatorType.ConditionalAnd,
new BinaryOperatorExpression(
new IdentifierExpression("b"),
BinaryOperatorType.ConditionalAnd,
new IdentifierExpression("c")
)
);
Assert.AreEqual("a && (b && c)", InsertRequired(expr));
Assert.AreEqual("a && (b && c)", InsertReadable(expr));
}
[Test]
public void Logical3()
{
Expression expr = new BinaryOperatorExpression(
new IdentifierExpression("a"),
BinaryOperatorType.ConditionalOr,
new BinaryOperatorExpression(
new IdentifierExpression("b"),
BinaryOperatorType.ConditionalAnd,
new IdentifierExpression("c")
)
);
Assert.AreEqual("a || b && c", InsertRequired(expr));
Assert.AreEqual("a || (b && c)", InsertReadable(expr));
}
[Test]
public void Logical4()
{
Expression expr = new BinaryOperatorExpression(
new IdentifierExpression("a"),
BinaryOperatorType.ConditionalAnd,
new BinaryOperatorExpression(
new IdentifierExpression("b"),
BinaryOperatorType.ConditionalOr,
new IdentifierExpression("c")
)
);
Assert.AreEqual("a && (b || c)", InsertRequired(expr));
Assert.AreEqual("a && (b || c)", InsertReadable(expr));
}
} }
} }

17
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/InsertParenthesesVisitor.cs

@ -186,7 +186,13 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} else { } else {
if (InsertParenthesesForReadability && precedence < Equality) { if (InsertParenthesesForReadability && precedence < Equality) {
ParenthesizeIfRequired(binaryOperatorExpression.Left, Equality); // In readable mode, boost the priority of the left-hand side if the operator
// there isn't the same as the operator on this expression.
if (GetBinaryOperatorType(binaryOperatorExpression.Left) == binaryOperatorExpression.Operator) {
ParenthesizeIfRequired(binaryOperatorExpression.Left, precedence);
} else {
ParenthesizeIfRequired(binaryOperatorExpression.Left, Equality);
}
ParenthesizeIfRequired(binaryOperatorExpression.Right, Equality); ParenthesizeIfRequired(binaryOperatorExpression.Right, Equality);
} else { } else {
// all other binary operators are left-associative // all other binary operators are left-associative
@ -197,6 +203,15 @@ namespace ICSharpCode.NRefactory.CSharp
return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data); return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data);
} }
BinaryOperatorType? GetBinaryOperatorType(Expression expr)
{
BinaryOperatorExpression boe = expr as BinaryOperatorExpression;
if (boe != null)
return boe.Operator;
else
return null;
}
public override object VisitIsExpression(IsExpression isExpression, object data) public override object VisitIsExpression(IsExpression isExpression, object data)
{ {
if (InsertParenthesesForReadability) { if (InsertParenthesesForReadability) {

4
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -566,7 +566,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteKeyword("checked"); WriteKeyword("checked");
LPar(); LPar();
Space(policy.WithinCheckedExpressionParantheses); Space(policy.WithinCheckedExpressionParantheses);
checkedExpression.AcceptVisitor(this, data); checkedExpression.Expression.AcceptVisitor(this, data);
Space(policy.WithinCheckedExpressionParantheses); Space(policy.WithinCheckedExpressionParantheses);
RPar(); RPar();
return EndNode(checkedExpression); return EndNode(checkedExpression);
@ -933,7 +933,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteKeyword("unchecked"); WriteKeyword("unchecked");
LPar(); LPar();
Space(policy.WithinCheckedExpressionParantheses); Space(policy.WithinCheckedExpressionParantheses);
uncheckedExpression.AcceptVisitor(this, data); uncheckedExpression.Expression.AcceptVisitor(this, data);
Space(policy.WithinCheckedExpressionParantheses); Space(policy.WithinCheckedExpressionParantheses);
RPar(); RPar();
return EndNode(uncheckedExpression); return EndNode(uncheckedExpression);

Loading…
Cancel
Save