Adding a constructor with the invalid name "with" angers the analyzer like a wild boar whose territory has been invaded #28807

Closed
Hixie opened this Issue Feb 17, 2017 · 3 comments

Projects

None yet

3 participants

@Hixie
Contributor
Hixie commented Feb 17, 2017 edited

Consider the following perfectly reasonable-looking piece of code. It has one mild error, though you may not notice it at first: the constructor name "with" is not a valid constructor name since that's a keyword. (Github's syntax highlighting makes that obvious.)

import 'package:meta/meta.dart';

typedef void AlternatingListCallback<T, U>(T odd, U even);

class AlternatingList<T, U> {
  AlternatingList() : _oddEntries = <T>[], _evenEntries = <U>[];

  AlternatingList.with(T odd, U even) {
    _oddEntries = <T>[odd];
    _evenEntries = <U>[even];
  }

  AlternatingList.from(AlternatingList<T, U> other) {
    _oddEntries = new List<T>.from(other._oddEntries);
    _evenEntries = new List<U>.from(other._evenEntries);
  }

  AlternatingList.prepend(T odd, U even, { @required AlternatingList<T, U> to }) {
    _oddEntries = new List<T>.from(to._oddEntries);
    _oddEntries.insert(0, odd);
    _evenEntries = new List<U>.from(to._evenEntries);
    _evenEntries.insert(0, even);
  }

  List<T> _oddEntries;
  List<U> _evenEntries;

  int get length => _oddEntries.length;

  bool get sealed => _sealed;
  bool _sealed = false;

  void seal() {
    _sealed = true;
  }

  void addPair(T odd, U even) {
    assert(!_sealed);
    _oddEntries.add(odd);
    _evenEntries.add(even);
  }

  void forEach(AlternatingListCallback<T, U> callback) {
    assert(_sealed);
    assert(_oddEntries.length == _evenEntries.length);
    for (int index = 0; index < length; index += 1)
      callback(_oddEntries[index], _evenEntries[index]);
  }

  bool contains(dynamic target) {
    return _oddEntries.contains(target) || _evenEntries.contains(target);
  }
}

void main() {
}

Here's the analyzer's output:

Analyzing [test.dart]...
[error] 'U' can't be used to name both a type variable and a member in this class. (/home/ianh/dev/scratch/test.dart, line 5, col 26)
[error] Invalid constructor name. (/home/ianh/dev/scratch/test.dart, line 6, col 3)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 6, col 60)
[error] Undefined class 'AlternatingList.with'. (/home/ianh/dev/scratch/test.dart, line 8, col 3)
[error] Expected an identifier. (/home/ianh/dev/scratch/test.dart, line 8, col 19)
[error] Expected a class member. (/home/ianh/dev/scratch/test.dart, line 8, col 19)
[error] Unexpected text 'with'. (/home/ianh/dev/scratch/test.dart, line 8, col 19)
[error] Unexpected text '('. (/home/ianh/dev/scratch/test.dart, line 8, col 23)
[error] Expected a class member. (/home/ianh/dev/scratch/test.dart, line 8, col 23)
[error] Expected to find ';'. (/home/ianh/dev/scratch/test.dart, line 8, col 31)
[error] even isn't a type. (/home/ianh/dev/scratch/test.dart, line 8, col 33)
[error] Unexpected text ')'. (/home/ianh/dev/scratch/test.dart, line 8, col 37)
[error] Expected a class member. (/home/ianh/dev/scratch/test.dart, line 8, col 37)
[error] Unexpected text '{'. (/home/ianh/dev/scratch/test.dart, line 8, col 39)
[error] Expected a class member. (/home/ianh/dev/scratch/test.dart, line 8, col 39)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 9, col 5)
[error] Only static members can be accessed in initializers. (/home/ianh/dev/scratch/test.dart, line 9, col 23)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 10, col 5)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 10, col 21)
[error] Undefined class 'AlternatingList.from'. (/home/ianh/dev/scratch/test.dart, line 13, col 3)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 13, col 23)
[error] Unexpected text '('. (/home/ianh/dev/scratch/test.dart, line 13, col 23)
[error] AlternatingList isn't a type. (/home/ianh/dev/scratch/test.dart, line 13, col 24)
[error] The name 'T' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 13, col 40)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 13, col 43)
[error] Expected to find ';'. (/home/ianh/dev/scratch/test.dart, line 13, col 46)
[error] Unexpected text ')'. (/home/ianh/dev/scratch/test.dart, line 13, col 51)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 13, col 51)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 14, col 5)
[error] The name 'T' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 14, col 28)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 15, col 5)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 15, col 29)
[error] Unexpected text '}'. (/home/ianh/dev/scratch/test.dart, line 16, col 3)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 16, col 3)
[error] Undefined class 'AlternatingList.prepend'. (/home/ianh/dev/scratch/test.dart, line 18, col 3)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 26)
[error] Unexpected text '('. (/home/ianh/dev/scratch/test.dart, line 18, col 26)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 26)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 18, col 26)
[error] Undefined class 'T'. (/home/ianh/dev/scratch/test.dart, line 18, col 27)
[error] Expected to find ';'. (/home/ianh/dev/scratch/test.dart, line 18, col 34)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 18, col 36)
[error] Expected to find ';'. (/home/ianh/dev/scratch/test.dart, line 18, col 42)
[error] Expected an identifier. (/home/ianh/dev/scratch/test.dart, line 18, col 42)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 42)
[error] Unexpected text '{'. (/home/ianh/dev/scratch/test.dart, line 18, col 42)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 42)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 18, col 42)
[error] required isn't a type. (/home/ianh/dev/scratch/test.dart, line 18, col 45)
[error] The name 'AlternatingList' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 54)
[error] A function body must be provided. (/home/ianh/dev/scratch/test.dart, line 18, col 76)
[error] Undefined class 'to'. (/home/ianh/dev/scratch/test.dart, line 18, col 76)
[error] Functions must have an explicit list of parameters. (/home/ianh/dev/scratch/test.dart, line 18, col 76)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 79)
[error] Unexpected text '}'. (/home/ianh/dev/scratch/test.dart, line 18, col 79)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 18, col 79)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 18, col 79)
[error] The name '_oddEntries=' is already defined. (/home/ianh/dev/scratch/test.dart, line 19, col 5)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 19, col 5)
[error] The name '_oddEntries' is already defined. (/home/ianh/dev/scratch/test.dart, line 19, col 5)
[error] The name 'T' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 19, col 28)
[error] Undefined name 'to'. (/home/ianh/dev/scratch/test.dart, line 19, col 36)
[error] Undefined class '_oddEntries.insert'. (/home/ianh/dev/scratch/test.dart, line 20, col 5)
[error] Unexpected text '('. (/home/ianh/dev/scratch/test.dart, line 20, col 23)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 20, col 23)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 20, col 23)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 20, col 23)
[error] odd isn't a type. (/home/ianh/dev/scratch/test.dart, line 20, col 27)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 20, col 30)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 20, col 30)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 20, col 30)
[error] Unexpected text ')'. (/home/ianh/dev/scratch/test.dart, line 20, col 30)
[error] The name '_evenEntries' is already defined. (/home/ianh/dev/scratch/test.dart, line 21, col 5)
[error] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. (/home/ianh/dev/scratch/test.dart, line 21, col 5)
[error] The name '_evenEntries=' is already defined. (/home/ianh/dev/scratch/test.dart, line 21, col 5)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 21, col 29)
[error] Undefined name 'to'. (/home/ianh/dev/scratch/test.dart, line 21, col 37)
[error] Undefined class '_evenEntries.insert'. (/home/ianh/dev/scratch/test.dart, line 22, col 5)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 22, col 24)
[error] Unexpected text '('. (/home/ianh/dev/scratch/test.dart, line 22, col 24)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 22, col 24)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 22, col 24)
[error] even isn't a type. (/home/ianh/dev/scratch/test.dart, line 22, col 28)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 22, col 32)
[error] The name '=' is already defined. (/home/ianh/dev/scratch/test.dart, line 22, col 32)
[error] The name '' is already defined. (/home/ianh/dev/scratch/test.dart, line 22, col 32)
[error] Unexpected text ')'. (/home/ianh/dev/scratch/test.dart, line 22, col 32)
[error] The name 'T' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 25, col 8)
[error] The name '_oddEntries=' is already defined. (/home/ianh/dev/scratch/test.dart, line 25, col 11)
[error] The name '_oddEntries' is already defined. (/home/ianh/dev/scratch/test.dart, line 25, col 11)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 26, col 8)
[error] The name '_evenEntries' is already defined. (/home/ianh/dev/scratch/test.dart, line 26, col 11)
[error] The name '_evenEntries=' is already defined. (/home/ianh/dev/scratch/test.dart, line 26, col 11)
[error] Undefined class 'T'. (/home/ianh/dev/scratch/test.dart, line 37, col 16)
[error] U isn't a type. (/home/ianh/dev/scratch/test.dart, line 37, col 23)
[error] The name 'T' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 43, col 40)
[error] The name 'U' isn't a type so it can't be used as a type argument. (/home/ianh/dev/scratch/test.dart, line 43, col 43)
[error] Expected a method, getter, setter or operator declaration. (/home/ianh/dev/scratch/test.dart, line 53, col 1)
[error] Unexpected text '}'. (/home/ianh/dev/scratch/test.dart, line 53, col 1)
[hint] Unused import. (/home/ianh/dev/scratch/test.dart, line 1, col 8)
[lint] Type annotate public APIs. (/home/ianh/dev/scratch/test.dart, line 18, col 36)
[lint] Name non-constant identifiers using lowerCamelCase. (/home/ianh/dev/scratch/test.dart, line 18, col 54)
99 errors, 1 hint and 2 lints found.

None of those errors are actually the error I would expect.

I would expect [error] The reserved word "with" cannot be used to name a constructor. (/home/ianh/dev/scratch/test.dart, line 8, col 19).

There are a few errors mentioning the word "with", the fourth (Undefined class 'AlternatingList.with') is highly misleading, the seventh (Unexpected text 'with') is at least not wrong. (The seventh is the one that finally helped me figure out what the actual problem was.)

@cbracken
Member
@bwilkerson
Member

Ouch! That's definitely a poor UX!

@bwilkerson bwilkerson self-assigned this Feb 18, 2017
@bwilkerson bwilkerson closed this Feb 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment