Skip to content
Merged
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
4 changes: 2 additions & 2 deletions Rewrite/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<Company>Moderne Inc.</Company>
<PackageIcon>openrewrite.png</PackageIcon>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<Version>0.8.0-preview-3</Version>
<Version>0.8.0-preview-4</Version>

<RewriteRemoteVersion>$(Version)</RewriteRemoteVersion>
<RewriteRemoteVersion>0.8.0-preview-3</RewriteRemoteVersion>
<RewriteRemoteDir Condition="'$(RewriteRemoteDir)'==''">..\..\..\..\..\moderneinc\rewrite-remote\Rewrite.Remote</RewriteRemoteDir>
</PropertyGroup>
</Project>
30 changes: 20 additions & 10 deletions Rewrite/src/Rewrite.CSharp/CSharpParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public Builder References(IEnumerable<MetadataReference> references)
_references = references;
return this;
}

public override Core.Parser.Builder Clone()
{
return new Builder();
Expand All @@ -58,17 +59,26 @@ public IEnumerable<SourceFile> ParseInputs(IEnumerable<Core.Parser.Input> source
var sourceFiles = new List<SourceFile>();
foreach (var source in sources)
{
var sourceText = SourceText.From(source.GetSource(ctx), encoding);
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText, path: source.GetRelativePath(relativeTo));
var root = syntaxTree.GetRoot();
var compilation = CSharpCompilation.Create("Dummy")
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(references)
.AddSyntaxTrees(syntaxTree);
var semanticModel = compilation.GetSemanticModel(syntaxTree);
SourceFile cs;
try
{
var sourceText = SourceText.From(source.GetSource(ctx), encoding);
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText, path: source.GetRelativePath(relativeTo));
var root = syntaxTree.GetRoot();
var compilation = CSharpCompilation.Create("Dummy")
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(references)
.AddSyntaxTrees(syntaxTree);
var semanticModel = compilation.GetSemanticModel(syntaxTree);

var visitor = new CSharpParserVisitor(semanticModel);
var cs = visitor.Visit(root) as Cs.CompilationUnit;
var visitor = new CSharpParserVisitor(semanticModel);
cs = visitor.Visit(root) as Cs.CompilationUnit;
}
catch (Exception t)
{
// ctx.OnError.accept(t);
cs = ParseError.Build(this, source, relativeTo, ctx, t);
}

sourceFiles.Add(cs!);
}
Expand Down
88 changes: 55 additions & 33 deletions Rewrite/src/Rewrite.CSharp/Parser/CSharpParserVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ public override J.Block VisitAccessorList(AccessorListSyntax node)
Format(Leading(node.CloseBraceToken))
);
}

private JRightPadded<Statement> MapAccessor(AccessorDeclarationSyntax accessorDeclarationSyntax)
{
var methodDeclaration = Convert<J.MethodDeclaration>(accessorDeclarationSyntax)!;
Expand Down Expand Up @@ -1393,7 +1393,8 @@ private J.Identifier MapIdentifier(SyntaxToken identifier, JavaType? type)
{
// the AST hierarchy in Roslyn is very different from that with `J.FieldAccess`
// see `VisitMemberBindingExpression()` for more details
return Convert<Expression>(node.WhenNotNull)!;
// return Convert<Expression>(node.WhenNotNull)!;
return base.VisitConditionalAccessExpression(node);
}

public override J? VisitMemberBindingExpression(MemberBindingExpressionSyntax node)
Expand Down Expand Up @@ -1909,13 +1910,17 @@ private J.ArrayAccess MapArrayAccess(ElementAccessExpressionSyntax node, int ind
private JRightPadded<J.VariableDeclarations.NamedVariable> MapNamedVariableFromExpression(
ExpressionSyntax expression)
{
var identifier = Convert<J.Identifier>(expression)!;
var identifierOrFieldAccess = Convert<Expression>(expression)!;
var identifier = identifierOrFieldAccess is J.Identifier i
? i
: (identifierOrFieldAccess as J.FieldAccess).Name;
return new JRightPadded<J.VariableDeclarations.NamedVariable>(
new J.VariableDeclarations.NamedVariable(
Core.Tree.RandomId(),
Format(Leading(expression)),
Markers.EMPTY,
identifier,
new J.Identifier(Core.Tree.RandomId(), identifierOrFieldAccess.Prefix, identifierOrFieldAccess.Markers,
identifier.Annotations, expression.ToString(), identifier.Type, identifier.FieldType),
[],
null,
identifier.Type as JavaType.Variable
Expand Down Expand Up @@ -2152,15 +2157,18 @@ private JRightPadded<Statement> MapAnonymousObjectMember(AnonymousObjectMemberDe
Markers.EMPTY,
node.StringStartToken.ToString(),
node.Contents.Count == 0
? [new JRightPadded<Expression>(
new J.Empty(
Core.Tree.RandomId(),
Format(Trailing(node.StringStartToken)),
?
[
new JRightPadded<Expression>(
new J.Empty(
Core.Tree.RandomId(),
Format(Trailing(node.StringStartToken)),
Markers.EMPTY
),
Space.EMPTY,
Markers.EMPTY
),
Space.EMPTY,
Markers.EMPTY
)]
)
]
: node.Contents.Select(c => new JRightPadded<Expression>(
Convert<Expression>(c)!,
Format(Trailing(c)),
Expand Down Expand Up @@ -2673,35 +2681,48 @@ private IList<JLeftPadded<Space>> MapArrayDimensions(BracketedArgumentListSyntax

public override J? VisitUsingStatement(UsingStatementSyntax node)
{
var jContainer = new JContainer<J.Try.Resource>(
Format(Leading(node.OpenParenToken)),
node.Declaration != null
?
[
new JRightPadded<J.Try.Resource>(
new J.Try.Resource(
Core.Tree.RandomId(),
Format(Leading(node.Declaration)),
Markers.EMPTY,
Convert<TypedTree>(node.Declaration)!,
false
),
Format(Trailing(node.Declaration)),
Markers.EMPTY
)
]
: [],
Markers.EMPTY
);
var s = Convert<Statement>(node.Statement);

return new J.Try(
Core.Tree.RandomId(),
Format(Leading(node)),
Markers.EMPTY,
new JContainer<J.Try.Resource>(
Format(Leading(node.OpenParenToken)),
node.Declaration != null
?
jContainer,
s is not J.Block block
? new J.Block(
Core.Tree.RandomId(),
Space.EMPTY,
Markers.EMPTY.Add(new OmitBraces(Core.Tree.RandomId())),
JRightPadded<bool>.Build(false),
[
new JRightPadded<J.Try.Resource>(
new J.Try.Resource(
Core.Tree.RandomId(),
Format(Leading(node.Declaration)),
Markers.EMPTY,
Convert<TypedTree>(node.Declaration)!,
false
),
Format(Trailing(node.Declaration)),
Markers.EMPTY
)
]
: [],
Markers.EMPTY
),
Convert<J.Block>(node.Statement)!,
JRightPadded<Statement>.Build(s),
],
Space.EMPTY
)
: block,
[],
null
);
return base.VisitUsingStatement(node);
}

public override J? VisitFixedStatement(FixedStatementSyntax node)
Expand Down Expand Up @@ -3423,6 +3444,7 @@ private JRightPadded<Expression> MapSwitchCaseLabel(SwitchLabelSyntax sls)
statement
) as T;
}

return (T?)visit;
}

Expand Down
26 changes: 26 additions & 0 deletions Rewrite/src/Rewrite.Core/Internal/ExceptionUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Rewrite.Core.Internal;

public class ExceptionUtils
{
public static string SanitizeStackTrace(Exception t, Type until)
{
var cause = t;
var sanitized = "";
sanitized = string.Join("\n", sanitized, cause.GetType().Name + ": " + cause.Message);

var i = 0;
foreach (var stackTraceElement in cause.StackTrace.TakeWhile(stackTraceElement =>
!stackTraceElement.Equals(until.Name)))
{
if (i++ >= 16)
{
sanitized = string.Join("\n", sanitized, " ...");
break;
}

sanitized = string.Join("\n", sanitized, " " + stackTraceElement);
}

return sanitized;
}
}
147 changes: 147 additions & 0 deletions Rewrite/src/Rewrite.Core/ParseError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System.Text;
using Rewrite.Core.Marker;

namespace Rewrite.Core;

public class ParseError(
Guid id,
Markers markers,
string sourcePath,
FileAttributes? fileAttributes,
string? charsetName,
bool charsetBomMarked,
Checksum? checksum,
string text,
SourceFile? erroneous) : SourceFile
{
public Guid Id => id;

public ParseError WithId(Guid newId)
{
return newId == id
? this
: new ParseError(newId, markers, sourcePath, fileAttributes, charsetName, charsetBomMarked, checksum, text,
erroneous);
}

public Markers Markers => markers;

public ParseError WithMarkers(Markers newMarkers)
{
return ReferenceEquals(newMarkers, markers)
? this
: new ParseError(id, newMarkers, sourcePath, fileAttributes, charsetName, charsetBomMarked, checksum, text,
erroneous);
}

public string SourcePath => sourcePath;

public ParseError WithSourcePath(string newSourcePath)
{
return newSourcePath == sourcePath
? this
: new ParseError(id, markers, newSourcePath, fileAttributes, charsetName, charsetBomMarked, checksum, text,
erroneous);
}

public FileAttributes? FileAttributes => fileAttributes;

public ParseError WithFileAttributes(FileAttributes? newFileAttributes)
{
return newFileAttributes == fileAttributes
? this
: new ParseError(id, markers, sourcePath, newFileAttributes, charsetName, charsetBomMarked, checksum, text,
erroneous);
}

public string? CharsetName => charsetName;

public ParseError WithCharsetName(string? newCharsetName)
{
return newCharsetName == charsetName
? this
: new ParseError(id, markers, sourcePath, fileAttributes, newCharsetName, charsetBomMarked, checksum, text,
erroneous);
}

public bool CharsetBomMarked => charsetBomMarked;

public ParseError WithCharsetBomMarked(bool newCharsetBomMarked)
{
return newCharsetBomMarked == charsetBomMarked
? this
: new ParseError(id, markers, sourcePath, fileAttributes, charsetName, newCharsetBomMarked, checksum, text,
erroneous);
}

public Checksum? Checksum => checksum;

public ParseError WithChecksum(Checksum? newChecksum)
{
return newChecksum == checksum
? this
: new ParseError(id, markers, sourcePath, fileAttributes, charsetName, charsetBomMarked, newChecksum, text,
erroneous);
}

public string Text => text;

public ParseError WithText(string newText)
{
return newText == text
? this
: new ParseError(id, markers, sourcePath, fileAttributes, charsetName, charsetBomMarked, checksum, newText,
erroneous);
}

public SourceFile? Erroneous => erroneous;

public ParseError WithErroneous(SourceFile? newErroneous)
{
return ReferenceEquals(newErroneous, erroneous)
? this
: new ParseError(id, markers, sourcePath, fileAttributes, charsetName, charsetBomMarked, checksum, text,
newErroneous);
}

public bool Equals(Tree? other)
{
return other is ParseError && other.Id == Id;
}

public override int GetHashCode()
{
return Id.GetHashCode();
}

public bool IsAcceptable<R, P>(ITreeVisitor<R, P> v, P p) where R : class, Tree
{
return v.IsAdaptableTo(typeof(ParseErrorVisitor<P>));
}

public ITreeVisitor<Tree, PrintOutputCapture<P>> Printer<P>(Cursor cursor)
{
return IPrinterFactory.Current()!.CreatePrinter<P>();
}

public static ParseError Build(Parser parser,
Parser.Input input,
string? relativeTo,
ExecutionContext ctx,
Exception t)
{
var stream = input.GetSource(ctx);
using var readableStream = new StreamReader(stream, Encoding.UTF8);
return new ParseError(
Tree.RandomId(),
new Markers(Tree.RandomId(), [ParseExceptionResult.build(parser, t)]),
input.GetRelativePath(relativeTo),
null, // FIXME: need real file attr
parser.GetCharset(ctx),
false, // stream.isCharsetBomMarked(),
null,
readableStream.ReadToEnd(),
null
);
}
}
Loading