blob: 949a4c4af99df0a21159e59d40fee27dc7797e7f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/expr/identifier_glob.h"
#include "src/developer/debug/zxdb/expr/expr_parser.h"
namespace zxdb {
namespace {
// Matches the template parameters of one component. Return value is the same as
// IdentifierGlob::Matches.
std::optional<int> MatchTemplateParams(const std::vector<std::string>& glob,
const std::vector<std::string>& type) {
if (type.size() < glob.size())
return std::nullopt; // Glob trying to match more parameters than the type has.
int last_score = 0;
for (size_t i = 0; i < glob.size(); i++) {
if (glob[i] == "*") {
if (i == glob.size() - 1) {
// Last glob "*" matches all remaining type parameters.
last_score = static_cast<int>(type.size()) - i;
break;
} else {
last_score = 1;
}
} else {
// Non-wildcards must be an exact match.
if (glob[i] != type[i])
return std::nullopt;
// Last glob template was not a whilecard, and there are still more type params to match.
if (i == glob.size() - 1 && type.size() > glob.size())
return std::nullopt;
}
}
return last_score;
}
} // namespace
Err IdentifierGlob::Init(const std::string& glob) {
return ExprParser::ParseIdentifier(glob, &parsed_);
}
std::optional<int> IdentifierGlob::Matches(const ParsedIdentifier& type) const {
if (type.components().size() != parsed_.components().size())
return std::nullopt;
int max_component_score = 0;
for (size_t i = 0; i < type.components().size(); i++) {
// The name must match exactly.
if (parsed_.components()[i].name() != type.components()[i].name() ||
parsed_.components()[i].has_template() != type.components()[i].has_template())
return std::nullopt;
if (parsed_.components()[i].has_template()) {
// Check template parameters.
if (auto score = MatchTemplateParams(parsed_.components()[i].template_contents(),
type.components()[i].template_contents())) {
// Want the largest score.
if (*score > max_component_score)
max_component_score = *score;
} else {
return std::nullopt; // Template params don't match.
}
}
}
return max_component_score;
}
} // namespace zxdb