[scripting] more parenthesis handling improvements
This commit is contained in:
Родитель
b431bf2c21
Коммит
750ca6e853
|
@ -2,6 +2,13 @@ using System;
|
||||||
|
|
||||||
namespace UnityScript2CSharp.Tests
|
namespace UnityScript2CSharp.Tests
|
||||||
{
|
{
|
||||||
|
public class C
|
||||||
|
{
|
||||||
|
public static int staticField;
|
||||||
|
public static int staticMethod() { return 1; }
|
||||||
|
public int instanceMethod() { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
public struct Other
|
public struct Other
|
||||||
{
|
{
|
||||||
public string value;
|
public string value;
|
||||||
|
|
|
@ -65,6 +65,19 @@ namespace UnityScript2CSharp.Tests
|
||||||
AssertConversion(sources, expectedConverted);
|
AssertConversion(sources, expectedConverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("o.staticField = 1;", "C.staticField = 1;")]
|
||||||
|
[TestCase("var i = o.staticField + 1;", "int i = C.staticField + 1;")]
|
||||||
|
[TestCase("var i = o.staticField + o.staticMethod();", "int i = C.staticField + C.staticMethod();")]
|
||||||
|
[TestCase("o.staticMethod();", "C.staticMethod();")]
|
||||||
|
[TestCase("C.staticMethod();", "C.staticMethod();")] // Proof that static references through a type ref are not affected
|
||||||
|
public void Static_Members_Through_Instance_Are_Updated(string usSnippet, string csSnippet)
|
||||||
|
{
|
||||||
|
SourceFile[] sources = { new SourceFile("static_member.js", $"import UnityScript2CSharp.Tests; function F(o:C) {{ {usSnippet} return 1; }}") };
|
||||||
|
SourceFile[] expectedConverted = { new SourceFile("static_member.cs", "using UnityScript2CSharp.Tests; " + DefaultGeneratedClass + $"static_member : MonoBehaviour {{ public virtual int F(C o) {{ {csSnippet} return 1; }} }}") };
|
||||||
|
|
||||||
|
AssertConversion(sources, expectedConverted);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Additional_Imports()
|
public void Additional_Imports()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Boo.Lang.Compiler.Ast;
|
using System.Linq;
|
||||||
|
using Boo.Lang.Compiler.Ast;
|
||||||
using Boo.Lang.Compiler.TypeSystem;
|
using Boo.Lang.Compiler.TypeSystem;
|
||||||
|
|
||||||
namespace UnityScript2CSharp.Extensions
|
namespace UnityScript2CSharp.Extensions
|
||||||
|
@ -10,7 +11,7 @@ namespace UnityScript2CSharp.Extensions
|
||||||
if (node.NodeType != NodeType.MethodInvocationExpression)
|
if (node.NodeType != NodeType.MethodInvocationExpression)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var invocation = (MethodInvocationExpression) node;
|
var invocation = (MethodInvocationExpression)node;
|
||||||
return invocation.Target.Entity != null && invocation.Target.Entity.EntityType == EntityType.Constructor;
|
return invocation.Target.Entity != null && invocation.Target.Entity.EntityType == EntityType.Constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +20,15 @@ namespace UnityScript2CSharp.Extensions
|
||||||
if (node.NodeType != NodeType.GenericReferenceExpression)
|
if (node.NodeType != NodeType.GenericReferenceExpression)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var gre = (GenericReferenceExpression) node;
|
var gre = (GenericReferenceExpression)node;
|
||||||
// Arrays in UnityScript are represented as a GenericReferenceExpession
|
// Arrays in UnityScript are represented as a GenericReferenceExpession
|
||||||
var target = gre.Target as ReferenceExpression;
|
var target = gre.Target as ReferenceExpression;
|
||||||
return target != null && target.Name == "array";
|
return target != null && target.Name == "array";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool NeedsQualificationFor(this Node node, INamespace ns)
|
||||||
|
{
|
||||||
|
return node.GetAncestors<Import>().Any(imp => imp.Namespace == ns.FullName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Boo.Lang.Compiler.Ast;
|
||||||
|
using Boo.Lang.Compiler.Steps;
|
||||||
|
using Boo.Lang.Compiler.TypeSystem;
|
||||||
|
using UnityScript2CSharp.Extensions;
|
||||||
|
|
||||||
|
namespace UnityScript2CSharp.Steps
|
||||||
|
{
|
||||||
|
class InstanceToTypeReferencedStaticMemberReference : AbstractTransformerCompilerStep
|
||||||
|
{
|
||||||
|
public override void OnMemberReferenceExpression(MemberReferenceExpression node)
|
||||||
|
{
|
||||||
|
IMember member = node.Entity as IMember;
|
||||||
|
if (member != null && member.IsStatic && node.Target.Entity.EntityType != EntityType.Type)
|
||||||
|
{
|
||||||
|
var declaringType = node.Target.ExpressionType;
|
||||||
|
var needsQualification = node.NeedsQualificationFor(declaringType.ParentNamespace);
|
||||||
|
|
||||||
|
node.Replace(node.Target, new ReferenceExpression(needsQualification ? declaringType.FullName : declaringType.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnMemberReferenceExpression(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -113,6 +113,7 @@
|
||||||
<Compile Include="Steps\ApplyEnumToImplicitConversions.cs" />
|
<Compile Include="Steps\ApplyEnumToImplicitConversions.cs" />
|
||||||
<Compile Include="Steps\ExpandAssignmentToValueTypeMembers.cs" />
|
<Compile Include="Steps\ExpandAssignmentToValueTypeMembers.cs" />
|
||||||
<Compile Include="Steps\InferredMethodReturnTypeFix.cs" />
|
<Compile Include="Steps\InferredMethodReturnTypeFix.cs" />
|
||||||
|
<Compile Include="Steps\InstanceToTypeReferencedStaticMemberReference.cs" />
|
||||||
<Compile Include="Steps\PromoteImplicitBooleanConversionsToExplicitComparisons.cs" />
|
<Compile Include="Steps\PromoteImplicitBooleanConversionsToExplicitComparisons.cs" />
|
||||||
<Compile Include="Steps\InjectTypeOfExpressionsInArgumentsOfSystemType.cs" />
|
<Compile Include="Steps\InjectTypeOfExpressionsInArgumentsOfSystemType.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
|
|
|
@ -135,6 +135,7 @@ namespace UnityScript2CSharp
|
||||||
|
|
||||||
adjustedPipeline.Add(new ReplaceGetSetItemMethodsWithOriginalIndexers());
|
adjustedPipeline.Add(new ReplaceGetSetItemMethodsWithOriginalIndexers());
|
||||||
adjustedPipeline.Add(new PromoteImplicitBooleanConversionsToExplicitComparisons());
|
adjustedPipeline.Add(new PromoteImplicitBooleanConversionsToExplicitComparisons());
|
||||||
|
adjustedPipeline.Add(new InstanceToTypeReferencedStaticMemberReference());
|
||||||
|
|
||||||
_compiler.Parameters.Pipeline = adjustedPipeline;
|
_compiler.Parameters.Pipeline = adjustedPipeline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -606,21 +606,21 @@ namespace UnityScript2CSharp
|
||||||
public override void OnBinaryExpression(BinaryExpression node)
|
public override void OnBinaryExpression(BinaryExpression node)
|
||||||
{
|
{
|
||||||
WrapWith(NeedParensAround(node), "(", ")", delegate()
|
WrapWith(NeedParensAround(node), "(", ")", delegate()
|
||||||
{
|
|
||||||
var isDeclarationStatement = node.Operator == BinaryOperatorType.Assign &&
|
|
||||||
node.Left.NodeType == NodeType.ReferenceExpression && node.IsSynthetic;
|
|
||||||
|
|
||||||
if (isDeclarationStatement)
|
|
||||||
{
|
{
|
||||||
var localDeclaration = (InternalLocal) node.Left.Entity;
|
var isDeclarationStatement = node.Operator == BinaryOperatorType.Assign &&
|
||||||
localDeclaration.OriginalDeclaration.Type.Accept(this);
|
node.Left.NodeType == NodeType.ReferenceExpression && node.IsSynthetic;
|
||||||
_writer.Write(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
node.Left.Accept(this);
|
if (isDeclarationStatement)
|
||||||
_writer.Write($" {CSharpOperatorFor(node.Operator)} ");
|
{
|
||||||
node.Right.Accept(this);
|
var localDeclaration = (InternalLocal)node.Left.Entity;
|
||||||
});
|
localDeclaration.OriginalDeclaration.Type.Accept(this);
|
||||||
|
_writer.Write(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
node.Left.Accept(this);
|
||||||
|
_writer.Write($" {CSharpOperatorFor(node.Operator)} ");
|
||||||
|
node.Right.Accept(this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnConditionalExpression(ConditionalExpression node)
|
public override void OnConditionalExpression(ConditionalExpression node)
|
||||||
|
@ -629,13 +629,13 @@ namespace UnityScript2CSharp
|
||||||
var needsParens = parent != null && (parent.Right != node || parent.Operator != BinaryOperatorType.Assign);
|
var needsParens = parent != null && (parent.Right != node || parent.Operator != BinaryOperatorType.Assign);
|
||||||
|
|
||||||
WrapWith(needsParens , "(", ")", delegate
|
WrapWith(needsParens , "(", ")", delegate
|
||||||
{
|
{
|
||||||
node.Condition.Accept(this);
|
node.Condition.Accept(this);
|
||||||
_writer.Write(" ? ");
|
_writer.Write(" ? ");
|
||||||
VisitWrapping(node.TrueValue, node.TrueValue.NodeType == NodeType.ConditionalExpression, "(", ")");
|
VisitWrapping(node.TrueValue, node.TrueValue.NodeType == NodeType.ConditionalExpression, "(", ")");
|
||||||
_writer.Write(" : ");
|
_writer.Write(" : ");
|
||||||
VisitWrapping(node.FalseValue, node.FalseValue.NodeType == NodeType.ConditionalExpression, "(", ")");
|
VisitWrapping(node.FalseValue, node.FalseValue.NodeType == NodeType.ConditionalExpression, "(", ")");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnReferenceExpression(ReferenceExpression node)
|
public override void OnReferenceExpression(ReferenceExpression node)
|
||||||
|
@ -843,7 +843,6 @@ namespace UnityScript2CSharp
|
||||||
|
|
||||||
public override void OnTryCastExpression(TryCastExpression node)
|
public override void OnTryCastExpression(TryCastExpression node)
|
||||||
{
|
{
|
||||||
var mre = node.ParentNode as MemberReferenceExpression;
|
|
||||||
var isTargetOfMemberReferenceExpression = NeedParensAround(node);
|
var isTargetOfMemberReferenceExpression = NeedParensAround(node);
|
||||||
|
|
||||||
VisitWrapping(node.Target, isTargetOfMemberReferenceExpression, "(");
|
VisitWrapping(node.Target, isTargetOfMemberReferenceExpression, "(");
|
||||||
|
@ -853,19 +852,13 @@ namespace UnityScript2CSharp
|
||||||
|
|
||||||
public override void OnCastExpression(CastExpression node)
|
public override void OnCastExpression(CastExpression node)
|
||||||
{
|
{
|
||||||
var mre = node.ParentNode as TryCastExpression;
|
WrapWith(NeedParensAround(node), "(", ")", delegate
|
||||||
var isTargetOfExpression = mre != null && mre.Target == node;
|
{
|
||||||
|
_writer.Write("(");
|
||||||
if (isTargetOfExpression)
|
node.Type.Accept(this);
|
||||||
_writer.Write("(");
|
_writer.Write(") ");
|
||||||
|
node.Target.Accept(this);
|
||||||
_writer.Write("(");
|
});
|
||||||
node.Type.Accept(this);
|
|
||||||
_writer.Write(") ");
|
|
||||||
node.Target.Accept(this);
|
|
||||||
|
|
||||||
if (isTargetOfExpression)
|
|
||||||
_writer.Write(")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnTypeofExpression(TypeofExpression node)
|
public override void OnTypeofExpression(TypeofExpression node)
|
||||||
|
@ -1085,25 +1078,28 @@ namespace UnityScript2CSharp
|
||||||
|
|
||||||
switch (nodeParent.NodeType)
|
switch (nodeParent.NodeType)
|
||||||
{
|
{
|
||||||
case NodeType.ExpressionStatement:
|
|
||||||
case NodeType.MacroStatement:
|
|
||||||
case NodeType.IfStatement:
|
case NodeType.IfStatement:
|
||||||
case NodeType.WhileStatement:
|
case NodeType.WhileStatement:
|
||||||
case NodeType.UnlessStatement:
|
case NodeType.UnlessStatement:
|
||||||
|
return ((ConditionalStatement)nodeParent).Condition != e;
|
||||||
|
|
||||||
|
case NodeType.ExpressionStatement:
|
||||||
|
case NodeType.MacroStatement:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case NodeType.MethodInvocationExpression:
|
case NodeType.MethodInvocationExpression:
|
||||||
return ((MethodInvocationExpression) nodeParent).Arguments.Any(a => a == e);
|
return !((MethodInvocationExpression)nodeParent).Arguments.Any(a => a == e);
|
||||||
|
|
||||||
case NodeType.BinaryExpression:
|
case NodeType.BinaryExpression:
|
||||||
return ((BinaryExpression) nodeParent).Right != e;
|
return ((BinaryExpression)nodeParent).Right != e;
|
||||||
|
|
||||||
case NodeType.ReturnStatement:
|
case NodeType.ReturnStatement:
|
||||||
return ((ReturnStatement) nodeParent).Expression != e;
|
return ((ReturnStatement)nodeParent).Expression != e;
|
||||||
|
|
||||||
case NodeType.ConditionalExpression:
|
case NodeType.ConditionalExpression:
|
||||||
return nodeParent.ParentNode.NodeType == NodeType.BinaryExpression && ((BinaryExpression)nodeParent.ParentNode).Operator != BinaryOperatorType.Assign;
|
return nodeParent.ParentNode.NodeType == NodeType.BinaryExpression && ((BinaryExpression)nodeParent.ParentNode).Operator != BinaryOperatorType.Assign;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче