blob: b9b03131a14ddd36785c7f31eb4d3a27a55a15f0 [file] [log] [blame]
// Copyright (c) 2023, 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/completion/dart/candidate_suggestion.dart';
import 'package:analysis_server/src/services/completion/dart/completion_state.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_collector.dart';
import 'package:analyzer/dart/ast/ast.dart';
/// A helper class that produces candidate suggestions for all of the labels
/// that are in scope at the completion location.
class LabelHelper {
/// The suggestion collector to which suggestions will be added.
final SuggestionCollector collector;
/// The state used to compute the candidate suggestions.
final CompletionState state;
/// Initialize a newly created helper to add suggestions to the [collector].
LabelHelper({required this.collector, required this.state});
/// Add the labels that are visible at the `break` or `continue` [statement].
void addLabels(Statement statement) {
var includeCaseLabels = statement is ContinueStatement;
AstNode? currentNode = statement;
while (currentNode != null) {
switch (currentNode) {
case SwitchStatement():
if (includeCaseLabels) {
for (var member in currentNode.members) {
_visitLabels(member.labels);
}
}
case FunctionBody():
return;
case LabeledStatement():
_visitLabels(currentNode.labels);
}
currentNode = currentNode.parent;
}
}
void _visitLabels(NodeList<Label> labels) {
for (var label in labels) {
var matcherScore = state.matcher.score(label.label.name);
if (matcherScore != -1) {
var suggestion =
LabelSuggestion(label: label, matcherScore: matcherScore);
collector.addSuggestion(suggestion);
}
}
}
}