Version 2.14.0-90.0.dev

Merge commit '484c999f129aacedc6c568d865450c98e4967fbd' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_for_loop.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_for_loop.dart
new file mode 100644
index 0000000..0481730
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_for_loop.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertForEachToForLoop extends CorrectionProducer {
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_FOR_EACH_TO_FOR_LOOP;
+
+  @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_FOR_EACH_TO_FOR_LOOP_MULTI;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var invocation = node.parent;
+    if (invocation is! MethodInvocation) {
+      return;
+    }
+    var statement = invocation.parent;
+    if (statement is! ExpressionStatement) {
+      return;
+    }
+    var argument = invocation.argumentList.arguments[0];
+    if (argument is! FunctionExpression) {
+      return;
+    }
+    var parameters = argument.parameters?.parameters;
+    if (parameters == null || parameters.length != 1) {
+      return;
+    }
+    var parameter = parameters[0];
+    if (parameter is! NormalFormalParameter) {
+      return;
+    }
+    var loopVariableName = parameter.identifier?.name;
+    if (loopVariableName == null) {
+      return;
+    }
+    var target = utils.getNodeText(invocation.target!);
+    var body = argument.body;
+    if (body is BlockFunctionBody) {
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addReplacement(range.startStart(invocation, body), (builder) {
+          builder.write('for (var ');
+          builder.write(loopVariableName);
+          builder.write(' in ');
+          builder.write(target);
+          builder.write(') ');
+        });
+        builder.addDeletion(range.endEnd(body, statement));
+      });
+    } else if (body is ExpressionFunctionBody) {
+      await builder.addDartFileEdit(file, (builder) {
+        var expression = body.expression;
+        var prefix = utils.getPrefix(statement.offset);
+        builder.addReplacement(range.startStart(invocation, expression),
+            (builder) {
+          builder.write('for (var ');
+          builder.write(loopVariableName);
+          builder.write(' in ');
+          builder.write(target);
+          builder.writeln(') {');
+          builder.write(prefix);
+          builder.write('  ');
+        });
+        builder.addReplacement(range.endEnd(expression, statement), (builder) {
+          builder.writeln(';');
+          builder.write(prefix);
+          builder.write('}');
+        });
+      });
+    }
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertForEachToForLoop newInstance() => ConvertForEachToForLoop();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 041bda6..7bb4b16 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -257,6 +257,14 @@
       'dart.fix.flutter.convert.childrenToChild',
       DartFixKindPriority.DEFAULT,
       'Convert to child:');
+  static const CONVERT_FOR_EACH_TO_FOR_LOOP = FixKind(
+      'dart.fix.convert.toForLoop',
+      DartFixKindPriority.DEFAULT,
+      "Convert 'forEach' to a 'for' loop");
+  static const CONVERT_FOR_EACH_TO_FOR_LOOP_MULTI = FixKind(
+      'dart.fix.convert.toForLoop.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert 'forEach' to a 'for' loop everywhere in file");
   static const CONVERT_INTO_EXPRESSION_BODY = FixKind(
       'dart.fix.convert.toExpressionBody',
       DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 3b6bbe8..23e1d41 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -43,6 +43,7 @@
 import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_contains.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_expression_function_body.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_for_loop.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_if_null.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
@@ -452,6 +453,15 @@
         ],
       )
     ],
+    LintNames.avoid_function_literals_in_foreach_calls: [
+      FixInfo(
+        canBeAppliedToFile: true,
+        canBeBulkApplied: true,
+        generators: [
+          ConvertForEachToForLoop.newInstance,
+        ],
+      )
+    ],
     LintNames.avoid_init_to_null: [
       FixInfo(
         canBeAppliedToFile: true,
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index cc4823f..4f9fd95 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -13,6 +13,8 @@
   static const String avoid_annotating_with_dynamic =
       'avoid_annotating_with_dynamic';
   static const String avoid_empty_else = 'avoid_empty_else';
+  static const String avoid_function_literals_in_foreach_calls =
+      'avoid_function_literals_in_foreach_calls';
   static const String avoid_init_to_null = 'avoid_init_to_null';
   static const String avoid_private_typedef_functions =
       'avoid_private_typedef_functions';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_for_each_to_for_loop_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_for_each_to_for_loop_test.dart
new file mode 100644
index 0000000..2514ae0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_for_each_to_for_loop_test.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertForEachToForLoop);
+  });
+}
+
+@reflectiveTest
+class ConvertForEachToForLoop extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.avoid_function_literals_in_foreach_calls;
+
+  Future<void> test_blockBody_blockBody() async {
+    await resolveTestCode(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  a.forEach((ea) {
+    b.forEach((eb) {
+      result.add('$ea $eb');
+    });
+  });
+}
+''');
+    await assertHasFix(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  for (var ea in a) {
+    for (var eb in b) {
+      result.add('$ea $eb');
+    }
+  }
+}
+''');
+  }
+
+  Future<void> test_blockBody_expressionBody() async {
+    await resolveTestCode(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  a.forEach((ea) {
+    b.forEach((eb) => result.add('$ea $eb'));
+  });
+}
+''');
+    await assertHasFix(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  for (var ea in a) {
+    for (var eb in b) {
+      result.add('$ea $eb');
+    }
+  }
+}
+''');
+  }
+
+  Future<void> test_expressionBody_blockBody() async {
+    await resolveTestCode(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  a.forEach((ea) => b.forEach((eb) {
+      result.add('$ea $eb');
+    }));
+}
+''');
+    await assertHasFix(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  for (var ea in a) {
+    b.forEach((eb) {
+      result.add('$ea $eb');
+    });
+  }
+}
+''');
+  }
+
+  Future<void> test_expressionBody_expressionBody() async {
+    await resolveTestCode(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  a.forEach((ea) => b.forEach((eb) => result.add('$ea $eb')));
+}
+''');
+    await assertHasFix(r'''
+void f(List<String> a, List<String> b) {
+  var result = <String>[];
+  for (var ea in a) {
+    b.forEach((eb) => result.add('$ea $eb'));
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 6b8bb68..a90e17f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -13,6 +13,7 @@
 import 'bulk_fix_processor_test.dart' as bulk_fix_processor;
 import 'convert_documentation_into_line_test.dart'
     as convert_documentation_into_line;
+import 'convert_for_each_to_for_loop_test.dart' as convert_for_each_to_for_loop;
 import 'convert_map_from_iterable_to_for_literal_test.dart'
     as convert_map_from_iterable_to_for_literal;
 import 'convert_to_contains_test.dart' as convert_to_contains;
@@ -82,6 +83,7 @@
     add_required.main();
     bulk_fix_processor.main();
     convert_documentation_into_line.main();
+    convert_for_each_to_for_loop.main();
     convert_map_from_iterable_to_for_literal.main();
     convert_to_contains.main();
     convert_to_generic_function_syntax.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
new file mode 100644
index 0000000..b8d2fbd
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertForEachToForLoopTest);
+  });
+}
+
+@reflectiveTest
+class ConvertForEachToForLoopTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_FOR_EACH_TO_FOR_LOOP;
+
+  @override
+  String get lintCode => LintNames.avoid_function_literals_in_foreach_calls;
+
+  Future<void> test_blockBody() async {
+    await resolveTestCode('''
+void f(List<String> list) {
+  list.forEach((e) {
+    e.length / 2;
+  });
+}
+''');
+    await assertHasFix('''
+void f(List<String> list) {
+  for (var e in list) {
+    e.length / 2;
+  }
+}
+''');
+  }
+
+  Future<void> test_expressionBody() async {
+    await resolveTestCode('''
+void f(List<String> list) {
+  list.forEach((e) => e.substring(3, 7));
+}
+''');
+    await assertHasFix('''
+void f(List<String> list) {
+  for (var e in list) {
+    e.substring(3, 7);
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 570d7a8..e520510 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -43,6 +43,7 @@
     as convert_documentation_into_line;
 import 'convert_flutter_child_test.dart' as convert_flutter_child;
 import 'convert_flutter_children_test.dart' as convert_flutter_children;
+import 'convert_for_each_to_for_loop_test.dart' as convert_for_each_to_for_loop;
 import 'convert_into_expression_body_test.dart' as convert_into_expression_body;
 import 'convert_to_contains_test.dart' as convert_to_contains;
 import 'convert_to_for_element_test.dart' as convert_to_for_element;
@@ -211,6 +212,7 @@
     convert_documentation_into_line.main();
     convert_flutter_child.main();
     convert_flutter_children.main();
+    convert_for_each_to_for_loop.main();
     convert_into_expression_body.main();
     convert_to_contains.main();
     convert_to_for_element.main();
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 996f87c..037ae47 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -2642,14 +2642,37 @@
     }
 
     var nameExpr = _emitTopLevelName(p);
+    var jsName = _safeFunctionNameForSafari(p.name.text, fn);
     body.add(js.statement('# = #',
-        [nameExpr, js_ast.NamedFunction(_emitTemporaryId(p.name.text), fn)]));
+        [nameExpr, js_ast.NamedFunction(_emitTemporaryId(jsName), fn)]));
 
     _currentUri = savedUri;
     _staticTypeContext.leaveMember(p);
     return js_ast.Statement.from(body);
   }
 
+  /// Choose a safe name for [fn].
+  ///
+  /// Most of the time we use [candidateName], except if the name collides
+  /// with a parameter name and the function contains default parameter values.
+  ///
+  /// In ES6, functions containing default parameter values, which DDC
+  /// generates when Dart uses positional optional parameters, cannot have
+  /// two parameters with the same name. Because we have a similar restriction
+  /// in Dart, this is not normally an issue we need to pay attention to.
+  /// However, a bug in Safari makes it a syntax error to have the function
+  /// name overlap with the parameter names as well. This rename works around
+  /// such bug (dartbug.com/43520).
+  static String _safeFunctionNameForSafari(
+      String candidateName, js_ast.Fun fn) {
+    if (fn.params.any((p) => p is js_ast.DestructuredVariable)) {
+      while (fn.params.any((a) => a.parameterName == candidateName)) {
+        candidateName = '$candidateName\$';
+      }
+    }
+    return candidateName;
+  }
+
   js_ast.Expression _emitFunctionTagged(js_ast.Expression fn, FunctionType type,
       {bool topLevel = false}) {
     var lazy = topLevel && !_canEmitTypeAtTopLevel(type);
diff --git a/runtime/observatory/tests/service/notify_debugger_on_exception_yielding_test.dart b/runtime/observatory/tests/service/notify_debugger_on_exception_yielding_test.dart
new file mode 100644
index 0000000..1cab6a7
--- /dev/null
+++ b/runtime/observatory/tests/service/notify_debugger_on_exception_yielding_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--verbose_debug
+
+// See: https://github.com/dart-lang/sdk/issues/45673
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE_A = 19;
+const int LINE_B = 29;
+const int LINE_C = 39;
+
+@pragma('vm:notify-debugger-on-exception')
+Future<void> throwFromAsync() async {
+  try {
+    throw 'Throw from throwFromAsync'; // LINE_A
+  } catch (e) {
+    // Ignore. Internals will notify debugger.
+  }
+  return Future.value();
+}
+
+@pragma('vm:notify-debugger-on-exception')
+Stream<int> throwFromAsyncStar() async* {
+  try {
+    throw 'Throw from throwFromAsyncStar'; // LINE_B
+  } catch (e) {
+    // Ignore. Internals will notify debugger.
+  }
+  yield 13;
+}
+
+@pragma('vm:notify-debugger-on-exception')
+Iterable<int> throwFromSyncStar() sync* {
+  try {
+    throw 'Throw from throwFromSyncStar'; // LINE_C
+  } catch (e) {
+    // Ignore. Internals will notify debugger.
+  }
+  yield 7;
+}
+
+testMain() async {
+  throwFromAsync();
+  await for (var e in throwFromAsyncStar()) {/*ignore*/}
+  for (var e in throwFromSyncStar()) {/*ignore*/}
+}
+
+final tests = <IsolateTest>[
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_A),
+  resumeIsolate,
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_B),
+  resumeIsolate,
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_C),
+];
+
+main([args = const <String>[]]) => runIsolateTests(args, tests,
+    testeeConcurrent: testMain, pause_on_unhandled_exceptions: true);
diff --git a/runtime/observatory_2/tests/service_2/notify_debugger_on_exception_yielding_test.dart b/runtime/observatory_2/tests/service_2/notify_debugger_on_exception_yielding_test.dart
new file mode 100644
index 0000000..1cab6a7
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/notify_debugger_on_exception_yielding_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--verbose_debug
+
+// See: https://github.com/dart-lang/sdk/issues/45673
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE_A = 19;
+const int LINE_B = 29;
+const int LINE_C = 39;
+
+@pragma('vm:notify-debugger-on-exception')
+Future<void> throwFromAsync() async {
+  try {
+    throw 'Throw from throwFromAsync'; // LINE_A
+  } catch (e) {
+    // Ignore. Internals will notify debugger.
+  }
+  return Future.value();
+}
+
+@pragma('vm:notify-debugger-on-exception')
+Stream<int> throwFromAsyncStar() async* {
+  try {
+    throw 'Throw from throwFromAsyncStar'; // LINE_B
+  } catch (e) {
+    // Ignore. Internals will notify debugger.
+  }
+  yield 13;
+}
+
+@pragma('vm:notify-debugger-on-exception')
+Iterable<int> throwFromSyncStar() sync* {
+  try {
+    throw 'Throw from throwFromSyncStar'; // LINE_C
+  } catch (e) {
+    // Ignore. Internals will notify debugger.
+  }
+  yield 7;
+}
+
+testMain() async {
+  throwFromAsync();
+  await for (var e in throwFromAsyncStar()) {/*ignore*/}
+  for (var e in throwFromSyncStar()) {/*ignore*/}
+}
+
+final tests = <IsolateTest>[
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_A),
+  resumeIsolate,
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_B),
+  resumeIsolate,
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_C),
+];
+
+main([args = const <String>[]]) => runIsolateTests(args, tests,
+    testeeConcurrent: testMain, pause_on_unhandled_exceptions: true);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index dc9d048..0f18a47 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -2248,11 +2248,27 @@
     // it will be caught once we unwind the stack.
     return true;
   }
+
+  auto& handler_function = Function::Handle(handler_frame->function().ptr());
+  // If the handler function is an synthetic inner function, we need to look for
+  // the annotations on the outer function.
+  if (handler_function.IsAsyncClosure()) {
+    // async :async_op
+    handler_function = handler_function.parent_function();
+  } else if (handler_frame->function().IsAsyncGenClosure()) {
+    // async* :async_op
+    handler_function = handler_function.parent_function();
+  } else if (handler_frame->function().IsSyncGenClosure()) {
+    // sync* :sync_op + :sync_op_gen
+    handler_function = handler_function.parent_function();
+    handler_function = handler_function.parent_function();
+  }
+
   // If handler_frame's function is annotated with
   // @pragma('vm:notify-debugger-on-exception'), we specifically want to notify
   // the debugger of this otherwise ignored exception.
   if (Library::FindPragma(Thread::Current(), /*only_core=*/false,
-                          handler_frame->function(),
+                          handler_function,
                           Symbols::vm_notify_debugger_on_exception())) {
     return true;
   }
diff --git a/tests/web/regress/43520_safari_test.dart b/tests/web/regress/43520_safari_test.dart
new file mode 100644
index 0000000..2dee2bb
--- /dev/null
+++ b/tests/web/regress/43520_safari_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Regression test for dartbug.com/43520.
+///
+/// Safari has a bug that makes it a syntax error for a function name to overlap
+/// with names of parameters in functions with default parameter values.
+///
+/// DDC now generates code to circumvent this issue.
+
+import 'package:expect/expect.dart';
+
+String a(Object a, [String f = '3']) {
+  return "$a$f";
+}
+
+main() async {
+  Expect.equals('13', a(1));
+}
diff --git a/tests/web_2/regress/43520_safari_test.dart b/tests/web_2/regress/43520_safari_test.dart
new file mode 100644
index 0000000..2dee2bb
--- /dev/null
+++ b/tests/web_2/regress/43520_safari_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Regression test for dartbug.com/43520.
+///
+/// Safari has a bug that makes it a syntax error for a function name to overlap
+/// with names of parameters in functions with default parameter values.
+///
+/// DDC now generates code to circumvent this issue.
+
+import 'package:expect/expect.dart';
+
+String a(Object a, [String f = '3']) {
+  return "$a$f";
+}
+
+main() async {
+  Expect.equals('13', a(1));
+}
diff --git a/tools/VERSION b/tools/VERSION
index 6ae49c3..ed6e679 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 89
+PRERELEASE 90
 PRERELEASE_PATCH 0
\ No newline at end of file