Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/ast.cc
Line
Count
Source
1
// Copyright 2022 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "common/ast.h"
16
17
#include <cstdint>
18
19
#include "absl/base/no_destructor.h"
20
#include "absl/base/nullability.h"
21
#include "common/ast/metadata.h"
22
#include "common/source.h"
23
24
namespace cel {
25
namespace {
26
27
0
const TypeSpec& DynSingleton() {
28
0
  static absl::NoDestructor<TypeSpec> singleton{TypeSpecKind(DynTypeSpec())};
29
0
  return *singleton;
30
0
}
31
32
}  // namespace
33
34
0
const TypeSpec* absl_nullable Ast::GetType(int64_t expr_id) const {
35
0
  auto iter = type_map_.find(expr_id);
36
0
  if (iter == type_map_.end()) {
37
0
    return nullptr;
38
0
  }
39
0
  return &iter->second;
40
0
}
41
42
0
const TypeSpec& Ast::GetTypeOrDyn(int64_t expr_id) const {
43
0
  if (const TypeSpec* type = GetType(expr_id); type != nullptr) {
44
0
    return *type;
45
0
  }
46
0
  return DynSingleton();
47
0
}
48
49
0
const TypeSpec& Ast::GetReturnType() const {
50
0
  return GetTypeOrDyn(root_expr().id());
51
0
}
52
53
0
const Reference* absl_nullable Ast::GetReference(int64_t expr_id) const {
54
0
  auto iter = reference_map_.find(expr_id);
55
0
  if (iter == reference_map_.end()) {
56
0
    return nullptr;
57
0
  }
58
0
  return &iter->second;
59
0
}
60
61
0
SourceLocation Ast::ComputeSourceLocation(int64_t expr_id) const {
62
0
  const auto& source_info = this->source_info();
63
0
  auto iter = source_info.positions().find(expr_id);
64
0
  if (iter == source_info.positions().end()) {
65
0
    return SourceLocation{};
66
0
  }
67
0
  int32_t absolute_position = iter->second;
68
0
  if (absolute_position < 0) {
69
0
    return SourceLocation{};
70
0
  }
71
72
  // Find the first line offset that is greater than the absolute position.
73
0
  int32_t line_idx = -1;
74
0
  int32_t offset = 0;
75
0
  for (int32_t i = 0; i < source_info.line_offsets().size(); ++i) {
76
0
    int32_t next_offset = source_info.line_offsets()[i];
77
0
    if (next_offset <= offset) {
78
      // Line offset is not monotonically increasing, so line information is
79
      // invalid.
80
0
      return SourceLocation{};
81
0
    }
82
0
    if (absolute_position < next_offset) {
83
0
      line_idx = i;
84
0
      break;
85
0
    }
86
0
    offset = next_offset;
87
0
  }
88
89
0
  if (line_idx < 0 || line_idx >= source_info.line_offsets().size()) {
90
0
    return SourceLocation{};
91
0
  }
92
93
0
  int32_t rel_position = absolute_position - offset;
94
95
0
  return SourceLocation{line_idx + 1, rel_position};
96
0
}
97
98
}  // namespace cel