Skip to content

Commit c00b956

Browse files
committed
Added method "InstanceOf" translates as "instanceof" operator.
Also, translates "is" to "instanceof".
1 parent de3d393 commit c00b956

File tree

3 files changed

+226
-45
lines changed

3 files changed

+226
-45
lines changed

CSharpToJavaScript/APIs/JS/GlobalObject.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,29 @@ namespace CSharpToJavaScript.APIs.JS.Ecma;
44

55
public partial class GlobalObject
66
{
7-
[To(ToAttribute.Default)]
7+
[Binary("===")]
88
public static bool EqualsStrict(dynamic left, dynamic right)
99
{
1010
return left == right;
1111
}
12-
[To(ToAttribute.Default)]
12+
[Binary("!==")]
1313
public static bool InequalsStrict(dynamic left, dynamic right)
1414
{
1515
return left != right;
1616
}
17-
[To(ToAttribute.Default)]
17+
[Unary("delete ")]
1818
public static bool Delete(dynamic arg)
1919
{
2020
return true;
2121
}
22-
[To(ToAttribute.Default)]
22+
[Unary("void ")]
2323
public static Undefined Void(dynamic arg)
2424
{
2525
return new Undefined();
2626
}
27-
}
27+
[Binary("instanceof")]
28+
public static bool InstanceOf(dynamic left, dynamic right)
29+
{
30+
return true;
31+
}
32+
}

CSharpToJavaScript/Utils/Attributes.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,21 @@ public string Convert(string str)
5858
}
5959
}
6060

61+
[AttributeUsage(AttributeTargets.All)]
62+
public class BinaryAttribute : Attribute
63+
{
64+
public string Value { get; init; }
65+
public BinaryAttribute(string value)
66+
{
67+
Value = value;
68+
}
69+
}
70+
[AttributeUsage(AttributeTargets.All)]
71+
public class UnaryAttribute : Attribute
72+
{
73+
public string Value { get; init; }
74+
public UnaryAttribute(string value)
75+
{
76+
Value = value;
77+
}
78+
}

CSharpToJavaScript/Walker.cs

Lines changed: 198 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using CSharpToJavaScript.Utils;
1+
using CSharpToJavaScript.APIs.JS.Ecma;
2+
using CSharpToJavaScript.Utils;
23
using Microsoft.CodeAnalysis;
34
using Microsoft.CodeAnalysis.CSharp;
45
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -3678,10 +3679,145 @@ public override void VisitBadDirectiveTrivia(BadDirectiveTriviaSyntax node)
36783679
}
36793680
public override void VisitBinaryExpression(BinaryExpressionSyntax node)
36803681
{
3681-
#if DEBUG
3682-
Log.WarningLine($"Not implemented or unlikely to be implemented. Calling base! (FullSpan: {node.FullSpan}|Location{node.GetLocation().GetLineSpan()})\n|{node.ToFullString()}|");
3683-
#endif
3684-
base.VisitBinaryExpression(node);
3682+
ChildSyntaxList nodesAndTokens = node.ChildNodesAndTokens();
3683+
3684+
for (int i = 0; i < nodesAndTokens.Count; i++)
3685+
{
3686+
SyntaxNode? asNode = nodesAndTokens[i].AsNode();
3687+
3688+
if (asNode != null)
3689+
{
3690+
SyntaxKind kind = asNode.Kind();
3691+
3692+
switch (kind)
3693+
{
3694+
case SyntaxKind.ThisExpression:
3695+
VisitThisExpression((ThisExpressionSyntax)asNode);
3696+
break;
3697+
case SyntaxKind.AnonymousObjectCreationExpression:
3698+
VisitAnonymousObjectCreationExpression((AnonymousObjectCreationExpressionSyntax)asNode);
3699+
break;
3700+
case SyntaxKind.TypeOfExpression:
3701+
VisitTypeOfExpression((TypeOfExpressionSyntax)asNode);
3702+
break;
3703+
case SyntaxKind.ObjectCreationExpression:
3704+
VisitObjectCreationExpression((ObjectCreationExpressionSyntax)asNode);
3705+
break;
3706+
case SyntaxKind.CastExpression:
3707+
VisitCastExpression((CastExpressionSyntax)asNode);
3708+
break;
3709+
case SyntaxKind.AwaitExpression:
3710+
VisitAwaitExpression((AwaitExpressionSyntax)asNode);
3711+
break;
3712+
case SyntaxKind.InvocationExpression:
3713+
VisitInvocationExpression((InvocationExpressionSyntax)asNode);
3714+
break;
3715+
case SyntaxKind.ElementAccessExpression:
3716+
VisitElementAccessExpression((ElementAccessExpressionSyntax)asNode);
3717+
break;
3718+
case SyntaxKind.UnaryPlusExpression:
3719+
case SyntaxKind.UnaryMinusExpression:
3720+
case SyntaxKind.BitwiseNotExpression:
3721+
case SyntaxKind.LogicalNotExpression:
3722+
case SyntaxKind.PreIncrementExpression:
3723+
case SyntaxKind.PreDecrementExpression:
3724+
case SyntaxKind.AddressOfExpression:
3725+
case SyntaxKind.PointerIndirectionExpression:
3726+
case SyntaxKind.IndexExpression:
3727+
VisitPrefixUnaryExpression((PrefixUnaryExpressionSyntax)asNode);
3728+
break;
3729+
case SyntaxKind.SimpleMemberAccessExpression:
3730+
case SyntaxKind.PointerMemberAccessExpression:
3731+
VisitMemberAccessExpression((MemberAccessExpressionSyntax)asNode);
3732+
break;
3733+
case SyntaxKind.ParenthesizedExpression:
3734+
VisitParenthesizedExpression((ParenthesizedExpressionSyntax)asNode);
3735+
break;
3736+
case SyntaxKind.ArgListExpression:
3737+
case SyntaxKind.NumericLiteralExpression:
3738+
case SyntaxKind.StringLiteralExpression:
3739+
case SyntaxKind.Utf8StringLiteralExpression:
3740+
case SyntaxKind.CharacterLiteralExpression:
3741+
case SyntaxKind.TrueLiteralExpression:
3742+
case SyntaxKind.FalseLiteralExpression:
3743+
case SyntaxKind.NullLiteralExpression:
3744+
case SyntaxKind.DefaultLiteralExpression:
3745+
VisitLiteralExpression((LiteralExpressionSyntax)asNode);
3746+
break;
3747+
case SyntaxKind.AddExpression:
3748+
case SyntaxKind.SubtractExpression:
3749+
case SyntaxKind.MultiplyExpression:
3750+
case SyntaxKind.DivideExpression:
3751+
case SyntaxKind.ModuloExpression:
3752+
case SyntaxKind.LeftShiftExpression:
3753+
case SyntaxKind.RightShiftExpression:
3754+
case SyntaxKind.UnsignedRightShiftExpression:
3755+
case SyntaxKind.LogicalOrExpression:
3756+
case SyntaxKind.LogicalAndExpression:
3757+
case SyntaxKind.BitwiseOrExpression:
3758+
case SyntaxKind.BitwiseAndExpression:
3759+
case SyntaxKind.ExclusiveOrExpression:
3760+
case SyntaxKind.EqualsExpression:
3761+
case SyntaxKind.NotEqualsExpression:
3762+
case SyntaxKind.LessThanExpression:
3763+
case SyntaxKind.LessThanOrEqualExpression:
3764+
case SyntaxKind.GreaterThanExpression:
3765+
case SyntaxKind.GreaterThanOrEqualExpression:
3766+
case SyntaxKind.IsExpression:
3767+
case SyntaxKind.AsExpression:
3768+
case SyntaxKind.CoalesceExpression:
3769+
VisitBinaryExpression((BinaryExpressionSyntax)asNode);
3770+
break;
3771+
case SyntaxKind.IdentifierName:
3772+
VisitIdentifierName((IdentifierNameSyntax)asNode);
3773+
break;
3774+
default:
3775+
Log.ErrorLine($"asNode : {kind}\n|{asNode.ToFullString()}|");
3776+
break;
3777+
}
3778+
}
3779+
else
3780+
{
3781+
SyntaxToken asToken = nodesAndTokens[i].AsToken();
3782+
SyntaxKind kind = asToken.Kind();
3783+
3784+
switch (kind)
3785+
{
3786+
case SyntaxKind.IsKeyword:
3787+
{
3788+
VisitLeadingTrivia(asToken);
3789+
JSSB.Append("instanceof");
3790+
VisitTrailingTrivia(asToken);
3791+
break;
3792+
}
3793+
case SyntaxKind.MinusToken:
3794+
case SyntaxKind.SlashToken:
3795+
case SyntaxKind.PercentToken:
3796+
case SyntaxKind.AmpersandAmpersandToken:
3797+
case SyntaxKind.GreaterThanGreaterThanToken:
3798+
case SyntaxKind.BarToken:
3799+
case SyntaxKind.BarBarToken:
3800+
case SyntaxKind.LessThanEqualsToken:
3801+
case SyntaxKind.QuestionQuestionToken:
3802+
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
3803+
case SyntaxKind.AsteriskToken:
3804+
case SyntaxKind.PlusToken:
3805+
case SyntaxKind.LessThanLessThanToken:
3806+
case SyntaxKind.GreaterThanToken:
3807+
case SyntaxKind.GreaterThanEqualsToken:
3808+
case SyntaxKind.AmpersandToken:
3809+
case SyntaxKind.CaretToken:
3810+
case SyntaxKind.EqualsEqualsToken:
3811+
case SyntaxKind.ExclamationEqualsToken:
3812+
case SyntaxKind.LessThanToken:
3813+
VisitToken(asToken);
3814+
break;
3815+
default:
3816+
Log.ErrorLine($"asToken : {kind}");
3817+
break;
3818+
}
3819+
}
3820+
}
36853821
}
36863822
public override void VisitBinaryPattern(BinaryPatternSyntax node)
36873823
{
@@ -4234,6 +4370,9 @@ public override void VisitForEachVariableStatement(ForEachVariableStatementSynta
42344370

42354371
switch (kind)
42364372
{
4373+
case SyntaxKind.ThisExpression:
4374+
VisitThisExpression((ThisExpressionSyntax)asNode);
4375+
break;
42374376
case SyntaxKind.ExpressionStatement:
42384377
VisitExpressionStatement((ExpressionStatementSyntax)asNode);
42394378
break;
@@ -4715,10 +4854,7 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)
47154854
JSSB.AppendLine("*/");
47164855
}
47174856

4718-
bool isEqualsStrict = false;
4719-
bool isInequalsStrict = false;
4720-
bool isDelete = false;
4721-
bool isVoid = false;
4857+
AttributeData[]? attributeDatas = null;
47224858

47234859
ChildSyntaxList nodesAndTokens = node.ChildNodesAndTokens();
47244860

@@ -4735,47 +4871,69 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)
47354871
case SyntaxKind.IdentifierName:
47364872
{
47374873
IdentifierNameSyntax _identifier = (IdentifierNameSyntax)asNode;
4738-
if (_identifier.Identifier.Text == "EqualsStrict")
4739-
isEqualsStrict = true;
4740-
else if (_identifier.Identifier.Text == "InequalsStrict")
4741-
isInequalsStrict = true;
4742-
else if (_identifier.Identifier.Text == "Delete")
4743-
isDelete = true;
4744-
else if (_identifier.Identifier.Text == "Void")
4745-
isVoid = true;
4874+
SymbolInfo _symbolInfo = _Model.GetSymbolInfo(_identifier);
4875+
ISymbol? _symbol = null;
4876+
4877+
if (_symbolInfo.CandidateSymbols.Length >= 1)
4878+
_symbol = _symbolInfo.CandidateSymbols[0];
47464879
else
4747-
VisitIdentifierName(_identifier);
4880+
_symbol = _symbolInfo.Symbol;
4881+
4882+
if (_symbol != null &&
4883+
_symbol.ContainingNamespace.ToString().Contains(nameof(APIs.JS.Ecma)) &&
4884+
_symbol.ContainingType.ToString().Contains(nameof(GlobalObject)))
4885+
{
4886+
attributeDatas = _symbol.GetAttributes().ToArray();
4887+
4888+
if (attributeDatas[0].AttributeClass != null)
4889+
{
4890+
if (attributeDatas[0].AttributeClass.Name == nameof(BinaryAttribute) ||
4891+
attributeDatas[0].AttributeClass.Name == nameof(UnaryAttribute))
4892+
{
4893+
break;
4894+
}
4895+
}
4896+
}
4897+
4898+
VisitIdentifierName(_identifier);
47484899
break;
47494900
}
47504901
case SyntaxKind.ArgumentList:
47514902
{
47524903
ArgumentListSyntax _arguments = (ArgumentListSyntax)asNode;
4753-
if (isEqualsStrict)
4904+
if (attributeDatas != null)
47544905
{
4755-
VisitArgument(_arguments.Arguments[0]);
4756-
JSSB.Append("===");
4757-
VisitArgument(_arguments.Arguments[1]);
4758-
}
4759-
else if (isInequalsStrict)
4760-
{
4761-
VisitArgument(_arguments.Arguments[0]);
4762-
JSSB.Append("!==");
4763-
VisitArgument(_arguments.Arguments[1]);
4764-
}
4765-
else if (isDelete)
4766-
{
4767-
JSSB.Append("delete ");
4768-
VisitArgument(_arguments.Arguments[0]);
4769-
}
4770-
else if (isVoid)
4771-
{
4772-
JSSB.Append("void ");
4773-
VisitArgument(_arguments.Arguments[0]);
4906+
for (int j = 0; j < attributeDatas.Length; j++)
4907+
{
4908+
if (attributeDatas[j].AttributeClass != null)
4909+
{
4910+
if (attributeDatas[j].AttributeClass.Name == nameof(BinaryAttribute))
4911+
{
4912+
VisitArgument(_arguments.Arguments[0]);
4913+
JSSB.Append(attributeDatas[j].ConstructorArguments[0].Value);
4914+
VisitTrailingTrivia(_arguments.Arguments.GetSeparator(0));
4915+
VisitArgument(_arguments.Arguments[1]);
4916+
goto Break;
4917+
}
4918+
4919+
if (attributeDatas[j].AttributeClass.Name == nameof(UnaryAttribute))
4920+
{
4921+
JSSB.Append(attributeDatas[j].ConstructorArguments[0].Value);
4922+
VisitArgument(_arguments.Arguments[0]);
4923+
goto Break;
4924+
}
4925+
}
4926+
}
47744927
}
4775-
else
4776-
VisitArgumentList(_arguments);
4928+
4929+
VisitArgumentList(_arguments);
4930+
//TODO?
4931+
Break:
47774932
break;
47784933
}
4934+
case SyntaxKind.ElementAccessExpression:
4935+
VisitElementAccessExpression((ElementAccessExpressionSyntax)asNode);
4936+
break;
47794937
case SyntaxKind.SimpleMemberAccessExpression:
47804938
case SyntaxKind.PointerMemberAccessExpression:
47814939
VisitMemberAccessExpression((MemberAccessExpressionSyntax)asNode);

0 commit comments

Comments
 (0)