[analysis_server] Tweak handling of factory keyword without type names in constructors

Change-Id: I4d162ef66300caa07fd64f7de338c6ed1df04fc1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/481963
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Danny Tuppeny
2026-02-19 13:13:10 -08:00
committed by Commit Queue
parent a484bb3973
commit f06562cbda
3 changed files with 63 additions and 1 deletions
@@ -917,6 +917,16 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
computer._addRegion_token(
node.factoryKeyword,
HighlightRegionType.BUILT_IN,
// We mark the factory keyword as the declaration when there is no
// type name (otherwise the type name is the declaration). This will allow
// the client/user to customise these differently if they wish, like they
// can with methods / constructors.
semanticTokenModifiers: node.typeName != null
? null
: {
CustomSemanticTokenModifiers.constructor,
SemanticTokenModifiers.declaration,
},
);
computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(
@@ -689,6 +689,25 @@ Never nnn() => throw '';
assertHasRegion(HighlightRegionType.CLASS, 'Never nnn');
}
Future<void> test_class_constructor_factoryKeyword() async {
var testCode = TestCode.parseNormalized(r'''
class A {
A._();
[!
factory () {}
factory named() {}
!]
}
''');
addTestFile(testCode.code);
await prepareHighlights();
assertHighlightText(testCode, 0, r'''
4:3 |factory| BUILT_IN
5:3 |factory| BUILT_IN
5:11 |named| CONSTRUCTOR
''');
}
Future<void> test_class_constructor_fieldFormalParameter() async {
var testCode = TestCode.parseNormalized(r'''
class A {
@@ -710,7 +729,7 @@ class A {
''');
}
Future<void> test_class_constructor_new() async {
Future<void> test_class_constructor_newKeyword() async {
var testCode = TestCode.parseNormalized(r'''
class A {
[!
@@ -550,6 +550,39 @@ const e = const MyClass();
await _initializeAndVerifyTokens(content, expected);
}
Future<void> test_class_constructors_factoryKeyword() async {
var content = r'''
class A {
A._();
[!
factory() => A._();
factory named() => A._();
!]
}
''';
var expected = [
_Token('factory', .keyword, [
CustomSemanticTokenModifiers.constructor,
.declaration,
]),
_Token('A', .class_, [CustomSemanticTokenModifiers.constructor]),
_Token('_', .method, [CustomSemanticTokenModifiers.constructor]),
_Token('factory', .keyword, [
CustomSemanticTokenModifiers.constructor,
.declaration,
]),
_Token('named', .method, [
CustomSemanticTokenModifiers.constructor,
.declaration,
]),
_Token('A', .class_, [CustomSemanticTokenModifiers.constructor]),
_Token('_', .method, [CustomSemanticTokenModifiers.constructor]),
];
await _initializeAndVerifyTokensInRange(content, expected);
}
Future<void> test_class_constructors_newKeyword() async {
var content = r'''
class A {