|
70 | 70 | import org.truffleruby.language.arguments.MissingArgumentBehavior;
|
71 | 71 | import org.truffleruby.language.arguments.ReadPreArgumentNode;
|
72 | 72 | import org.truffleruby.language.arguments.RubyArguments;
|
| 73 | +import org.truffleruby.language.control.RaiseException; |
73 | 74 | import org.truffleruby.language.control.WhileNode;
|
74 | 75 | import org.truffleruby.language.control.WhileNodeFactory;
|
75 | 76 | import org.truffleruby.language.library.RubyStringLibrary;
|
|
84 | 85 | import org.truffleruby.shared.Metrics;
|
85 | 86 | import org.yarp.Loader;
|
86 | 87 | import org.yarp.Nodes;
|
| 88 | +import org.yarp.ParseResult; |
87 | 89 | import org.yarp.Parser;
|
88 | 90 |
|
89 | 91 | import java.util.ArrayList;
|
@@ -405,10 +407,52 @@ public static org.yarp.Nodes.Node parseToYARPAST(RubyContext context, RubyLangua
|
405 | 407 | byte[] serializedBytes = Parser.parseAndSerialize(sourceBytes);
|
406 | 408 |
|
407 | 409 | var yarpSource = createYARPSource(sourceBytes, rubySource);
|
408 |
| - return Loader.load(serializedBytes, yarpSource); |
409 |
| - // YARP end |
| 410 | + var parseResult = Loader.load(serializedBytes, yarpSource); |
| 411 | + |
| 412 | + final String filename = rubySource.getSourcePath(); |
| 413 | + final ParseResult.Error[] errors = parseResult.getErrors(); |
| 414 | + |
| 415 | + // collect warnings generated by the parser |
| 416 | + for (ParseResult.Warning warning : parseResult.getWarnings()) { |
| 417 | + Nodes.Location location = warning.getLocation(); |
| 418 | + SourceSection section = rubySource.getSource().createSection(location.startOffset, location.length); |
| 419 | + int lineNumber = RubySource.getStartLineAdjusted(context, section); |
| 420 | + |
| 421 | + rubyWarnings.warn(filename, lineNumber, warning.getMessage()); |
| 422 | + } |
| 423 | + |
| 424 | + if (errors.length != 0) { |
| 425 | + // print warnings immediately |
| 426 | + // if there is no syntax error they will be printed in runtime |
| 427 | + if (!rubyWarnings.warnings.isEmpty()) { |
| 428 | + EmitWarningsNode.printWarnings(context, rubyWarnings); |
| 429 | + } |
| 430 | + |
| 431 | + // Handle only the first reported syntax error. |
| 432 | + // The order of errors should be deterministic, |
| 433 | + // but it isn't guarantied that the first error is the most specific/relevant to user |
| 434 | + ParseResult.Error error = errors[0]; |
410 | 435 |
|
411 |
| - // TODO: handle syntax errors |
| 436 | + Nodes.Location location = error.getLocation(); |
| 437 | + SourceSection section = rubySource.getSource().createSection(location.startOffset, location.length); |
| 438 | + String message = context.fileLine(section) + ": " + error.getMessage(); |
| 439 | + |
| 440 | + if (context != null) { |
| 441 | + int lineNumber = RubySource.getStartLineAdjusted(context, section); |
| 442 | + |
| 443 | + throw new RaiseException( |
| 444 | + context, |
| 445 | + context.getCoreExceptions().syntaxErrorAlreadyWithFileLine( |
| 446 | + message, |
| 447 | + null, |
| 448 | + rubySource.getSource().createSection(lineNumber))); |
| 449 | + } else { |
| 450 | + throw new UnsupportedOperationException(message); |
| 451 | + } |
| 452 | + } |
| 453 | + |
| 454 | + return parseResult.getValue(); |
| 455 | + // YARP end |
412 | 456 |
|
413 | 457 | // RubyParser parser = new RubyParser(lexerSource, rubyWarnings);
|
414 | 458 | // TruffleSafepoint.poll(DummyNode.INSTANCE); // RubyParser <clinit> takes a while
|
|
0 commit comments