Fix compile error when using dart_style with analyzer 6.2.0. (#1414)

Fix #1413.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 35f27ae..ec434c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,6 @@
-## 2.3.6-wip
+## 2.3.6
 
-There are no user-visible changes in this release. The only changes are behind
-the `tall-style` experiment flag.
+* Fix compile error when using dart_style with analyzer 6.2.0.
 
 ## 2.3.5
 
diff --git a/lib/src/ast_extensions.dart b/lib/src/ast_extensions.dart
index 19cfb7b..f0f5bbb 100644
--- a/lib/src/ast_extensions.dart
+++ b/lib/src/ast_extensions.dart
@@ -409,3 +409,25 @@
         _ => false,
       };
 }
+
+// TODO(rnystrom): This is a gross hack because dart_style 2.3.5 has a bad
+// analyzer constraint which allows dart_style to be used with a version of
+// analyzer that doesn't publicly expose the `.macroKeyword` getter.
+// Fortunately, the oldest analyzer that dart_style allows *does* have the
+// getter on the ClassDeclarationImpl class.
+//
+// To get users off that bad version, we're publishing a new version of
+// dart_style that has the same constraint and gracefully handles that getter
+// not statically being visible.
+//
+// This hack will be removed immediately after publishing a version with that
+// fix.
+extension ClassDeclarationExtensions on ClassDeclaration {
+  /// If the [ClassDeclaration] is from a version of analyzer that has the
+  /// `macroKeyword` getter and the class has a `macro` keyword, returns that
+  /// token.
+  ///
+  /// Otherwise, returns `null`.
+  Token? get hackMacroKeywordForOlderAnalyzer =>
+      (this as dynamic).macroKeyword as Token?;
+}
diff --git a/lib/src/cli/formatter_options.dart b/lib/src/cli/formatter_options.dart
index 826f8fb..ff0e658 100644
--- a/lib/src/cli/formatter_options.dart
+++ b/lib/src/cli/formatter_options.dart
@@ -11,7 +11,7 @@
 import 'summary.dart';
 
 // Note: The following line of code is modified by tool/grind.dart.
-const dartStyleVersion = '2.3.5';
+const dartStyleVersion = '2.3.6';
 
 /// Global options that affect how the formatter produces and uses its outputs.
 class FormatterOptions {
diff --git a/lib/src/front_end/ast_node_visitor.dart b/lib/src/front_end/ast_node_visitor.dart
index 099bf4f..d80a403 100644
--- a/lib/src/front_end/ast_node_visitor.dart
+++ b/lib/src/front_end/ast_node_visitor.dart
@@ -248,7 +248,7 @@
           node.interfaceKeyword,
           node.finalKeyword,
           node.sealedKeyword,
-          node.macroKeyword,
+          node.hackMacroKeywordForOlderAnalyzer,
           node.mixinKeyword,
           node.classKeyword,
         ],
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 7d47980..c306981 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -592,7 +592,7 @@
     modifier(node.finalKeyword);
     modifier(node.sealedKeyword);
     modifier(node.mixinKeyword);
-    modifier(node.macroKeyword);
+    modifier(node.hackMacroKeywordForOlderAnalyzer);
     token(node.classKeyword);
     space();
     token(node.name);
diff --git a/pubspec.yaml b/pubspec.yaml
index be4f69c..a262a83 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: dart_style
 # Note: See tool/grind.dart for how to bump the version.
-version: 2.3.6-wip
+version: 2.3.6
 description: >-
   Opinionated, automatic Dart source code formatter.
   Provides an API and a CLI tool.