Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@854 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
13 changed files with 244 additions and 19 deletions
@ -0,0 +1,132 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using Boo.Lang.Compiler; |
||||||
|
using Boo.Lang.Compiler.Ast; |
||||||
|
using Boo.Lang.Compiler.Ast.Visitors; |
||||||
|
|
||||||
|
namespace NRefactoryToBooConverter |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Prettifies the Boo code by removing type declarations that aren't required in Boo.
|
||||||
|
/// </summary>
|
||||||
|
public class RemoveRedundantTypeReferencesVisitor : DepthFirstTransformer |
||||||
|
{ |
||||||
|
bool IsVoid(TypeReference typeRef) |
||||||
|
{ |
||||||
|
SimpleTypeReference str = typeRef as SimpleTypeReference; |
||||||
|
return str != null && (str.Name == "void" || str.Name == "System.Void"); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnMethod(Method node) |
||||||
|
{ |
||||||
|
base.OnMethod(node); |
||||||
|
if (IsVoid(node.ReturnType)) |
||||||
|
node.ReturnType = null; |
||||||
|
} |
||||||
|
|
||||||
|
Stack<List<Field>> fieldStack = new Stack<List<Field>>(); |
||||||
|
|
||||||
|
void EnterTypeDefinition(TypeDefinition node) |
||||||
|
{ |
||||||
|
List<Field> list = new List<Field>(); |
||||||
|
fieldStack.Push(list); |
||||||
|
foreach (TypeMember member in node.Members) { |
||||||
|
if (member is Field) |
||||||
|
list.Add((Field)member); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool SearchField(string name) |
||||||
|
{ |
||||||
|
foreach (List<Field> list in fieldStack) { |
||||||
|
foreach (Field field in list) { |
||||||
|
if (field.Name == name) |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnClassDefinition(ClassDefinition node) |
||||||
|
{ |
||||||
|
EnterTypeDefinition(node); |
||||||
|
base.OnClassDefinition(node); |
||||||
|
fieldStack.Pop(); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnStructDefinition(StructDefinition node) |
||||||
|
{ |
||||||
|
EnterTypeDefinition(node); |
||||||
|
base.OnStructDefinition(node); |
||||||
|
fieldStack.Pop(); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnModule(Module node) |
||||||
|
{ |
||||||
|
EnterTypeDefinition(node); |
||||||
|
base.OnModule(node); |
||||||
|
fieldStack.Pop(); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnField(Field node) |
||||||
|
{ |
||||||
|
if (node.Type != null) { |
||||||
|
TypeReference initializerType = GetInferredType(node.Initializer); |
||||||
|
if (node.Type.Matches(initializerType)) { |
||||||
|
node.Type = null; |
||||||
|
} |
||||||
|
} |
||||||
|
base.OnField(node); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnDeclarationStatement(DeclarationStatement node) |
||||||
|
{ |
||||||
|
if (node.Declaration.Type != null && !SearchField(node.Declaration.Name)) { |
||||||
|
TypeReference initializerType = GetInferredType(node.Initializer); |
||||||
|
if (node.Declaration.Type.Matches(initializerType)) { |
||||||
|
node.Declaration.Type = null; |
||||||
|
} |
||||||
|
} |
||||||
|
base.OnDeclarationStatement(node); |
||||||
|
} |
||||||
|
|
||||||
|
TypeReference GetInferredType(Expression expr) |
||||||
|
{ |
||||||
|
switch (expr.NodeType) { |
||||||
|
case NodeType.TypeofExpression: |
||||||
|
return new SimpleTypeReference("type"); |
||||||
|
case NodeType.BoolLiteralExpression: |
||||||
|
return new SimpleTypeReference("bool"); |
||||||
|
case NodeType.IntegerLiteralExpression: |
||||||
|
if (((IntegerLiteralExpression)expr).IsLong) |
||||||
|
break; |
||||||
|
return new SimpleTypeReference("int"); |
||||||
|
case NodeType.StringLiteralExpression: |
||||||
|
return new SimpleTypeReference("string"); |
||||||
|
case NodeType.CharLiteralExpression: |
||||||
|
return new SimpleTypeReference("char"); |
||||||
|
case NodeType.DoubleLiteralExpression: |
||||||
|
if (((DoubleLiteralExpression)expr).IsSingle) |
||||||
|
break; |
||||||
|
return new SimpleTypeReference("double"); |
||||||
|
case NodeType.CastExpression: |
||||||
|
return ((CastExpression)expr).Type; |
||||||
|
case NodeType.TryCastExpression: |
||||||
|
return ((TryCastExpression)expr).Type; |
||||||
|
case NodeType.MethodInvocationExpression: |
||||||
|
MethodInvocationExpression mie = (MethodInvocationExpression)expr; |
||||||
|
if (mie.Target.NodeType == NodeType.ReferenceExpression) |
||||||
|
return new SimpleTypeReference(((ReferenceExpression)mie.Target).Name); |
||||||
|
break; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using NUnit.Framework; |
||||||
|
|
||||||
|
namespace NRefactoryToBooConverter.Tests |
||||||
|
{ |
||||||
|
[TestFixture] |
||||||
|
public class RemoveRedundantTypeReferencesTest : TestHelper |
||||||
|
{ |
||||||
|
protected override void ApplySettings(ConverterSettings settings) |
||||||
|
{ |
||||||
|
base.ApplySettings(settings); |
||||||
|
settings.SimplifyTypeNames = true; |
||||||
|
settings.RemoveRedundantTypeReferences = true; |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void VoidMethod() |
||||||
|
{ |
||||||
|
TestInClass("private void Main() {}", "private def Main():\n\tpass"); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void ConstructorCall() |
||||||
|
{ |
||||||
|
TestStatement("MyClass m = new MyClass(4);", "m = MyClass(4)"); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Cast() |
||||||
|
{ |
||||||
|
TestStatement("MyClass m = (MyClass)variable;", "m = cast(MyClass, variable)"); |
||||||
|
TestStatement("MyClass m = variable as MyClass;", "m = (variable as MyClass)"); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void PrimitiveAssignment() |
||||||
|
{ |
||||||
|
TestStatement("string text = \"Text!\";", "text = 'Text!'"); |
||||||
|
TestStatement("int a = 5;", "a = 5"); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void FieldAndLocalVariable() |
||||||
|
{ |
||||||
|
TestInClass("private int var = 3;\n" + |
||||||
|
"private void Main() {\n" + |
||||||
|
" int var = 5;\n" + |
||||||
|
"}", |
||||||
|
"private var = 3\n" + |
||||||
|
"private def Main():\n" + |
||||||
|
"\tvar as int = 5"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue