[scripting] support for preserving as many comments as possible

This commit is contained in:
Adriano Carlos Verona 2017-08-18 15:53:34 -03:00
Родитель d6efba9c15
Коммит d435c7666e
9 изменённых файлов: 836 добавлений и 89 удалений

Просмотреть файл

@ -722,10 +722,13 @@ namespace UnityScript2CSharp.Tests
comment = "/* C1 */"; comment = "/* C1 */";
yield return new TestCaseData($"function F() {{ return 42; {comment}\r\n}}", $"public virtual int F() {{ return 42 {comment}; }}").SetName("Right MultiLine"); yield return new TestCaseData($"function F() {{ return 42; {comment}\r\n}}", $"public virtual int F() {{ return 42 {comment}; }}").SetName("Right MultiLine");
yield return new TestCaseData($"{comment}\nfunction F() {{ }}", $"{comment}\npublic virtual void F() {{ }}").SetName("Above MultiLine"); yield return new TestCaseData($"{comment}\r\nfunction F() {{ }}", $"{comment}\r\npublic virtual void F() {{ }}").SetName("Above MultiLine");
yield return new TestCaseData($"function F() {{ var x = 42;\r\n{comment}\r\nreturn x; }}", $"public virtual int F() {{ int x = 42;\r\n{comment}\r\nreturn x; }}").SetName("Below MultiLine"); yield return new TestCaseData($"function F() {{ var x = 42;\r\n{comment}\r\nreturn x; }}", $"public virtual int F() {{ int x = 42;\r\n{comment}\r\nreturn x; }}").SetName("Below MultiLine");
yield return new TestCaseData($"function F() : int {{ {comment} return 42; }}", $"public virtual int F() {{ {comment} return 42; }}").SetName("Left MultiLine"); yield return new TestCaseData($"function F() : int {{ {comment} return 42; }}", $"public virtual int F() {{ {comment} return 42; }}").SetName("Left MultiLine");
yield return new TestCaseData("function F() : int { return 42 /*1*/; /*2*/ }", "public virtual int F() { return 42 /*1*/ /*2*/; }").SetName("Multiple multiLine comments"); yield return new TestCaseData("function F() : int { return 42 /*1*/; /*2*/ }", "public virtual int F() { return 42 /*1*/ /*2*/; }").SetName("Multiple multiLine comments");
yield return new TestCaseData("function F(/*B*/ i:int /*A*/ ) { }", "public virtual void F(/*B*/int /*A*/ i) { }").SetName("In Parameters");
yield return new TestCaseData("// 1\r\nprivate var i:int;\r\nfunction F() { }", "// 1\r\nprivate int i;\r\npublic virtual void F() { }").SetName("Above Fields");
} }
private static IEnumerable CSharpNonClashingKeywords() private static IEnumerable CSharpNonClashingKeywords()

Просмотреть файл

@ -30,6 +30,10 @@ namespace UnityScript2CSharp
[Option('i', HelpText = "Ignore compilation errors. This allows the conversion process to continue instead of aborting.")] public bool IgnoreErrors { get; set; } [Option('i', HelpText = "Ignore compilation errors. This allows the conversion process to continue instead of aborting.")] public bool IgnoreErrors { get; set; }
[Option(HelpText = "Do not try to preserve comments (Use this option if processing comments cause any issues).", DefaultValue = false)] public bool SkipComments { get; set; }
[Option(HelpText = "Show a list of comments that were not written to the converted sources (used to help identifying issues with the comment processing code).")] public bool ShowOrphanComments { get; set; }
[Option('n', "dry-run", HelpText = "Run the conversion but do not change/create any files on disk.")] public bool DryRun { get; set; } [Option('n', "dry-run", HelpText = "Run the conversion but do not change/create any files on disk.")] public bool DryRun { get; set; }
[Option('v', "verbose", HelpText = "Show verbose messages.")] public bool Verbose { get; set; } [Option('v', "verbose", HelpText = "Show verbose messages.")] public bool Verbose { get; set; }

Просмотреть файл

@ -0,0 +1,556 @@
using System;
using System.Collections.Generic;
using Boo.Lang.Compiler.Ast;
using Attribute = Boo.Lang.Compiler.Ast.Attribute;
namespace UnityScript2CSharp
{
internal class OrphanCommentVisitor : DepthFirstVisitor
{
private void Check(Node node)
{
if (node.ContainsAnnotation("COMMENTS"))
{
var comments = (IList<Comment>) node["COMMENTS"];
foreach (var comment in comments)
{
Console.WriteLine($"[ORPHAN COMMENT | {node.NodeType}, {comment.AnchorKind}] {node.LexicalInfo} : {comment.Token.getText()}\r\n\t{node}");
}
}
}
public override void OnCompileUnit(CompileUnit node)
{
base.OnCompileUnit(node);
Check(node);
}
public override void OnTypeMemberStatement(TypeMemberStatement node)
{
base.OnTypeMemberStatement(node);
Check(node);
}
public override void OnExplicitMemberInfo(ExplicitMemberInfo node)
{
base.OnExplicitMemberInfo(node);
Check(node);
}
public override void OnSimpleTypeReference(SimpleTypeReference node)
{
base.OnSimpleTypeReference(node);
Check(node);
}
public override void OnArrayTypeReference(ArrayTypeReference node)
{
base.OnArrayTypeReference(node);
Check(node);
}
public override void OnCallableTypeReference(CallableTypeReference node)
{
base.OnCallableTypeReference(node);
Check(node);
}
public override void OnGenericTypeReference(GenericTypeReference node)
{
base.OnGenericTypeReference(node);
Check(node);
}
public override void OnGenericTypeDefinitionReference(GenericTypeDefinitionReference node)
{
base.OnGenericTypeDefinitionReference(node);
Check(node);
}
public override void OnCallableDefinition(CallableDefinition node)
{
base.OnCallableDefinition(node);
Check(node);
}
public override void OnNamespaceDeclaration(NamespaceDeclaration node)
{
base.OnNamespaceDeclaration(node);
Check(node);
}
public override void OnImport(Import node)
{
base.OnImport(node);
Check(node);
}
public override void OnModule(Module node)
{
base.OnModule(node);
Check(node);
}
public override void OnClassDefinition(ClassDefinition node)
{
base.OnClassDefinition(node);
Check(node);
}
public override void OnStructDefinition(StructDefinition node)
{
base.OnStructDefinition(node);
Check(node);
}
public override void OnInterfaceDefinition(InterfaceDefinition node)
{
base.OnInterfaceDefinition(node);
Check(node);
}
public override void OnEnumDefinition(EnumDefinition node)
{
base.OnEnumDefinition(node);
Check(node);
}
public override void OnEnumMember(EnumMember node)
{
base.OnEnumMember(node);
Check(node);
}
public override void OnField(Field node)
{
base.OnField(node);
Check(node);
}
public override void OnProperty(Property node)
{
base.OnProperty(node);
Check(node);
}
public override void OnEvent(Event node)
{
base.OnEvent(node);
Check(node);
}
public override void OnLocal(Local node)
{
base.OnLocal(node);
Check(node);
}
public override void OnBlockExpression(BlockExpression node)
{
base.OnBlockExpression(node);
Check(node);
}
public override void OnMethod(Method node)
{
base.OnMethod(node);
Check(node);
}
public override void OnConstructor(Constructor node)
{
base.OnConstructor(node);
Check(node);
}
public override void OnDestructor(Destructor node)
{
base.OnDestructor(node);
Check(node);
}
public override void OnParameterDeclaration(ParameterDeclaration node)
{
base.OnParameterDeclaration(node);
Check(node);
}
public override void OnGenericParameterDeclaration(GenericParameterDeclaration node)
{
base.OnGenericParameterDeclaration(node);
Check(node);
}
public override void OnDeclaration(Declaration node)
{
base.OnDeclaration(node);
Check(node);
}
public override void OnAttribute(Attribute node)
{
base.OnAttribute(node);
Check(node);
}
public override void OnStatementModifier(StatementModifier node)
{
base.OnStatementModifier(node);
Check(node);
}
public override void OnGotoStatement(GotoStatement node)
{
base.OnGotoStatement(node);
Check(node);
}
public override void OnLabelStatement(LabelStatement node)
{
base.OnLabelStatement(node);
Check(node);
}
public override void OnBlock(Block node)
{
base.OnBlock(node);
Check(node);
}
public override void OnDeclarationStatement(DeclarationStatement node)
{
base.OnDeclarationStatement(node);
Check(node);
}
public override void OnMacroStatement(MacroStatement node)
{
base.OnMacroStatement(node);
Check(node);
}
public override void OnTryStatement(TryStatement node)
{
base.OnTryStatement(node);
Check(node);
}
public override void OnExceptionHandler(ExceptionHandler node)
{
base.OnExceptionHandler(node);
Check(node);
}
public override void OnIfStatement(IfStatement node)
{
base.OnIfStatement(node);
Check(node);
}
public override void OnUnlessStatement(UnlessStatement node)
{
base.OnUnlessStatement(node);
Check(node);
}
public override void OnForStatement(ForStatement node)
{
base.OnForStatement(node);
Check(node);
}
public override void OnWhileStatement(WhileStatement node)
{
base.OnWhileStatement(node);
Check(node);
}
public override void OnBreakStatement(BreakStatement node)
{
base.OnBreakStatement(node);
Check(node);
}
public override void OnContinueStatement(ContinueStatement node)
{
base.OnContinueStatement(node);
Check(node);
}
public override void OnReturnStatement(ReturnStatement node)
{
base.OnReturnStatement(node);
Check(node);
}
public override void OnYieldStatement(YieldStatement node)
{
base.OnYieldStatement(node);
Check(node);
}
public override void OnRaiseStatement(RaiseStatement node)
{
base.OnRaiseStatement(node);
Check(node);
}
public override void OnUnpackStatement(UnpackStatement node)
{
base.OnUnpackStatement(node);
Check(node);
}
public override void OnExpressionStatement(ExpressionStatement node)
{
base.OnExpressionStatement(node);
Check(node);
}
public override void OnOmittedExpression(OmittedExpression node)
{
base.OnOmittedExpression(node);
Check(node);
}
public override void OnExpressionPair(ExpressionPair node)
{
base.OnExpressionPair(node);
Check(node);
}
public override void OnMethodInvocationExpression(MethodInvocationExpression node)
{
base.OnMethodInvocationExpression(node);
Check(node);
}
public override void OnUnaryExpression(UnaryExpression node)
{
base.OnUnaryExpression(node);
Check(node);
}
public override void OnBinaryExpression(BinaryExpression node)
{
base.OnBinaryExpression(node);
Check(node);
}
public override void OnConditionalExpression(ConditionalExpression node)
{
base.OnConditionalExpression(node);
Check(node);
}
public override void OnReferenceExpression(ReferenceExpression node)
{
base.OnReferenceExpression(node);
Check(node);
}
public override void OnMemberReferenceExpression(MemberReferenceExpression node)
{
base.OnMemberReferenceExpression(node);
Check(node);
}
public override void OnGenericReferenceExpression(GenericReferenceExpression node)
{
base.OnGenericReferenceExpression(node);
Check(node);
}
public override void OnQuasiquoteExpression(QuasiquoteExpression node)
{
base.OnQuasiquoteExpression(node);
Check(node);
}
public override void OnStringLiteralExpression(StringLiteralExpression node)
{
base.OnStringLiteralExpression(node);
Check(node);
}
public override void OnCharLiteralExpression(CharLiteralExpression node)
{
base.OnCharLiteralExpression(node);
Check(node);
}
public override void OnTimeSpanLiteralExpression(TimeSpanLiteralExpression node)
{
base.OnTimeSpanLiteralExpression(node);
Check(node);
}
public override void OnIntegerLiteralExpression(IntegerLiteralExpression node)
{
base.OnIntegerLiteralExpression(node);
Check(node);
}
public override void OnDoubleLiteralExpression(DoubleLiteralExpression node)
{
base.OnDoubleLiteralExpression(node);
Check(node);
}
public override void OnNullLiteralExpression(NullLiteralExpression node)
{
base.OnNullLiteralExpression(node);
Check(node);
}
public override void OnSelfLiteralExpression(SelfLiteralExpression node)
{
base.OnSelfLiteralExpression(node);
Check(node);
}
public override void OnSuperLiteralExpression(SuperLiteralExpression node)
{
base.OnSuperLiteralExpression(node);
Check(node);
}
public override void OnBoolLiteralExpression(BoolLiteralExpression node)
{
base.OnBoolLiteralExpression(node);
Check(node);
}
public override void OnRELiteralExpression(RELiteralExpression node)
{
base.OnRELiteralExpression(node);
Check(node);
}
public override void OnSpliceExpression(SpliceExpression node)
{
base.OnSpliceExpression(node);
Check(node);
}
public override void OnSpliceTypeReference(SpliceTypeReference node)
{
base.OnSpliceTypeReference(node);
Check(node);
}
public override void OnSpliceMemberReferenceExpression(SpliceMemberReferenceExpression node)
{
base.OnSpliceMemberReferenceExpression(node);
Check(node);
}
public override void OnSpliceTypeMember(SpliceTypeMember node)
{
base.OnSpliceTypeMember(node);
Check(node);
}
public override void OnSpliceTypeDefinitionBody(SpliceTypeDefinitionBody node)
{
base.OnSpliceTypeDefinitionBody(node);
Check(node);
}
public override void OnSpliceParameterDeclaration(SpliceParameterDeclaration node)
{
base.OnSpliceParameterDeclaration(node);
Check(node);
}
public override void OnExpressionInterpolationExpression(ExpressionInterpolationExpression node)
{
base.OnExpressionInterpolationExpression(node);
Check(node);
}
public override void OnHashLiteralExpression(HashLiteralExpression node)
{
base.OnHashLiteralExpression(node);
Check(node);
}
public override void OnListLiteralExpression(ListLiteralExpression node)
{
base.OnListLiteralExpression(node);
Check(node);
}
public override void OnCollectionInitializationExpression(CollectionInitializationExpression node)
{
base.OnCollectionInitializationExpression(node);
Check(node);
}
public override void OnArrayLiteralExpression(ArrayLiteralExpression node)
{
base.OnArrayLiteralExpression(node);
Check(node);
}
public override void OnGeneratorExpression(GeneratorExpression node)
{
base.OnGeneratorExpression(node);
Check(node);
}
public override void OnExtendedGeneratorExpression(ExtendedGeneratorExpression node)
{
base.OnExtendedGeneratorExpression(node);
Check(node);
}
public override void OnSlice(Slice node)
{
base.OnSlice(node);
Check(node);
}
public override void OnSlicingExpression(SlicingExpression node)
{
base.OnSlicingExpression(node);
Check(node);
}
public override void OnTryCastExpression(TryCastExpression node)
{
base.OnTryCastExpression(node);
Check(node);
}
public override void OnCastExpression(CastExpression node)
{
base.OnCastExpression(node);
Check(node);
}
public override void OnTypeofExpression(TypeofExpression node)
{
base.OnTypeofExpression(node);
Check(node);
}
public override void OnCustomStatement(CustomStatement node)
{
base.OnCustomStatement(node);
Check(node);
}
public override void OnCustomExpression(CustomExpression node)
{
base.OnCustomExpression(node);
Check(node);
}
public override void OnStatementTypeMember(StatementTypeMember node)
{
base.OnStatementTypeMember(node);
Check(node);
}
}
}

Просмотреть файл

@ -61,7 +61,7 @@ namespace UnityScript2CSharp
DumpScripts("Plugin/Editor", pluginEditorScritps); DumpScripts("Plugin/Editor", pluginEditorScritps);
} }
var converter = new UnityScript2CSharpConverter(options.Value.IgnoreErrors); var converter = new UnityScript2CSharpConverter(options.Value.IgnoreErrors, options.Value.SkipComments, options.Value.ShowOrphanComments);
var references = AssemblyReferencesFrom(options); var references = AssemblyReferencesFrom(options);

Просмотреть файл

@ -24,25 +24,12 @@ namespace UnityScript2CSharp.Steps
base.OnModule(node); base.OnModule(node);
foreach (var comment in _sourceComments.ToArray()) AttachRemainingComments(node);
{
var attachedComments = GetAttachedCommentsFrom(comment.BestCandidate);
attachedComments.Add(comment);
_sourceComments.Remove(comment);
}
} }
public override void LeaveMethod(Method node) public override void LeaveMethod(Method node)
{ {
foreach (var comment in _sourceComments.ToArray()) AttachRemainingComments(node);
{
var attachedComments = GetAttachedCommentsFrom(comment.BestCandidate);
attachedComments.Add(comment);
_sourceComments.Remove(comment);
}
base.LeaveMethod(node); base.LeaveMethod(node);
} }
@ -58,8 +45,11 @@ namespace UnityScript2CSharp.Steps
var commentsAboveNode = _sourceComments.Where(candidate => candidate.Token.getLine() < node.LexicalInfo.Line).ToArray(); var commentsAboveNode = _sourceComments.Where(candidate => candidate.Token.getLine() < node.LexicalInfo.Line).ToArray();
foreach (var comment in commentsAboveNode) foreach (var comment in commentsAboveNode)
{ {
comment.BestCandidate = comment.BestCandidate ?? node; if (comment.BestCandidate == null)
{
comment.BestCandidate = node;
comment.AnchorKind = AnchorKind.Above; comment.AnchorKind = AnchorKind.Above;
}
var attachedComments = GetAttachedCommentsFrom(comment.BestCandidate); var attachedComments = GetAttachedCommentsFrom(comment.BestCandidate);
attachedComments.Add(comment); attachedComments.Add(comment);
@ -67,6 +57,10 @@ namespace UnityScript2CSharp.Steps
_sourceComments.Remove(comment); _sourceComments.Remove(comment);
} }
if (node.Entity != null && node.Entity.FullName == "Boo.Lang.Builtins.array")
return;
// Handle comments in the same line // Handle comments in the same line
var foundOnSameLine = _sourceComments.Where(candidate => candidate.Token.getLine() == node.LexicalInfo.Line); var foundOnSameLine = _sourceComments.Where(candidate => candidate.Token.getLine() == node.LexicalInfo.Line);
foreach (var comment in foundOnSameLine) foreach (var comment in foundOnSameLine)
@ -75,55 +69,79 @@ namespace UnityScript2CSharp.Steps
{ {
comment.BestCandidate = node; comment.BestCandidate = node;
comment.Distance = Int32.MaxValue; comment.Distance = Int32.MaxValue;
continue;
} }
int distance = 0;
if (node.LexicalInfo.Column > comment.Token.getColumn()) // comment is on left of the AST node if (node.LexicalInfo.Column > comment.Token.getColumn()) // comment is on left of the AST node
{ {
var endOfCommentCollumn = comment.Token.getColumn() + comment.Token.getText().Length; var endOfCommentCollumn = comment.Token.getColumn() + comment.Token.getText().Length;
var distance = node.LexicalInfo.Column - endOfCommentCollumn; distance = node.LexicalInfo.Column - endOfCommentCollumn;
if (distance <= comment.Distance) if (distance <= comment.Distance && distance >= 0)
{ {
comment.BestCandidate = node; comment.BestCandidate = node;
comment.Distance = distance; comment.Distance = distance;
comment.AnchorKind = AnchorKind.Left; comment.AnchorKind = AnchorKind.Left;
} }
} }
else
{ // comment sould be on RIGHT of the AST node
// comment is on RIGHT of the AST node var endOfNodeColumn = EndColumnOf(node);
var endOfNodeColumn = node.LexicalInfo.Column + TokenLengthFor(node); distance = comment.Token.getColumn() - endOfNodeColumn;
var distance = comment.Token.getColumn() - endOfNodeColumn; if (distance <= comment.Distance && (distance >= 0 || comment.CommentKind == CommentKind.SingleLine))
if (distance <= comment.Distance)
{ {
comment.BestCandidate = node; comment.BestCandidate = node;
comment.Distance = distance; comment.Distance = distance;
comment.AnchorKind = AnchorKind.Right; comment.AnchorKind = AnchorKind.Right;
} }
} }
}
base.OnNode(node); base.OnNode(node);
} }
private void AttachRemainingComments(Node node)
{
if (!node.EndSourceLocation.IsValid)
return;
foreach (var comment in _sourceComments.Where(comment => comment.Token.getLine() <= node.EndSourceLocation.Line).ToArray())
{
if (comment.BestCandidate == null)
{
comment.BestCandidate = node;
comment.AnchorKind = AnchorKind.Below;
}
var attachedComments = GetAttachedCommentsFrom(comment.BestCandidate);
attachedComments.Add(comment);
_sourceComments.Remove(comment);
}
}
private IList<Comment> GetAttachedCommentsFrom(Node node) private IList<Comment> GetAttachedCommentsFrom(Node node)
{ {
if (!node.ContainsAnnotation(COMMENTS_KEY)) if (!node.ContainsAnnotation(COMMENTS_KEY))
{ {
node.Annotate(COMMENTS_KEY, new List<Comment>()); node.Annotate(COMMENTS_KEY, new System.Collections.Generic.List<Comment>());
} }
return (IList<Comment>) node[COMMENTS_KEY]; return (IList<Comment>) node[COMMENTS_KEY];
} }
private int TokenLengthFor(Node node) // This method returns an aproximation for the *end column* of the passed node.
private int EndColumnOf(Node node)
{ {
switch (node.NodeType) switch (node.NodeType)
{ {
case NodeType.ReturnStatement: return "return".Length; case NodeType.BinaryExpression: return ((BinaryExpression) node).Left.LexicalInfo.Column + node.ToString().Length;
case NodeType.ReturnStatement: return node.LexicalInfo.Column + "return".Length;
case NodeType.IfStatement:
{
var condition = ((IfStatement)node).Condition;
return condition.LexicalInfo.Column + condition.ToString().Length + 1; // consider the ')' after the condition
}
} }
return node.ToString().Length; return node.LexicalInfo.Column + node.ToString().Length;
} }
} }
} }

Просмотреть файл

@ -110,6 +110,7 @@
<Compile Include="AnchorKind.cs" /> <Compile Include="AnchorKind.cs" />
<Compile Include="Comment.cs" /> <Compile Include="Comment.cs" />
<Compile Include="CommentKind.cs" /> <Compile Include="CommentKind.cs" />
<Compile Include="OrphanCommentVisitor.cs" />
<Compile Include="Steps\AttachComments.cs" /> <Compile Include="Steps\AttachComments.cs" />
<Compile Include="BlockIdentation.cs" /> <Compile Include="BlockIdentation.cs" />
<Compile Include="CommandLineArguments.cs" /> <Compile Include="CommandLineArguments.cs" />

Просмотреть файл

@ -20,15 +20,20 @@ namespace UnityScript2CSharp
class UnityScript2CSharpConverter class UnityScript2CSharpConverter
{ {
private readonly bool _ignoreErrors; private readonly bool _ignoreErrors;
private readonly bool _skipComments;
private readonly bool _checkOrphanComments;
public UnityScript2CSharpConverter(bool ignoreErrors = false) public UnityScript2CSharpConverter(bool ignoreErrors = false, bool skipComments = false, bool checkOrphanComments = true)
{ {
_ignoreErrors = ignoreErrors; _ignoreErrors = ignoreErrors;
_skipComments = skipComments;
_checkOrphanComments = checkOrphanComments;
} }
public void Convert(IEnumerable<SourceFile> inputs, IEnumerable<string> definedSymbols, IEnumerable<string> referencedAssemblies, Action<string, string, int> onScriptConverted) public void Convert(IEnumerable<SourceFile> inputs, IEnumerable<string> definedSymbols, IEnumerable<string> referencedAssemblies, Action<string, string, int> onScriptConverted)
{ {
var comp = CreatAndInitializeCompiler(inputs, definedSymbols, referencedAssemblies); var comments = CollectCommentsFrom(inputs, definedSymbols);
var comp = CreatAndInitializeCompiler(inputs, definedSymbols, referencedAssemblies, comments);
var result = comp.Run(); var result = comp.Run();
HandleCompilationResult(result); HandleCompilationResult(result);
@ -36,15 +41,21 @@ namespace UnityScript2CSharp
var visitor = new UnityScript2CSharpConverterVisitor(); var visitor = new UnityScript2CSharpConverterVisitor();
visitor.ScriptConverted += onScriptConverted; visitor.ScriptConverted += onScriptConverted;
result.CompileUnit.Accept(visitor); result.CompileUnit.Accept(visitor);
if (_checkOrphanComments)
result.CompileUnit.Accept(new OrphanCommentVisitor());
} }
private IDictionary<string, IList<Comment>> CollectCommentsFrom(IEnumerable<SourceFile> inputs, IEnumerable<string> definedSymbols) private IDictionary<string, IList<Comment>> CollectCommentsFrom(IEnumerable<SourceFile> inputs, IEnumerable<string> definedSymbols)
{ {
var comments = new Dictionary<string, IList<Comment>>(); var comments = new Dictionary<string, IList<Comment>>();
if (!_skipComments)
{
foreach (var source in inputs) foreach (var source in inputs)
{ {
comments[source.FileName] = CollectCommentsFor(source, definedSymbols); comments[source.FileName] = CollectCommentsFor(source, definedSymbols);
} }
}
return comments; return comments;
} }
@ -68,18 +79,10 @@ namespace UnityScript2CSharp
IToken last = null; IToken last = null;
while (token != null && token.Type != UnityScriptLexer.EOF) while (token != null && token.Type != UnityScriptLexer.EOF)
{ {
IToken next = null;
try try
{ {
if (token.Type == UnityScriptLexer.SL_COMMENT || token.Type == UnityScriptLexer.ML_COMMENT) if (token.Type == UnityScriptLexer.SL_COMMENT || token.Type == UnityScriptLexer.ML_COMMENT)
{
next = lexer.nextToken();
if (next.getLine() > token.getLine())
{
token.setText(token.getText() + Environment.NewLine);
}
comments.Add(new Comment(token, token.Type == UnityScriptLexer.SL_COMMENT ? CommentKind.SingleLine : CommentKind.MultipleLine, last)); comments.Add(new Comment(token, token.Type == UnityScriptLexer.SL_COMMENT ? CommentKind.SingleLine : CommentKind.MultipleLine, last));
}
else else
last = token; last = token;
} }
@ -91,7 +94,7 @@ namespace UnityScript2CSharp
{ {
try try
{ {
token = next ?? lexer.nextToken(); token = lexer.nextToken();
} }
catch (TokenStreamRecognitionException tre) catch (TokenStreamRecognitionException tre)
{ {
@ -129,11 +132,10 @@ namespace UnityScript2CSharp
CompilerWarnings = CompilerWarnings ?? new List<string>(); CompilerWarnings = CompilerWarnings ?? new List<string>();
} }
internal UnityScriptCompiler CreatAndInitializeCompiler(IEnumerable<SourceFile> inputs, IEnumerable<string> definedSymbols, IEnumerable<string> referencedAssemblies) internal UnityScriptCompiler CreatAndInitializeCompiler(IEnumerable<SourceFile> inputs, IEnumerable<string> definedSymbols, IEnumerable<string> referencedAssemblies, IDictionary<string, IList<Comment>> comments)
{ {
_compiler = new UnityScriptCompiler(); _compiler = new UnityScriptCompiler();
_compiler.Parameters.TabSize = 4; _compiler.Parameters.TabSize = 4;
var comments = CollectCommentsFrom(inputs, definedSymbols);
SetupCompilerParameters(definedSymbols, referencedAssemblies); SetupCompilerParameters(definedSymbols, referencedAssemblies);
SetupCompilerPipeline(comments); SetupCompilerPipeline(comments);
@ -226,6 +228,8 @@ namespace UnityScript2CSharp
adjustedPipeline.Add(new PromoteImplicitBooleanConversionsToExplicitComparisons()); adjustedPipeline.Add(new PromoteImplicitBooleanConversionsToExplicitComparisons());
adjustedPipeline.Add(new InstanceToTypeReferencedStaticMemberReference()); adjustedPipeline.Add(new InstanceToTypeReferencedStaticMemberReference());
adjustedPipeline.Add(new TransforwmKnownUnityEngineMethods()); adjustedPipeline.Add(new TransforwmKnownUnityEngineMethods());
if (!_skipComments)
adjustedPipeline.Add(new AttachComments(comments)); adjustedPipeline.Add(new AttachComments(comments));
_compiler.Parameters.Pipeline = adjustedPipeline; _compiler.Parameters.Pipeline = adjustedPipeline;

Просмотреть файл

@ -44,12 +44,12 @@ namespace UnityScript2CSharp
public override void OnSimpleTypeReference(SimpleTypeReference node) public override void OnSimpleTypeReference(SimpleTypeReference node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Left);
var typeName = TypeNameFor(node.Entity); var typeName = TypeNameFor(node.Entity);
_writer.Write(typeName ?? node.Name); _writer.Write(typeName ?? node.Name);
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
private void _builderAppendIdented(string str) private void _builderAppendIdented(string str)
@ -75,12 +75,20 @@ namespace UnityScript2CSharp
public override void OnArrayTypeReference(ArrayTypeReference node) public override void OnArrayTypeReference(ArrayTypeReference node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
node.ElementType.Accept(this); node.ElementType.Accept(this);
_writer.Write($"[{new String(',', (int) (node.Rank.Value -1))}]"); _writer.Write($"[{new String(',', (int) (node.Rank.Value -1))}]");
WriteComments(node, AnchorKind.Right);
} }
public override void OnCallableTypeReference(CallableTypeReference node) public override void OnCallableTypeReference(CallableTypeReference node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
var types = new List<TypeReference>(node.Parameters.Select(p => p.Type)); var types = new List<TypeReference>(node.Parameters.Select(p => p.Type));
if (node.ReturnType == null) if (node.ReturnType == null)
{ {
@ -98,6 +106,7 @@ namespace UnityScript2CSharp
WriteCommaSeparatedList(types); WriteCommaSeparatedList(types);
_writer.Write(">"); _writer.Write(">");
} }
WriteComments(node, AnchorKind.Right);
} }
public override void OnGenericTypeReference(GenericTypeReference node) public override void OnGenericTypeReference(GenericTypeReference node)
@ -147,6 +156,9 @@ namespace UnityScript2CSharp
if (IsSyntheticDelegateUsedByCallable(node)) if (IsSyntheticDelegateUsedByCallable(node))
return; return;
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.WriteLine("[System.Serializable]"); // Every class in UnityScript is serializable _writer.WriteLine("[System.Serializable]"); // Every class in UnityScript is serializable
WriteAttributes(node.Attributes); WriteAttributes(node.Attributes);
@ -159,6 +171,8 @@ namespace UnityScript2CSharp
_writer.WriteLine("{"); _writer.WriteLine("{");
WriteMembersOf(node); WriteMembersOf(node);
_writer.WriteLine("}"); _writer.WriteLine("}");
WriteComments(node, AnchorKind.Right);
} }
public override void OnStructDefinition(StructDefinition node) public override void OnStructDefinition(StructDefinition node)
@ -186,8 +200,15 @@ namespace UnityScript2CSharp
public override void OnEnumDefinition(EnumDefinition node) public override void OnEnumDefinition(EnumDefinition node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.IndentNextWrite = true; _writer.IndentNextWrite = true;
_writer.WriteLine($"{ModifiersToString(node.Modifiers)} enum {node.Name}"); _writer.Write($"{ModifiersToString(node.Modifiers)} enum {node.Name}");
WriteComments(node, AnchorKind.Right);
_writer.WriteLine();
_writer.WriteLine("{"); _writer.WriteLine("{");
using (new BlockIdentation(_writer)) using (new BlockIdentation(_writer))
{ {
@ -203,16 +224,24 @@ namespace UnityScript2CSharp
public override void OnEnumMember(EnumMember node) public override void OnEnumMember(EnumMember node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write(node.Name); _writer.Write(node.Name);
if (node.Initializer != null) if (node.Initializer != null)
{ {
_writer.Write(" = "); _writer.Write(" = ");
node.Initializer.Accept(this); node.Initializer.Accept(this);
} }
WriteComments(node, AnchorKind.Right);
} }
public override void OnField(Field node) public override void OnField(Field node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
WriteAttributes(node.Attributes); WriteAttributes(node.Attributes);
_builderAppend(ModifiersToString(node.Modifiers)); _builderAppend(ModifiersToString(node.Modifiers));
@ -226,6 +255,8 @@ namespace UnityScript2CSharp
_builderAppend(" = "); _builderAppend(" = ");
} }
WriteComments(node, AnchorKind.Right);
_writer.WriteLine(";"); _writer.WriteLine(";");
} }
@ -256,10 +287,14 @@ namespace UnityScript2CSharp
public override void OnMethod(Method node) public override void OnMethod(Method node)
{ {
HandleComments(node, AnchorKind.Above); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
if (node.Name == "Main" || node.IsSynthetic) if (node.Name == "Main" || node.IsSynthetic)
{
WriteComments(node, AnchorKind.Below);
return; return;
}
WriteAttributes(node.Attributes); WriteAttributes(node.Attributes);
@ -273,10 +308,14 @@ namespace UnityScript2CSharp
_builderAppend(node.Name); _builderAppend(node.Name);
WriteParameterList(node.Parameters); WriteParameterList(node.Parameters);
WriteComments(node, AnchorKind.Right);
if (isInterface) if (isInterface)
_writer.WriteLine(";"); _writer.WriteLine(";");
else else
node.Body.Accept(this); node.Body.Accept(this);
WriteComments(node, AnchorKind.Below);
} }
public override bool EnterBlock(Block node) public override bool EnterBlock(Block node)
@ -311,6 +350,9 @@ namespace UnityScript2CSharp
public override void OnConstructor(Constructor node) public override void OnConstructor(Constructor node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
var stmts = CtorStatementsWithoutParameterlessSuperInvocation(node); var stmts = CtorStatementsWithoutParameterlessSuperInvocation(node);
if (stmts.Count == 0) if (stmts.Count == 0)
return; return;
@ -325,6 +367,8 @@ namespace UnityScript2CSharp
WriteCtorChainningFor(node); WriteCtorChainningFor(node);
WriteComments(node, AnchorKind.Right);
node.Body.Accept(this); node.Body.Accept(this);
} }
@ -336,9 +380,14 @@ namespace UnityScript2CSharp
public override void OnParameterDeclaration(ParameterDeclaration node) public override void OnParameterDeclaration(ParameterDeclaration node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
node.Type.Accept(this); node.Type.Accept(this);
_builderAppend(' '); _builderAppend(' ');
_builderAppend(node.Name); _builderAppend(node.Name);
WriteComments(node, AnchorKind.Right);
} }
public override void OnGenericParameterDeclaration(GenericParameterDeclaration node) public override void OnGenericParameterDeclaration(GenericParameterDeclaration node)
@ -373,6 +422,9 @@ namespace UnityScript2CSharp
public override void OnAttribute(Attribute node) public override void OnAttribute(Attribute node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
if (node.Name == "System.SerializableAttribute") if (node.Name == "System.SerializableAttribute")
return; return;
@ -397,6 +449,8 @@ namespace UnityScript2CSharp
_writer.Write(")"); _writer.Write(")");
_writer.WriteLine("]"); _writer.WriteLine("]");
WriteComments(node, AnchorKind.Right);
} }
public override void OnStatementModifier(StatementModifier node) public override void OnStatementModifier(StatementModifier node)
@ -462,10 +516,15 @@ namespace UnityScript2CSharp
public override void OnIfStatement(IfStatement node) public override void OnIfStatement(IfStatement node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_builderAppendIdented("if ("); _builderAppendIdented("if (");
node.Condition.Accept(this); node.Condition.Accept(this);
_builderAppend(")"); _builderAppend(")");
WriteComments(node, AnchorKind.Right);
node.TrueBlock.Accept(this); node.TrueBlock.Accept(this);
if (node.FalseBlock != null) if (node.FalseBlock != null)
{ {
@ -482,6 +541,9 @@ namespace UnityScript2CSharp
public override void OnForStatement(ForStatement node) public override void OnForStatement(ForStatement node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write("foreach ("); _writer.Write("foreach (");
VisitPossibleClashingDeclaration(node.Declarations[0]); VisitPossibleClashingDeclaration(node.Declarations[0]);
@ -489,42 +551,56 @@ namespace UnityScript2CSharp
node.Iterator.Accept(this); node.Iterator.Accept(this);
_writer.Write(")"); _writer.Write(")");
WriteComments(node, AnchorKind.Right);
node.Block.Accept(this); node.Block.Accept(this);
} }
public override void OnWhileStatement(WhileStatement node) public override void OnWhileStatement(WhileStatement node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_builderAppendIdented("while ("); _builderAppendIdented("while (");
node.Condition.Accept(this); node.Condition.Accept(this);
_builderAppend(")"); _builderAppend(")");
WriteComments(node, AnchorKind.Right);
node.Block.Accept(this); node.Block.Accept(this);
} }
public override void OnBreakStatement(BreakStatement node) public override void OnBreakStatement(BreakStatement node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.WriteLine("break;"); _writer.WriteLine("break;");
HandleComments(node, AnchorKind.Right);
WriteComments(node, AnchorKind.Right);
} }
public override void OnContinueStatement(ContinueStatement node) public override void OnContinueStatement(ContinueStatement node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.WriteLine("continue;"); _writer.WriteLine("continue;");
HandleComments(node, AnchorKind.Right);
WriteComments(node, AnchorKind.Right);
} }
public override void OnReturnStatement(ReturnStatement node) public override void OnReturnStatement(ReturnStatement node)
{ {
HandleComments(node, AnchorKind.Above); WriteComments(node, AnchorKind.Above);
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Left);
if (TryHandleYieldBreak(node)) if (TryHandleYieldBreak(node))
return; return;
_builderAppendIdented("return"); _builderAppendIdented("return");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
if (node.Expression != null) if (node.Expression != null)
{ {
@ -537,6 +613,9 @@ namespace UnityScript2CSharp
public override void OnYieldStatement(YieldStatement node) public override void OnYieldStatement(YieldStatement node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write("yield return "); _writer.Write("yield return ");
if (node.Expression != null) if (node.Expression != null)
node.Expression.Accept(this); node.Expression.Accept(this);
@ -544,6 +623,8 @@ namespace UnityScript2CSharp
_writer.Write("null"); _writer.Write("null");
_writer.WriteLine(";"); _writer.WriteLine(";");
WriteComments(node, AnchorKind.Right);
} }
public override void OnRaiseStatement(RaiseStatement node) public override void OnRaiseStatement(RaiseStatement node)
@ -560,11 +641,15 @@ namespace UnityScript2CSharp
public override void OnExpressionStatement(ExpressionStatement node) public override void OnExpressionStatement(ExpressionStatement node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
node.Expression.Accept(this); node.Expression.Accept(this);
if (!_lastIgnored) if (!_lastIgnored)
_writer.WriteLine(";"); _writer.WriteLine(";");
_lastIgnored = false; _lastIgnored = false;
WriteComments(node, AnchorKind.Right);
} }
public override void OnOmittedExpression(OmittedExpression node) public override void OnOmittedExpression(OmittedExpression node)
@ -575,14 +660,22 @@ namespace UnityScript2CSharp
public override void OnExpressionPair(ExpressionPair node) public override void OnExpressionPair(ExpressionPair node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
node.First.Accept(this); node.First.Accept(this);
_writer.Write(" = "); _writer.Write(" = ");
node.Second.Accept(this); node.Second.Accept(this);
WriteComments(node, AnchorKind.Right);
} }
public override void OnMethodInvocationExpression(MethodInvocationExpression node) public override void OnMethodInvocationExpression(MethodInvocationExpression node)
{ {
if (node.Target.Entity != null && node.Target.Entity.EntityType == EntityType.BuiltinFunction) WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
if (node.Target.Entity != null && node.Target.Entity.EntityType == EntityType.BuiltinFunction && node.Target.Entity != BuiltinFunction.Quack)
{ {
_lastIgnored = true; _lastIgnored = true;
return; return;
@ -618,6 +711,8 @@ namespace UnityScript2CSharp
WriteParameterList(node.Arguments, refOutWriter); WriteParameterList(node.Arguments, refOutWriter);
_brackets.Pop(); _brackets.Pop();
WriteComments(node, AnchorKind.Right);
} }
private void HandleNewExpression(MethodInvocationExpression node) private void HandleNewExpression(MethodInvocationExpression node)
@ -630,6 +725,9 @@ namespace UnityScript2CSharp
public override void OnUnaryExpression(UnaryExpression node) public override void OnUnaryExpression(UnaryExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
bool postOperator = AstUtil.IsPostUnaryOperator(node.Operator); bool postOperator = AstUtil.IsPostUnaryOperator(node.Operator);
var operatorText = node.Operator == UnaryOperatorType.LogicalNot ? "!" : BooPrinterVisitor.GetUnaryOperatorText(node.Operator); var operatorText = node.Operator == UnaryOperatorType.LogicalNot ? "!" : BooPrinterVisitor.GetUnaryOperatorText(node.Operator);
if (!postOperator) if (!postOperator)
@ -641,10 +739,15 @@ namespace UnityScript2CSharp
{ {
_builderAppend(operatorText); _builderAppend(operatorText);
} }
WriteComments(node, AnchorKind.Right);
} }
public override void OnBinaryExpression(BinaryExpression node) public override void OnBinaryExpression(BinaryExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
var needParensAround = node.Operator != BinaryOperatorType.Assign; var needParensAround = node.Operator != BinaryOperatorType.Assign;
if (needParensAround) if (needParensAround)
{ {
@ -671,10 +774,15 @@ namespace UnityScript2CSharp
_writer.Write($" {CSharpOperatorFor(node.Operator)} "); _writer.Write($" {CSharpOperatorFor(node.Operator)} ");
node.Right.Accept(this); node.Right.Accept(this);
}); });
WriteComments(node, AnchorKind.Right);
} }
public override void OnConditionalExpression(ConditionalExpression node) public override void OnConditionalExpression(ConditionalExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
var parent = node.ParentNode as BinaryExpression; var parent = node.ParentNode as BinaryExpression;
var needsParens = parent != null && (parent.Right != node || parent.Operator != BinaryOperatorType.Assign); var needsParens = parent != null && (parent.Right != node || parent.Operator != BinaryOperatorType.Assign);
@ -686,15 +794,21 @@ namespace UnityScript2CSharp
_writer.Write(" : "); _writer.Write(" : ");
VisitWrapping(node.FalseValue, node.FalseValue.NodeType == NodeType.ConditionalExpression, "(", ")"); VisitWrapping(node.FalseValue, node.FalseValue.NodeType == NodeType.ConditionalExpression, "(", ")");
}); });
WriteComments(node, AnchorKind.Right);
} }
public override void OnReferenceExpression(ReferenceExpression node) public override void OnReferenceExpression(ReferenceExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
if (node.ContainsAnnotation("VALUE_TYPE_INITIALIZATON_MARKER")) if (node.ContainsAnnotation("VALUE_TYPE_INITIALIZATON_MARKER"))
{ {
_writer.Write("default("); _writer.Write("default(");
_writer.Write(TypeNameFor(node.Entity) ?? node.Name); _writer.Write(TypeNameFor(node.Entity) ?? node.Name);
_writer.Write(")"); _writer.Write(")");
WriteComments(node, AnchorKind.Right);
return; return;
} }
@ -702,16 +816,26 @@ namespace UnityScript2CSharp
_writer.Write("object"); _writer.Write("object");
else else
_writer.Write(TypeNameFor(node.Entity) ?? node.Name); _writer.Write(TypeNameFor(node.Entity) ?? node.Name);
WriteComments(node, AnchorKind.Right);
} }
public override void OnMemberReferenceExpression(MemberReferenceExpression node) public override void OnMemberReferenceExpression(MemberReferenceExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
node.Target.Accept(this); node.Target.Accept(this);
_builderAppend($".{node.Name}"); _builderAppend($".{node.Name}");
WriteComments(node, AnchorKind.Right);
} }
public override void OnGenericReferenceExpression(GenericReferenceExpression node) public override void OnGenericReferenceExpression(GenericReferenceExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
if (node.IsArrayInstantiation()) if (node.IsArrayInstantiation())
{ {
_writer.Write("new "); _writer.Write("new ");
@ -731,6 +855,8 @@ namespace UnityScript2CSharp
_writer.Write(", "); _writer.Write(", ");
} }
_writer.Write(">"); _writer.Write(">");
WriteComments(node, AnchorKind.Right);
} }
public override void OnQuasiquoteExpression(QuasiquoteExpression node) public override void OnQuasiquoteExpression(QuasiquoteExpression node)
@ -760,9 +886,10 @@ namespace UnityScript2CSharp
value.Replace(replacement.Key, replacement.Value); value.Replace(replacement.Key, replacement.Value);
} }
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write($"\"{value}\""); _writer.Write($"\"{value}\"");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnCharLiteralExpression(CharLiteralExpression node) public override void OnCharLiteralExpression(CharLiteralExpression node)
@ -779,44 +906,50 @@ namespace UnityScript2CSharp
public override void OnIntegerLiteralExpression(IntegerLiteralExpression node) public override void OnIntegerLiteralExpression(IntegerLiteralExpression node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write(node.Value); _writer.Write(node.Value);
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnDoubleLiteralExpression(DoubleLiteralExpression node) public override void OnDoubleLiteralExpression(DoubleLiteralExpression node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write($"{node.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)}f"); _writer.Write($"{node.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)}f");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnNullLiteralExpression(NullLiteralExpression node) public override void OnNullLiteralExpression(NullLiteralExpression node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_builderAppend("null"); _builderAppend("null");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnSelfLiteralExpression(SelfLiteralExpression node) public override void OnSelfLiteralExpression(SelfLiteralExpression node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write("this"); _writer.Write("this");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnSuperLiteralExpression(SuperLiteralExpression node) public override void OnSuperLiteralExpression(SuperLiteralExpression node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write("base"); _writer.Write("base");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnBoolLiteralExpression(BoolLiteralExpression node) public override void OnBoolLiteralExpression(BoolLiteralExpression node)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write(node.Value ? "true" : "false"); _writer.Write(node.Value ? "true" : "false");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
} }
public override void OnRELiteralExpression(RELiteralExpression node) public override void OnRELiteralExpression(RELiteralExpression node)
@ -869,6 +1002,9 @@ namespace UnityScript2CSharp
public override void OnHashLiteralExpression(HashLiteralExpression node) public override void OnHashLiteralExpression(HashLiteralExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write("new Hashtable() {"); _writer.Write("new Hashtable() {");
foreach (var item in node.Items) foreach (var item in node.Items)
{ {
@ -879,6 +1015,8 @@ namespace UnityScript2CSharp
_writer.Write(" }, "); _writer.Write(" }, ");
} }
_writer.Write("}"); _writer.Write("}");
WriteComments(node, AnchorKind.Right);
} }
public override void OnListLiteralExpression(ListLiteralExpression node) public override void OnListLiteralExpression(ListLiteralExpression node)
@ -916,23 +1054,36 @@ namespace UnityScript2CSharp
public override void OnSlicingExpression(SlicingExpression node) public override void OnSlicingExpression(SlicingExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
node.Target.Accept(this); node.Target.Accept(this);
_writer.Write("["); _writer.Write("[");
WriteCommaSeparatedList(node.Indices); WriteCommaSeparatedList(node.Indices);
_writer.Write("]"); _writer.Write("]");
WriteComments(node, AnchorKind.Right);
} }
public override void OnTryCastExpression(TryCastExpression node) public override void OnTryCastExpression(TryCastExpression node)
{ {
var isTargetOfMemberReferenceExpression = NeedParensAround(node); var isTargetOfMemberReferenceExpression = NeedParensAround(node);
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
VisitWrapping(node.Target, isTargetOfMemberReferenceExpression, "("); VisitWrapping(node.Target, isTargetOfMemberReferenceExpression, "(");
_writer.Write(" as "); _writer.Write(" as ");
VisitWrapping(node.Type, isTargetOfMemberReferenceExpression, posfix: ")"); VisitWrapping(node.Type, isTargetOfMemberReferenceExpression, posfix: ")");
WriteComments(node, AnchorKind.Right);
} }
public override void OnCastExpression(CastExpression node) public override void OnCastExpression(CastExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
WrapWith(NeedParensAround(node), "(", ")", delegate WrapWith(NeedParensAround(node), "(", ")", delegate
{ {
_writer.Write("("); _writer.Write("(");
@ -944,13 +1095,20 @@ namespace UnityScript2CSharp
node.Target.Accept(this); node.Target.Accept(this);
}); });
}); });
WriteComments(node, AnchorKind.Right);
} }
public override void OnTypeofExpression(TypeofExpression node) public override void OnTypeofExpression(TypeofExpression node)
{ {
WriteComments(node, AnchorKind.Above);
WriteComments(node, AnchorKind.Left);
_writer.Write("typeof("); _writer.Write("typeof(");
node.Type.Accept(this); node.Type.Accept(this);
_writer.Write(")"); _writer.Write(")");
WriteComments(node, AnchorKind.Right);
} }
public override void OnCustomStatement(CustomStatement node) public override void OnCustomStatement(CustomStatement node)
@ -978,9 +1136,9 @@ namespace UnityScript2CSharp
if (isReturningIEnumerable) if (isReturningIEnumerable)
{ {
HandleComments(node, AnchorKind.Left); WriteComments(node, AnchorKind.Left);
_writer.Write("yield break;"); _writer.Write("yield break;");
HandleComments(node, AnchorKind.Right); WriteComments(node, AnchorKind.Right);
_writer.WriteLine(); _writer.WriteLine();
} }
@ -1335,7 +1493,7 @@ namespace UnityScript2CSharp
return "Label" + label.Replace("$", "_"); return "Label" + label.Replace("$", "_");
} }
private void HandleComments(Node node, AnchorKind anchorKind) private void WriteComments(Node node, AnchorKind anchorKind)
{ {
if (!node.ContainsAnnotation(COMMENT_KEY)) if (!node.ContainsAnnotation(COMMENT_KEY))
return; return;
@ -1353,6 +1511,9 @@ namespace UnityScript2CSharp
_writer.WriteBeforeNextNewLine(commentText); _writer.WriteBeforeNextNewLine(commentText);
else else
_writer.Write(commentText); _writer.Write(commentText);
if (comment.AnchorKind == AnchorKind.Above)
_writer.WriteLine();
} }
if (comments.Count == 0) if (comments.Count == 0)

Просмотреть файл

@ -7,7 +7,7 @@ namespace UnityScript2CSharp
{ {
private StringBuilder _builder; private StringBuilder _builder;
private int _indentation; private int _indentation;
private string _x; private string _toBeWrittenBeforeNextNewLine;
private static readonly string _newLine = Environment.NewLine; private static readonly string _newLine = Environment.NewLine;
public Writer(string contents) public Writer(string contents)
@ -49,10 +49,10 @@ namespace UnityScript2CSharp
public void WriteLine() public void WriteLine()
{ {
if (_x != null) if (_toBeWrittenBeforeNextNewLine != null)
{ {
_builder.Append(_x); _builder.Append(_toBeWrittenBeforeNextNewLine);
_x = null; _toBeWrittenBeforeNextNewLine = null;
} }
_builder.Append(_newLine); _builder.Append(_newLine);
@ -66,7 +66,7 @@ namespace UnityScript2CSharp
} }
public void WriteBeforeNextNewLine(string text) public void WriteBeforeNextNewLine(string text)
{ {
_x = text; _toBeWrittenBeforeNextNewLine = text;
} }
public static string NewLine { get { return _newLine; } } public static string NewLine { get { return _newLine; } }