Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CSharpToJavaScript.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<GenerateDocumentationFile>False</GenerateDocumentationFile>
<Authors>TiLied</Authors>
<Description>A library for translating/converting cs into js, using Roslyn.</Description>
<PackageProjectUrl>https://tilied.github.io/CSTOJS_Pages/</PackageProjectUrl>
Expand Down
12 changes: 6 additions & 6 deletions CSharpToJavaScript/APIs/JS/GlobalObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static bool InequalsStrict(dynamic left, dynamic right)
/// </remarks>
/// <param name="arg">object.property</param>
/// <returns>true for all cases except when the property is an own non-configurable property, in which case false is returned in non-strict mode.</returns>
[Unary("delete ")]
[Unary("delete")]
public static bool Delete(dynamic arg)
{
return true;
Expand All @@ -57,7 +57,7 @@ public static bool Delete(dynamic arg)
/// </remarks>
/// <param name="arg">expression</param>
/// <returns>Undefined</returns>
[Unary("void ")]
[Unary("void")]
public static Undefined Void(dynamic arg)
{
return new Undefined();
Expand All @@ -71,7 +71,7 @@ public static Undefined Void(dynamic arg)
/// </remarks>
/// <param name="operand">An expression representing the object or primitive whose type is to be returned.</param>
/// <returns>string</returns>
[Unary("typeof ")]
[Unary("typeof")]
public static string TypeOf(object operand)
{
return string.Empty;
Expand All @@ -84,7 +84,7 @@ public static string TypeOf(object operand)
/// </remarks>
/// <param name="operand">An expression representing the object or primitive whose type is to be returned.</param>
/// <returns>string</returns>
[Unary("typeof ")]
[Unary("typeof")]
public static string TypeOf(Func<dynamic> operand)
{
return string.Empty;
Expand All @@ -97,7 +97,7 @@ public static string TypeOf(Func<dynamic> operand)
/// </remarks>
/// <typeparam name="O">An expression representing the object or primitive whose type is to be returned.</typeparam>
/// <returns>string</returns>
[GenericUnary("typeof ")]
[GenericUnary("typeof")]
public static string TypeOf<O>()
{
return string.Empty;
Expand All @@ -112,7 +112,7 @@ public static string TypeOf<O>()
/// <typeparam name="C">Constructor to test against.</typeparam>
/// <param name="obj">The object to test.</param>
/// <returns>bool</returns>
[GenericBinary(" instanceof ")]
[GenericBinary("instanceof")]
public static bool InstanceOf<C>(dynamic obj)
{
return true;
Expand Down
121 changes: 67 additions & 54 deletions CSharpToJavaScript/CSTOJS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.CodeAnalysis;
using System.Linq;
using CSharpToJavaScript.Utils;
using System.Collections.Immutable;

namespace CSharpToJavaScript;

Expand Down Expand Up @@ -49,80 +50,81 @@ public static FileData[] Translate(FileData[] files, MetadataReference[]? refere

trees[0] = AddGlobalUsings(trees[0]);

CSharpCompilation compilation = CSharpCompilation
.Create("HelloWorld")
.AddReferences(references)
.AddSyntaxTrees(trees);

for (int i = 0; i < files.Length; i++)
{
if (files[i].OptionsForFile.TranslateFile == false)
continue;

if (files[i].OptionsForFile.NormalizeWhitespace)
trees[i] = trees[i].GetRoot().NormalizeWhitespace().SyntaxTree;
SemanticModel _model = compilation.GetSemanticModel(trees[i]);

if (files[i].OptionsForFile.KeepBraceOnTheSameLine)
ImmutableArray<Diagnostic> diagnostics = _model.GetDiagnostics();
for (int j = 0; j < diagnostics.Length; j++)
{
//Mostly deleted whitespaces, still TODO?
SyntaxToken[] allBraces = trees[i].GetRoot().DescendantTokens().Where((e) => e.IsKind(SyntaxKind.OpenBraceToken)).ToArray();

List<SyntaxTrivia> allTriviaToDelete = new();
if (files[i].OptionsForFile.Debug)
Log.WarningLine(diagnostics[j].ToString());

for (int j = 0; j < allBraces.Length; j++)
//Print an error if compilation fails.
if (diagnostics[j].Severity == DiagnosticSeverity.Error)
{
if (allBraces[j].HasLeadingTrivia)
{
SyntaxTriviaList _lt = allBraces[j].LeadingTrivia;
for (int y = 0; y < _lt.Count; y++)
{
allTriviaToDelete.Add(_lt[y]);
}
}
if (files[i].OptionsForFile.DisableCompilationErrors == false)
Log.ErrorLine(diagnostics[i].ToString());
}
//Is this the right way to delete trivia?
trees[i] = trees[i].GetRoot().ReplaceTrivia(allTriviaToDelete, (o, r) => SyntaxFactory.ElasticMarker).SyntaxTree;
}

allBraces = trees[i].GetRoot().DescendantTokens().Where((e) => e.IsKind(SyntaxKind.OpenBraceToken)).ToArray();
SyntaxNode _root = trees[i].GetRoot();

List<SyntaxTrivia> allTriviaToReplace = new();
WithSemanticRewriter _withSemanticRewriter = new(_model, files[i].OptionsForFile);
WithoutSemanticRewriter _withoutSemanticRewriter = new(files[i].OptionsForFile);

StringBuilderWalker _stringBuilderWalker = new();

for (int j = 0; j < allBraces.Length; j++)
{
SyntaxToken _token = allBraces[j].GetPreviousToken();
if (_token.HasTrailingTrivia)
{
SyntaxTrivia _trivia = _token.TrailingTrivia.Where((e) => e.IsKind(SyntaxKind.EndOfLineTrivia)).FirstOrDefault();
if (!_trivia.IsKind(SyntaxKind.None))
{
allTriviaToReplace.Add(_trivia);
}
}
}
trees[i] = trees[i].GetRoot().ReplaceTrivia(allTriviaToReplace, (o, r) => SyntaxFactory.Space).SyntaxTree;
}
}
SyntaxNode newRoot1 = _withSemanticRewriter.Visit(_root);
if (_root != newRoot1)
_root = newRoot1;

CSharpCompilation compilation = CSharpCompilation
.Create("HelloWorld")
.AddReferences(references)
.AddSyntaxTrees(trees);
_root = _root.ReplaceNodes(_withSemanticRewriter.ReplaceNodes.Keys, (o, r) =>
{
return _withSemanticRewriter.ReplaceNodes[o];
});

for (int i = 0; i < files.Length; i++)
{
if (files[i].OptionsForFile.TranslateFile == false)
continue;
if (files[i].OptionsForFile.Debug)
files[i].Debug_WithSemanticRewriter = _root.ToFullString();

Walker _walker = new(files[i].OptionsForFile, compilation.GetSemanticModel(trees[i]));
SyntaxNode newRoot2 = _withoutSemanticRewriter.Visit(_root);
if (_root != newRoot2)
_root = newRoot2;

_walker.JSSB.Append(files[i].OptionsForFile.AddSBAtTheTop);
if (files[i].OptionsForFile.Debug)
files[i].Debug_WithoutSemanticRewriter = _root.ToFullString();

if (files[i].OptionsForFile.NormalizeWhitespace)
_root = _root.NormalizeWhitespace();

_walker.Visit(trees[i].GetRoot());
if (files[i].OptionsForFile.KeepBraceOnTheSameLine)
{
KeepBraceOnTheSameLineRewriter _keepBraceOnTheSameLineRewriter = new();

SyntaxNode newRoot3 = _keepBraceOnTheSameLineRewriter.Visit(_root);
if (_root != newRoot3)
_root = newRoot3;
}

_walker.JSSB.Append(files[i].OptionsForFile.AddSBAtTheBottom);
_stringBuilderWalker.JSSB.Append(files[i].OptionsForFile.AddSBAtTheTop);
_stringBuilderWalker.Visit(_root);
_stringBuilderWalker.JSSB.Append(files[i].OptionsForFile.AddSBAtTheBottom);

files[i].TranslatedStr = _walker.JSSB.ToString();
files[i].TranslatedStr = _stringBuilderWalker.JSSB.ToString();
}

return files;
}

private static MetadataReference[] GetReferences(CSTOJSOptions options)
public static MetadataReference[] GetReferences(CSTOJSOptions options)
{
HashSet<MetadataReference> assemblyMetadata = new();

Expand Down Expand Up @@ -200,7 +202,7 @@ private static MetadataReference[] GetReferences(CSTOJSOptions options)
}
Log.InfoLine($"---");
}

MetadataReference[] references = new MetadataReference[assemblyMetadata.Count];
int i = 0;
foreach (MetadataReference metadata in assemblyMetadata)
Expand All @@ -218,11 +220,11 @@ private static MetadataReference[] GetReferences(CSTOJSOptions options)
}
Log.InfoLine($"+++");
}

return references;
}

private static SyntaxTree AddGlobalUsings(SyntaxTree tree)
public static SyntaxTree AddGlobalUsings(SyntaxTree tree)
{
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
UsingDirectiveSyntax[] oldUsing = root.Usings.ToArray();
Expand Down Expand Up @@ -397,9 +399,20 @@ public class FileData
/// CS input string.
/// </summary>
public string SourceStr { get; set; } = string.Empty;

/// <summary>
/// JS translated string.
/// </summary>
public string TranslatedStr { get; set; } = string.Empty;
}


/// <summary>
/// Debug string.
/// </summary>
public string Debug_WithSemanticRewriter { get; set; } = string.Empty;

/// <summary>
/// Debug string.
/// </summary>
public string Debug_WithoutSemanticRewriter { get; set; } = string.Empty;
}
Loading