-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weird parser error #475
Comments
This comment was originally written by @mhausner The error message from the VM may seem weird, but I think it is correct. method peekAfterType has one untyped parameter named Token, which hides the class name Token. The line: Token peek = token.next; therefore starts with the expression Token, after which the compiler expects a semicolon. Are you saying this interpretation of the semantics of your code snipped it incorrect? |
The error message from the VM is not correct. The program contains a lot of warnings, but the VM normally doesn't produce these warnings. So instead the VM should compile the code and produce a dynamic error on this line: Token peek = token.next; This is because "token" is unresolved, so it turns into "this.token". So the dynamic error would be: NoSuchMethodException - receiver: 'Instance of 'Fisk'' function name: 'get:token' arguments: []] Similar to how it would treat this program: class Fisk { main() { Unhandled exception: |
VM has no concept of warnings, none are produced (all according to spec, AFAIK). foo(x) { |
This comment was originally written by @mhausner The issue in the code is not that token is undefined. The language spec clearly defines what happens when an identifier cannot be resolved. The issue is that what looks like a declaration: Token peek = ... is not a valid declaration. Token is not a type, it's the name of the formal parameter. Thus, this line is a malformed expression and the error message is correct. I agree that the error message is misleading, but that is because you expect the line to be something completely different from what it actually is. |
Where in the spec does it say that Token peek = ... is not a valid declaration? The grammar says that it is a variable declaration statement. The grammar is context free. The specification says the following about type annotations: "Static type annotations are used in variable declarations (5) (including formal parameters (6.2)) and in the return types of functions (6). Static type annotations are used during static checking and when running programs in checked mode. They have no effect whatsoever in production mode." |
Token peek == token.next; is a variable declaration. The fact that Token is the name of a formal parameter does not change that (it's a context-free grammar). |
This comment was originally written by @mhausner This is now fixed. The VM correctly reports a runtime error when it can not resolve the call to getter for 'token': NoSuchMethodException : method not found: 'get:token' In checked mode, we get an error, as expected: $ dart --enable_type_checks=true ~/tmp/t.dart Added Fixed label. |
Very nice. Thank you! |
This program:
final int IDENTIFIER_TOKEN = 0;
class Token {
int kind;
}
class Fisk {
Token peekAfterType(Token) {
assert(token.kind === IDENTIFIER_TOKEN);
Token peek = token.next;
}
}
main() {
new Fisk().peekAfterType(null);
}
Gives this error:
'foo.dart': Error: line 10 pos 11: semicolon expected
Token peek = token.next;
^
Compare this to how dartc handles this problem:
foo.dart/foo.dart:10: type "Token" expected, but "PARAMETER" found
9: assert(token.kind === IDENTIFIER_TOKEN);
10: Token peek = token.next;
foo.dart/foo.dart:10: no such type "Token"
9: assert(token.kind === IDENTIFIER_TOKEN);
10: Token peek = token.next;
foo.dart/foo.dart:9: cannot resolve token
8: Token peekAfterType(Token) {
9: assert(token.kind === IDENTIFIER_TOKEN);
foo.dart/foo.dart:10: cannot resolve token
9: assert(token.kind === IDENTIFIER_TOKEN);
10: Token peek = token.next;
These are all warnings (as they should be) and the program runs and throws an dynamic error:
/var/folders/++/++3l3+++6+0++4RjPqRgNE+-QFE/-Tmp-/dart_foo.dart1176370598895860049.js:17663: TypeError: Object #<unnamedc08e84$Fisk$Dart> has no method 'token$getter'
var peek = this.token$getter().next$getter();
^
TypeError: Object #<unnamedc08e84$Fisk$Dart> has no method 'token$getter'
And here is what frogsh reports:
foo.dart:9:12: warning: can not resolve "token" on "Fisk"
assert(token.kind === IDENTIFIER_TOKEN);
^^^^^
foo.dart:9:12: warning: token is not defined anywhere in the world.
assert(token.kind === IDENTIFIER_TOKEN);
^^^^^
foo.dart:10:18: warning: can not resolve "token" on "Fisk"
Token peek = token.next;
^^^^^
foo.dart:10:18: warning: token is not defined anywhere in the world.
Token peek = token.next;
^^^^^
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
NoSuchMethodException - receiver: '[object Object]' function name: 'get:token' arguments: []]
The text was updated successfully, but these errors were encountered: