Support multiple categories per message.

Also move more messages to use this feature.

R=brianwilkerson@google.com

Review URL: https://codereview.chromium.org/1763373002 .
This commit is contained in:
Florian Loitsch 2016-03-07 16:37:57 +01:00
parent e0f7b4f314
commit 65b4256b9e
7 changed files with 306 additions and 108 deletions

View file

@ -3435,9 +3435,8 @@ class HintCode extends ErrorCode {
* 0: the name of the actual argument type
* 1: the name of the expected type
*/
static const HintCode ARGUMENT_TYPE_NOT_ASSIGNABLE = const HintCode(
'ARGUMENT_TYPE_NOT_ASSIGNABLE',
"The argument type '{0}' cannot be assigned to the parameter type '{1}'");
static const HintCode ARGUMENT_TYPE_NOT_ASSIGNABLE =
shared_messages.ARGUMENT_TYPE_NOT_ASSIGNABLE_HINT;
/**
* When the target expression uses '?.' operator, it can be `null`, so all the
@ -4125,8 +4124,7 @@ class StaticTypeWarningCode extends ErrorCode {
* 2: the name of the method
*/
static const StaticTypeWarningCode RETURN_OF_INVALID_TYPE =
const StaticTypeWarningCode('RETURN_OF_INVALID_TYPE',
"The return type '{0}' is not a '{1}', as defined by the method '{2}'");
shared_messages.RETURN_OF_INVALID_TYPE;
/**
* 12.11 Instance Creation: It is a static type warning if any of the type
@ -4472,8 +4470,7 @@ class StaticWarningCode extends ErrorCode {
* 1: the name of the expected type
*/
static const StaticWarningCode ARGUMENT_TYPE_NOT_ASSIGNABLE =
const StaticWarningCode('ARGUMENT_TYPE_NOT_ASSIGNABLE',
"The argument type '{0}' cannot be assigned to the parameter type '{1}'");
shared_messages.ARGUMENT_TYPE_NOT_ASSIGNABLE_STATIC_WARNING;
/**
* 5 Variables: Attempting to assign to a final variable elsewhere will cause

View file

@ -81,3 +81,18 @@ const CompileTimeErrorCode RETURN_IN_GENERATOR = const CompileTimeErrorCode(
'RETURN_IN_GENERATOR',
"Can't return a value from a generator function (using the '{0}' modifier).",
"Try removing the value, replacing 'return' with 'yield' or changing the method body modifier"); // Generated. Don't edit.
const StaticTypeWarningCode RETURN_OF_INVALID_TYPE = const StaticTypeWarningCode(
'RETURN_OF_INVALID_TYPE',
"The return type '{0}' is not a '{1}', as defined by the method '{2}'.",
null); // Generated. Don't edit.
const HintCode ARGUMENT_TYPE_NOT_ASSIGNABLE_HINT = const HintCode(
'ARGUMENT_TYPE_NOT_ASSIGNABLE',
"The argument type '{0}' cannot be assigned to the parameter type '{1}'.",
null); // Generated. Don't edit.
const StaticWarningCode ARGUMENT_TYPE_NOT_ASSIGNABLE_STATIC_WARNING = const StaticWarningCode(
'ARGUMENT_TYPE_NOT_ASSIGNABLE',
"The argument type '{0}' cannot be assigned to the parameter type '{1}'.",
null); // Generated. Don't edit.

View file

@ -120,4 +120,19 @@ const Map<MessageKind, MessageTemplate> TEMPLATES = const <MessageKind, MessageT
""",
]
), // Generated. Don't edit.
MessageKind.NOT_ASSIGNABLE: const MessageTemplate(
MessageKind.NOT_ASSIGNABLE,
"'#{fromType}' is not assignable to '#{toType}'." ), // Generated. Don't edit.
MessageKind.FORIN_NOT_ASSIGNABLE: const MessageTemplate(
MessageKind.FORIN_NOT_ASSIGNABLE,
"The element type '#{currentType}' of '#{expressionType}' is not assignable to '#{elementType}'.",
examples: const [
r"""
main() {
List<int> list = <int>[1, 2];
for (String x in list) x;
}
""",
]
), // Generated. Don't edit.
};

View file

@ -518,15 +518,6 @@ class MessageTemplate {
MessageKind.GENERIC:
const MessageTemplate(MessageKind.GENERIC, '#{text}'),
MessageKind.NOT_ASSIGNABLE:
const MessageTemplate(MessageKind.NOT_ASSIGNABLE,
"'#{fromType}' is not assignable to '#{toType}'."),
MessageKind.FORIN_NOT_ASSIGNABLE:
const MessageTemplate(MessageKind.FORIN_NOT_ASSIGNABLE,
"The element type '#{currentType}' of '#{expressionType}' "
"is not assignable to '#{elementType}'."),
MessageKind.VOID_EXPRESSION:
const MessageTemplate(MessageKind.VOID_EXPRESSION,
"Expression does not yield a value."),

View file

@ -172,6 +172,19 @@ String convertToAnalyzerTemplate(String template, holeOrder) {
});
}
String camlToAllCaps(String input) {
StringBuffer out = new StringBuffer();
for (int i = 0; i < input.length; i++) {
String c = input[i];
if (c.toUpperCase() == c) {
out.write("_$c");
} else {
out.write(c.toUpperCase());
}
}
return out.toString();
}
/// Emits the messages in analyzer format.
///
/// Messages are encoded as instances of `ErrorCode` classes where the
@ -200,21 +213,25 @@ void emitAnalyzer() {
"show ParserErrorCode;");
input.forEach((name, message) {
if (!message.usedBy.contains(Platform.analyzer)) return;
List<Category> categories = message.categories;
bool hasMultipleCategories = categories.length != 1;
for (Category category in categories) {
String className = category.name + "Code";
String analyzerName =
hasMultipleCategories ? "$name${camlToAllCaps(category.name)}" : name;
out.writeln();
out.writeln("const $className $analyzerName = const $className(");
out.writeln(" '$name',");
Category category = message.category;
String className = category.name + "Code";
out.writeln();
out.writeln("const $className $name = const $className(");
out.writeln(" '$name',");
String template = message.template;
List holeOrder = message.templateHoleOrder;
String analyzerTemplate = convertToAnalyzerTemplate(template, holeOrder);
out.write(" ");
out.write(escapeString(analyzerTemplate));
out.write(",\n ");
out.write(escapeString(message.howToFix));
out.writeln("); // Generated. Don't edit.");
String template = message.template;
List holeOrder = message.templateHoleOrder;
String analyzerTemplate = convertToAnalyzerTemplate(template, holeOrder);
out.write(" ");
out.write(escapeString(analyzerTemplate));
out.write(",\n ");
out.write(escapeString(message.howToFix));
out.writeln("); // Generated. Don't edit.");
}
});
new io.File(outPath).writeAsStringSync(out.toString());

View file

@ -2,7 +2,9 @@
"exampleMessage": {
"id": "use an Id generated by bin/message_id.dart",
"subId": 0,
"category": "AnalysisOptionsError",
"categories": [
"AnalysisOptionsError"
],
"template": "#use #named #arguments",
"templateHoleOrder": [
"arguments",
@ -23,7 +25,9 @@
"CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY": {
"id": "LGJGHW",
"subId": 0,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Const constructor or factory can't have a body.",
"templateHoleOrder": null,
"howToFix": "Remove the 'const' keyword or the body.",
@ -39,7 +43,9 @@
"CONST_CONSTRUCTOR_WITH_BODY": {
"id": "LGJGHW",
"subId": 1,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Const constructor can't have a body.",
"templateHoleOrder": null,
"howToFix": "Try removing the 'const' keyword or the body.",
@ -54,7 +60,9 @@
"CONST_FACTORY": {
"id": "LGJGHW",
"subId": 2,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Only redirecting factory constructors can be declared to be 'const'.",
"templateHoleOrder": null,
"howToFix": "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.",
@ -69,7 +77,9 @@
"EXTRANEOUS_MODIFIER": {
"id": "GRKIQE",
"subId": 0,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Can't have modifier '#{modifier}' here.",
"templateHoleOrder": null,
"howToFix": "Try removing '#{modifier}'.",
@ -99,7 +109,9 @@
"EXTRANEOUS_MODIFIER_REPLACE": {
"id": "GRKIQE",
"subId": 1,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Can't have modifier '#{modifier}' here.",
"templateHoleOrder": null,
"howToFix": "Try replacing modifier '#{modifier}' with 'var', 'final', or a type.",
@ -117,7 +129,9 @@
"CONST_CLASS": {
"id": "GRKIQE",
"subId": 2,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Classes can't be declared to be 'const'",
"templateHoleOrder": null,
"howToFix": "Try removing the 'const' keyword or moving to the class' constructor(s).",
@ -132,7 +146,9 @@
"CONST_METHOD": {
"id": "GRKIQE",
"subId": 3,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Getters, setters and methods can't be declared to be 'const'",
"templateHoleOrder": null,
"howToFix": "Try removing the 'const' keyword.",
@ -152,7 +168,9 @@
"CONST_ENUM": {
"id": "GRKIQE",
"subId": 4,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Enums can't be declared to be 'const'",
"templateHoleOrder": null,
"howToFix": "Try removing the 'const' keyword.",
@ -167,7 +185,9 @@
"CONST_TYPEDEF": {
"id": "GRKIQE",
"subId": 5,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Type aliases can't be declared to be 'const'",
"templateHoleOrder": null,
"howToFix": "Try removing the 'const' keyword.",
@ -182,7 +202,9 @@
"CONST_AND_FINAL": {
"id": "GRKIQE",
"subId": 6,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Members can't be declared to be both 'const' and 'final'",
"templateHoleOrder": null,
"howToFix": "Try removing either the 'const' or 'final' keyword.",
@ -200,7 +222,9 @@
"CONST_AND_VAR": {
"id": "GRKIQE",
"subId": 7,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Members can't be declared to be both 'const' and 'var'",
"templateHoleOrder": null,
"howToFix": "Try removing either the 'const' or 'var' keyword.",
@ -218,7 +242,9 @@
"CLASS_IN_CLASS": {
"id": "DOTHQH",
"subId": 0,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Classes can't be declared inside other classes.",
"templateHoleOrder": null,
"howToFix": "Try moving the class to the top-level.",
@ -233,7 +259,9 @@
"CONSTRUCTOR_WITH_RETURN_TYPE": {
"id": "VOJBWY",
"subId": 0,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Constructors can't have a return type",
"templateHoleOrder": null,
"howToFix": "Try removing the return type.",
@ -249,7 +277,9 @@
"MISSING_EXPRESSION_IN_THROW": {
"id": "FTGGMJ",
"subId": 0,
"category": "ParserError",
"categories": [
"ParserError"
],
"template": "Missing expression after 'throw'.",
"templateHoleOrder": null,
"howToFix": "Did you mean 'rethrow'?",
@ -266,7 +296,9 @@
"RETHROW_OUTSIDE_CATCH": {
"id": "MWETLC",
"subId": 0,
"category": "CompileTimeError",
"categories": [
"CompileTimeError"
],
"template": "Rethrow must be inside of catch clause",
"templateHoleOrder": null,
"howToFix": "Try moving the expression into a catch clause, or using a 'throw' expression.",
@ -282,7 +314,9 @@
"RETURN_IN_GENERATIVE_CONSTRUCTOR": {
"id": "UOTDQH",
"subId": 0,
"category": "CompileTimeError",
"categories": [
"CompileTimeError"
],
"template": "Constructors can't return values.",
"templateHoleOrder": null,
"howToFix": "Try removing the return statement or using a factory constructor.",
@ -298,7 +332,9 @@
"RETURN_IN_GENERATOR": {
"id": "JRUTUQ",
"subId": 0,
"category": "CompileTimeError",
"categories": [
"CompileTimeError"
],
"template": "Can't return a value from a generator function (using the '#{modifier}' modifier).",
"templateHoleOrder": null,
"howToFix": "Try removing the value, replacing 'return' with 'yield' or changing the method body modifier",
@ -311,5 +347,72 @@
" foo() async* { return 0; }\n main() => foo();\n ",
" foo() sync* { return 0; }\n main() => foo();\n "
]
},
"NOT_ASSIGNABLE": {
"id": "FYQYXB",
"subId": 0,
"categories": [
"StaticTypeWarning"
],
"template": "'#{fromType}' is not assignable to '#{toType}'.",
"templateHoleOrder": null,
"howToFix": null,
"options": null,
"usedBy": [
"Platform.dart2js"
],
"examples": null
},
"FORIN_NOT_ASSIGNABLE": {
"id": "FYQYXB",
"subId": 1,
"categories": [
"Hint"
],
"template": "The element type '#{currentType}' of '#{expressionType}' is not assignable to '#{elementType}'.",
"templateHoleOrder": null,
"howToFix": null,
"options": null,
"usedBy": [
"Platform.dart2js"
],
"examples": [
" main() {\n List<int> list = <int>[1, 2];\n for (String x in list) x;\n }\n "
]
},
"RETURN_OF_INVALID_TYPE": {
"id": "FYQYXB",
"subId": 2,
"categories": [
"StaticTypeWarning"
],
"template": "The return type '#{fromType}' is not a '#{toType}', as defined by the method '#{method}'.",
"templateHoleOrder": null,
"howToFix": null,
"options": null,
"usedBy": [
"Platform.analyzer"
],
"examples": [
"int foo() => 'foo'; main() { foo(); }"
]
},
"ARGUMENT_TYPE_NOT_ASSIGNABLE": {
"id": "FYQYXB",
"subId": 3,
"categories": [
"Hint",
"StaticWarning"
],
"template": "The argument type '#{fromType}' cannot be assigned to the parameter type '#{toType}'.",
"templateHoleOrder": null,
"howToFix": null,
"options": null,
"usedBy": [
"Platform.analyzer"
],
"examples": [
"foo(int x) => x; main() { foo('bar'); }"
]
}
}

View file

@ -77,6 +77,12 @@ class Category {
static final compileTimeError = new Category("CompileTimeError");
static final staticTypeWarning = new Category("StaticTypeWarning");
static final staticWarning = new Category("StaticWarning");
static final hint = new Category("Hint");
final String name;
Category(this.name);
@ -112,7 +118,12 @@ class Message {
/// generic message.
final String specializationOf;
final Category category;
/// The categories of this message.
///
/// The same message can be used in multiple categories, for example, as
/// hint and warning.
final List<Category> categories;
final String template;
// The analyzer fills holes positionally (and not named). The following field
// overrides the order of the holes.
@ -131,7 +142,7 @@ class Message {
{this.id,
this.subId: 0,
this.specializationOf: null,
this.category,
this.categories,
this.template,
this.templateHoleOrder,
this.howToFix,
@ -146,7 +157,8 @@ String get messagesAsJson {
jsonified[name] = {
'id': message.id,
'subId': message.subId,
'category': message.category.name,
'categories':
message.categories.map((category) => category.name).toList(),
'template': message.template,
'templateHoleOrder': message.templateHoleOrder,
'howToFix': message.howToFix,
@ -161,7 +173,7 @@ String get messagesAsJson {
final Map<String, Message> MESSAGES = {
'exampleMessage': new Message(
id: 'use an Id generated by bin/message_id.dart',
category: Category.analysisOptionsError,
categories: [Category.analysisOptionsError],
template: "#use #named #arguments",
templateHoleOrder: ["arguments", "named", "use"],
howToFix: "an explanation on how to fix things",
@ -183,12 +195,10 @@ final Map<String, Message> MESSAGES = {
'CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY': new Message(
id: 'LGJGHW',
subId: 0,
category: Category.parserError,
categories: [Category.parserError],
template: "Const constructor or factory can't have a body.",
howToFix: "Remove the 'const' keyword or the body.",
usedBy: [
dart2js
],
usedBy: [dart2js],
examples: const [
r"""
class C {
@ -208,12 +218,10 @@ final Map<String, Message> MESSAGES = {
id: 'LGJGHW',
subId: 1,
specializationOf: "CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY",
category: Category.parserError,
categories: [Category.parserError],
template: "Const constructor can't have a body.",
howToFix: "Try removing the 'const' keyword or the body.",
usedBy: [
analyzer
],
usedBy: [analyzer],
examples: const [
r"""
class C {
@ -227,14 +235,12 @@ final Map<String, Message> MESSAGES = {
id: 'LGJGHW',
subId: 2,
specializationOf: "CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY",
category: Category.parserError,
categories: [Category.parserError],
template: "Only redirecting factory constructors can be declared to "
"be 'const'.",
howToFix: "Try removing the 'const' keyword or replacing the body with "
"'=' followed by a valid target.",
usedBy: [
analyzer
],
usedBy: [analyzer],
examples: const [
r"""
class C {
@ -247,12 +253,10 @@ final Map<String, Message> MESSAGES = {
'EXTRANEOUS_MODIFIER': new Message(
id: 'GRKIQE',
subId: 0,
category: Category.parserError,
categories: [Category.parserError],
template: "Can't have modifier '#{modifier}' here.",
howToFix: "Try removing '#{modifier}'.",
usedBy: [
dart2js
],
usedBy: [dart2js],
examples: const [
"var String foo; main(){}",
// "var get foo; main(){}",
@ -276,13 +280,11 @@ final Map<String, Message> MESSAGES = {
'EXTRANEOUS_MODIFIER_REPLACE': new Message(
id: 'GRKIQE',
subId: 1,
category: Category.parserError,
categories: [Category.parserError],
template: "Can't have modifier '#{modifier}' here.",
howToFix: "Try replacing modifier '#{modifier}' with 'var', 'final', "
"or a type.",
usedBy: [
dart2js
],
usedBy: [dart2js],
examples: const [
// "get foo; main(){}",
"set foo; main(){}",
@ -297,13 +299,11 @@ final Map<String, Message> MESSAGES = {
// The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
// example below triggers 'EXTRANEOUS_MODIFIER'.
specializationOf: 'EXTRANEOUS_MODIFIER',
category: Category.parserError,
categories: [Category.parserError],
template: "Classes can't be declared to be 'const'",
howToFix: "Try removing the 'const' keyword or moving to the class'"
" constructor(s).",
usedBy: [
analyzer
],
usedBy: [analyzer],
examples: const [
r"""
const class C {}
@ -318,12 +318,10 @@ final Map<String, Message> MESSAGES = {
// The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
// example below triggers 'EXTRANEOUS_MODIFIER'.
specializationOf: 'EXTRANEOUS_MODIFIER',
category: Category.parserError,
categories: [Category.parserError],
template: "Getters, setters and methods can't be declared to be 'const'",
howToFix: "Try removing the 'const' keyword.",
usedBy: [
analyzer
],
usedBy: [analyzer],
examples: const [
"const int foo() => 499; main() {}",
"const int get foo => 499; main() {}",
@ -339,7 +337,7 @@ final Map<String, Message> MESSAGES = {
// The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
// example below triggers 'EXTRANEOUS_MODIFIER'.
specializationOf: 'EXTRANEOUS_MODIFIER',
category: Category.parserError,
categories: [Category.parserError],
template: "Enums can't be declared to be 'const'",
howToFix: "Try removing the 'const' keyword.",
usedBy: [analyzer],
@ -351,7 +349,7 @@ final Map<String, Message> MESSAGES = {
// The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
// example below triggers 'EXTRANEOUS_MODIFIER'.
specializationOf: 'EXTRANEOUS_MODIFIER',
category: Category.parserError,
categories: [Category.parserError],
template: "Type aliases can't be declared to be 'const'",
howToFix: "Try removing the 'const' keyword.",
usedBy: [analyzer],
@ -363,12 +361,10 @@ final Map<String, Message> MESSAGES = {
// The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
// example below triggers 'EXTRANEOUS_MODIFIER'.
specializationOf: 'EXTRANEOUS_MODIFIER',
category: Category.parserError,
categories: [Category.parserError],
template: "Members can't be declared to be both 'const' and 'final'",
howToFix: "Try removing either the 'const' or 'final' keyword.",
usedBy: [
analyzer
],
usedBy: [analyzer],
examples: const [
"final const int x = 499; main() {}",
"const final int x = 499; main() {}",
@ -382,12 +378,10 @@ final Map<String, Message> MESSAGES = {
// The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
// example below triggers 'EXTRANEOUS_MODIFIER'.
specializationOf: 'EXTRANEOUS_MODIFIER',
category: Category.parserError,
categories: [Category.parserError],
template: "Members can't be declared to be both 'const' and 'var'",
howToFix: "Try removing either the 'const' or 'var' keyword.",
usedBy: [
analyzer
],
usedBy: [analyzer],
examples: const [
"var const x = 499; main() {}",
"const var x = 499; main() {}",
@ -399,7 +393,7 @@ final Map<String, Message> MESSAGES = {
// Dart2js currently reports this as an EXTRANEOUS_MODIFIER error.
// TODO(floitsch): make dart2js use this error instead.
id: 'DOTHQH',
category: Category.parserError,
categories: [Category.parserError],
template: "Classes can't be declared inside other classes.",
howToFix: "Try moving the class to the top-level.",
usedBy: [analyzer],
@ -407,7 +401,7 @@ final Map<String, Message> MESSAGES = {
'CONSTRUCTOR_WITH_RETURN_TYPE': new Message(
id: 'VOJBWY',
category: Category.parserError,
categories: [Category.parserError],
template: "Constructors can't have a return type",
howToFix: "Try removing the return type.",
usedBy: [analyzer, dart2js],
@ -416,13 +410,10 @@ final Map<String, Message> MESSAGES = {
'MISSING_EXPRESSION_IN_THROW': new Message(
id: 'FTGGMJ',
subId: 0,
category: Category.parserError,
categories: [Category.parserError],
template: "Missing expression after 'throw'.",
howToFix: "Did you mean 'rethrow'?",
usedBy: [
analyzer,
dart2js
],
usedBy: [analyzer, dart2js],
examples: const [
'main() { throw; }',
'main() { try { throw 0; } catch(e) { throw; } }'
@ -434,7 +425,7 @@ final Map<String, Message> MESSAGES = {
*/
'RETHROW_OUTSIDE_CATCH': new Message(
id: 'MWETLC',
category: Category.compileTimeError,
categories: [Category.compileTimeError],
template: 'Rethrow must be inside of catch clause',
howToFix: "Try moving the expression into a catch clause, or "
"using a 'throw' expression.",
@ -447,14 +438,11 @@ final Map<String, Message> MESSAGES = {
*/
'RETURN_IN_GENERATIVE_CONSTRUCTOR': new Message(
id: 'UOTDQH',
category: Category.compileTimeError,
categories: [Category.compileTimeError],
template: "Constructors can't return values.",
howToFix:
"Try removing the return statement or using a factory constructor.",
usedBy: [
analyzer,
dart2js
],
usedBy: [analyzer, dart2js],
examples: const [
"""
class C {
@ -473,15 +461,12 @@ final Map<String, Message> MESSAGES = {
'RETURN_IN_GENERATOR': new Message(
id: 'JRUTUQ',
subId: 0,
category: Category.compileTimeError,
categories: [Category.compileTimeError],
template: "Can't return a value from a generator function "
"(using the '#{modifier}' modifier).",
howToFix: "Try removing the value, replacing 'return' with 'yield' or"
" changing the method body modifier",
usedBy: [
analyzer,
dart2js
],
usedBy: [analyzer, dart2js],
examples: const [
"""
foo() async* { return 0; }
@ -492,4 +477,79 @@ final Map<String, Message> MESSAGES = {
main() => foo();
"""
]),
'NOT_ASSIGNABLE': new Message(
id: 'FYQYXB',
subId: 0,
categories: [Category.staticTypeWarning],
template: "'#{fromType}' is not assignable to '#{toType}'.",
usedBy: [dart2js]),
'FORIN_NOT_ASSIGNABLE': new Message(
id: 'FYQYXB',
subId: 1,
categories: [Category.hint],
template: "The element type '#{currentType}' of '#{expressionType}' "
"is not assignable to '#{elementType}'.",
usedBy: [dart2js],
examples: const [
"""
main() {
List<int> list = <int>[1, 2];
for (String x in list) x;
}
"""
]),
/**
* 13.11 Return: It is a static type warning if the type of <i>e</i> may not
* be assigned to the declared return type of the immediately enclosing
* function.
*/
'RETURN_OF_INVALID_TYPE': new Message(
id: 'FYQYXB',
subId: 2,
specializationOf: 'NOT_ASSIGNABLE',
categories: [Category.staticTypeWarning],
template: "The return type '#{fromType}' is not a '#{toType}', as "
"defined by the method '#{method}'.",
usedBy: [analyzer],
examples: const ["int foo() => 'foo'; main() { foo(); }"]),
/**
* 12.11.1 New: It is a static warning if the static type of <i>a<sub>i</sub>,
* 1 &lt;= i &lt;= n+ k</i> may not be assigned to the type of the
* corresponding formal parameter of the constructor <i>T.id</i> (respectively
* <i>T</i>).
*
* 12.11.2 Const: It is a static warning if the static type of
* <i>a<sub>i</sub>, 1 &lt;= i &lt;= n+ k</i> may not be assigned to the type
* of the corresponding formal parameter of the constructor <i>T.id</i>
* (respectively <i>T</i>).
*
* 12.14.2 Binding Actuals to Formals: Let <i>T<sub>i</sub></i> be the static
* type of <i>a<sub>i</sub></i>, let <i>S<sub>i</sub></i> be the type of
* <i>p<sub>i</sub>, 1 &lt;= i &lt;= n+k</i> and let <i>S<sub>q</sub></i> be
* the type of the named parameter <i>q</i> of <i>f</i>. It is a static
* warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1
* &lt;= j &lt;= m</i>.
*
* 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub>, 1
* &lt;= i &lt;= l</i>, must have a corresponding named parameter in the set
* <i>{p<sub>n+1</sub>, &hellip; p<sub>n+k</sub>}</i> or a static warning
* occurs. It is a static warning if <i>T<sub>m+j</sub></i> may not be
* assigned to <i>S<sub>r</sub></i>, where <i>r = q<sub>j</sub>, 1 &lt;= j
* &lt;= l</i>.
*/
'ARGUMENT_TYPE_NOT_ASSIGNABLE': new Message(
id: 'FYQYXB',
subId: 3,
specializationOf: 'NOT_ASSIGNABLE',
categories: [Category.hint, Category.staticWarning],
template: "The argument type '#{fromType}' cannot be assigned to the "
"parameter type '#{toType}'.",
usedBy: [analyzer],
// TODO(floitsch): support hint warnings and ways to specify which
// category an example should trigger for.
examples: const ["foo(int x) => x; main() { foo('bar'); }"]),
};