Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Move $ContextStack to $ErrorData, and append location data for syntax errors #461

Merged
merged 1 commit into from
Apr 27, 2017

Conversation

sebmarkbage
Copy link
Contributor

@sebmarkbage sebmarkbage commented Apr 26, 2017

I believe the $ErrorData slot is meant to be an internal host provided object that keeps things like the context stack on it. So we don't need to come up with another slot to store it. We might want to minimize internal fields to create monomorphic data structures as a perf optimization.

I also added another field to $ErrorData that stores the source location of syntax errors when the parser causes an error.

This is used inside hosting environments such as Node to print a nicer error message with the location of the syntax error. This is different from the contextStack since this is not actually part of the execution stack.

This can be used to print messages with an error showing the location of the syntax error.

foo.js:3
x ++ y
     ^
SyntaxError: Unexpected identifier

You can see how I use it to model the contextify module in node.js which uses this data to append to the stack of an error if it bubbles up to the evaluation of a script boundary (a contextify script).

We could do the same thing in the Repl for example to show where syntax errors occurred.

@@ -18,9 +18,9 @@ import traverse from "babel-traverse";
import { parse } from "babylon";
import type { BabelNodeFile } from "babel-types";

export default function (realm: Realm, code: string, filename: string, sourceType: SourceType = "script"): BabelNodeFile {
export default function (realm: Realm, code: string, filename: string, sourceType: SourceType = "script", startLine: number = 1): BabelNodeFile {
Copy link
Contributor Author

@sebmarkbage sebmarkbage Apr 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also needed the startLine option to model contextify's ability to shift source location numbers. @kittens is there a way to do the same for columns in babylon?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to make sure that everything we add to the code base has test coverage, so it would be better if startLine can be added in a separate pull request that includes a use case and test for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal of this string of PRs is to break out everything from #397 with changes existing code. To make it easier to review that one. I could just leave it in #397 as one big blob but that makes rebasing and reviewing harder. I could make up some artificial test case here but I'm not quite sure how to do a pure unit test since we don't really have any infra set up for unit tests. I'd have to wire up a lot of things just to test this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. It is usually possible to do an integration test that exercises new code, but in this case we'd need a unit testing story.

@sebmarkbage sebmarkbage force-pushed the syntaxerrorlocation branch 2 times, most recently from 662e039 to 4c3aae5 Compare April 26, 2017 03:17
Copy link
Contributor

@hermanventer hermanventer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until the CI build issues are sorted out, please push a branch to facebook/prepack. We should never merge a commit that has not been checked by the CI.

}
if (error.$ErrorData) {
// If the constructed Error object has the built-in error data append
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why "if"? My expectation is that Construct will always provide a value for it. Consequently, I would prefer to state this in an invariant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally had it as an invariant but then I wondered if this could be messed with at runtime. Since this can get called after something has messed with internal constructors and prototypes.

I don't think there is any mechanism to change the allocation strategy here at the moment (even if you change the prototype), but if there was a reflective mechanism to change the constructor or if this constructor was later specified to invoke a super call of its prototype (like the inheritance mechanism is set up) then it would be possible.

That was my defensive rationale at least. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of the code is that there is no way for user code to cause $ErrorData to be missing from an Error object. If a change to the prepack code causes $ErrorData to be absent, it is very likely an unintended and undesirable change, so an invariant is a far better way to deal with the absence than relying on a unit test to fail.

@@ -18,9 +18,9 @@ import traverse from "babel-traverse";
import { parse } from "babylon";
import type { BabelNodeFile } from "babel-types";

export default function (realm: Realm, code: string, filename: string, sourceType: SourceType = "script"): BabelNodeFile {
export default function (realm: Realm, code: string, filename: string, sourceType: SourceType = "script", startLine: number = 1): BabelNodeFile {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to make sure that everything we add to the code base has test coverage, so it would be better if startLine can be added in a separate pull request that includes a use case and test for it.

…rrors

I believe the $ErrorData slot is meant to be an internal host provided
object that keeps things like the context stack on it. So we don't need
to come up with another slot to store it. We might want to minimize
internal fields to create monomorphic data structures as a perf
optimization.

I also added another field to $ErrorData that stores the source location
of syntax errors when the parser causes an error.

This is used inside hosting environments such as Node to print a nicer
error message with the location of the syntax error. This is different
from the contextStack since this is not actually part of the execution
stack.

This can be used to print messages with an error showing the location of
the syntax error.

```
foo.js:3
x ++ y
     ^
SyntaxError: Unexpected identifier
```
@sebmarkbage sebmarkbage force-pushed the syntaxerrorlocation branch from 4c3aae5 to 2994c52 Compare April 26, 2017 17:58
@sebmarkbage sebmarkbage dismissed hermanventer’s stale review April 26, 2017 18:21

I switched to using invariant. I pushed a branch but didn't submit another PR to avoid bloating the PRs since we can't delete them. However you can see this branch passing here: https://circleci.com/gh/facebook/prepack/289

@sebmarkbage
Copy link
Contributor Author

Oh because I pushed the same commit I guess it shows as passed here too. Cool.

@sebmarkbage sebmarkbage merged commit 0bea37c into facebookarchive:master Apr 27, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants