Skip to content
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

Closed
peter-ahe-google opened this issue Nov 16, 2011 · 9 comments
Closed

Weird parser error #475

peter-ahe-google opened this issue Nov 16, 2011 · 9 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.

Comments

@peter-ahe-google
Copy link
Contributor

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: []]

@DartBot
Copy link

DartBot commented Nov 16, 2011

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?

@peter-ahe-google
Copy link
Contributor Author

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 {
  test() {
    token;
  }
}

main() {
  new Fisk().test();
}

Unhandled exception:
NoSuchMethodException - receiver: 'Instance of 'Fisk'' function name: 'get:token' arguments: []]
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:93 col:3
 1. Function: 'Fisk.test' url: '/Users/ahe/Dart/all/dart.googlecode.com/dart/foo.dart' line:3 col:10
 2. Function: '::.main' url: '/Users/ahe/Dart/all/dart.googlecode.com/dart/foo.dart' line:8 col:18

@ghost
Copy link

ghost commented Nov 16, 2011

VM has no concept of warnings, none are produced (all according to spec, AFAIK).
Using a variable incorrectly should be a compile time error, as in this:

foo(x) {
  x y z;
}

@DartBot
Copy link

DartBot commented Nov 16, 2011

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.

@peter-ahe-google
Copy link
Contributor Author

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."

@gbracha
Copy link
Contributor

gbracha commented Nov 16, 2011

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).

@iposva-google
Copy link
Contributor

In the latest VM builds we do not complain about the type confusion any longer. Although we are not resolving the access to token properly: Issue #1805


Set owner to @mhausner.
Added Accepted label.
Marked this as being blocked by #1805.

@DartBot
Copy link

DartBot commented Apr 13, 2012

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'
Receiver: Instance of 'Fisk'
Arguments: []
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:717 col:3
 1. Function: 'Fisk.peekAfterType' url: 'file:///Users/hausner/tmp/t.dart' line:10 col:24
 2. Function: '::main' url: 'file:///Users/hausner/tmp/t.dart' line:15 col:27

In checked mode, we get an error, as expected:

$ dart --enable_type_checks=true ~/tmp/t.dart
'file:///Users/hausner/tmp/t.dart': Error: line 10 pos 5: using 'Token' in this context is invalid
    Token peek = token.next;
    ^


Added Fixed label.

@peter-ahe-google
Copy link
Contributor Author

Very nice. Thank you!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.
Projects
None yet
Development

No branches or pull requests

4 participants