1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/torque/kythe-data.h"
6
7 namespace v8 {
8 namespace internal {
9 namespace torque {
10
11 DEFINE_CONTEXTUAL_VARIABLE(KytheData)
12
13 namespace {
14
MakeKythePosition(const SourcePosition & pos)15 KythePosition MakeKythePosition(const SourcePosition& pos) {
16 KythePosition p;
17 if (pos.source.IsValid()) {
18 p.file_path = SourceFileMap::PathFromV8Root(pos.source);
19 } else {
20 p.file_path = "UNKNOWN";
21 }
22 p.start_offset = pos.start.offset;
23 p.end_offset = pos.end.offset;
24 return p;
25 }
26
27 } // namespace
28
29 // Constants
AddConstantDefinition(const Value * constant)30 kythe_entity_t KytheData::AddConstantDefinition(const Value* constant) {
31 DCHECK(constant->IsNamespaceConstant() || constant->IsExternConstant());
32 KytheData* that = &KytheData::Get();
33 // Check if we know the constant already.
34 auto it = that->constants_.find(constant);
35 if (it != that->constants_.end()) return it->second;
36
37 // Register this constant.
38 KythePosition pos = MakeKythePosition(constant->name()->pos);
39 kythe_entity_t constant_id = that->consumer_->AddDefinition(
40 KytheConsumer::Kind::Constant, constant->name()->value, pos);
41 that->constants_.insert(it, std::make_pair(constant, constant_id));
42 return constant_id;
43 }
44
AddConstantUse(SourcePosition use_position,const Value * constant)45 void KytheData::AddConstantUse(SourcePosition use_position,
46 const Value* constant) {
47 DCHECK(constant->IsNamespaceConstant() || constant->IsExternConstant());
48 KytheData* that = &Get();
49 kythe_entity_t constant_id = AddConstantDefinition(constant);
50 KythePosition use_pos = MakeKythePosition(use_position);
51 that->consumer_->AddUse(KytheConsumer::Kind::Constant, constant_id, use_pos);
52 }
53
54 // Callables
AddFunctionDefinition(Callable * callable)55 kythe_entity_t KytheData::AddFunctionDefinition(Callable* callable) {
56 KytheData* that = &KytheData::Get();
57 // Check if we know the caller already.
58 auto it = that->callables_.find(callable);
59 if (it != that->callables_.end()) return it->second;
60
61 // Register this callable.
62 auto ident_pos = callable->IdentifierPosition();
63 kythe_entity_t callable_id = that->consumer_->AddDefinition(
64 KytheConsumer::Kind::Function, callable->ExternalName(),
65 MakeKythePosition(ident_pos));
66 that->callables_.insert(it, std::make_pair(callable, callable_id));
67 return callable_id;
68 }
69
AddCall(Callable * caller,SourcePosition call_position,Callable * callee)70 void KytheData::AddCall(Callable* caller, SourcePosition call_position,
71 Callable* callee) {
72 if (!caller) return; // Ignore those for now.
73 DCHECK_NOT_NULL(caller);
74 DCHECK_NOT_NULL(callee);
75 KytheData* that = &Get();
76 if (call_position.source.IsValid()) {
77 kythe_entity_t caller_id = AddFunctionDefinition(caller);
78 kythe_entity_t callee_id = AddFunctionDefinition(callee);
79
80 KythePosition call_pos = MakeKythePosition(call_position);
81 that->consumer_->AddCall(KytheConsumer::Kind::Function, caller_id, call_pos,
82 callee_id);
83 }
84 }
85
86 // Class fields
AddClassFieldDefinition(const Field * field)87 kythe_entity_t KytheData::AddClassFieldDefinition(const Field* field) {
88 DCHECK(field);
89 KytheData* that = &KytheData::Get();
90 // Check if we know that field already.
91 auto it = that->class_fields_.find(field);
92 if (it != that->class_fields_.end()) return it->second;
93 // Register this field.
94 KythePosition pos = MakeKythePosition(field->pos);
95 kythe_entity_t field_id = that->consumer_->AddDefinition(
96 KytheConsumer::Kind::ClassField, field->name_and_type.name, pos);
97 that->class_fields_.insert(it, std::make_pair(field, field_id));
98 return field_id;
99 }
100
AddClassFieldUse(SourcePosition use_position,const Field * field)101 void KytheData::AddClassFieldUse(SourcePosition use_position,
102 const Field* field) {
103 DCHECK(field);
104 KytheData* that = &KytheData::Get();
105 kythe_entity_t field_id = AddClassFieldDefinition(field);
106
107 KythePosition use_pos = MakeKythePosition(use_position);
108 that->consumer_->AddUse(KytheConsumer::Kind::ClassField, field_id, use_pos);
109 }
110
111 // Bindings
AddBindingDefinition(Binding<LocalValue> * binding)112 kythe_entity_t KytheData::AddBindingDefinition(Binding<LocalValue>* binding) {
113 CHECK(binding);
114 const uint64_t binding_index = binding->unique_index();
115 return AddBindingDefinitionImpl(binding_index, binding->name(),
116 binding->declaration_position());
117 }
118
AddBindingDefinition(Binding<LocalLabel> * binding)119 kythe_entity_t KytheData::AddBindingDefinition(Binding<LocalLabel>* binding) {
120 CHECK(binding);
121 const uint64_t binding_index = binding->unique_index();
122 return AddBindingDefinitionImpl(binding_index, binding->name(),
123 binding->declaration_position());
124 }
125
AddBindingDefinitionImpl(uint64_t binding_index,const std::string & name,const SourcePosition & ident_pos)126 kythe_entity_t KytheData::AddBindingDefinitionImpl(
127 uint64_t binding_index, const std::string& name,
128 const SourcePosition& ident_pos) {
129 KytheData* that = &KytheData::Get();
130 // Check if we know the binding already.
131 auto it = that->local_bindings_.find(binding_index);
132 if (it != that->local_bindings_.end()) return it->second;
133 // Register this binding.
134 kythe_entity_t binding_id = that->consumer_->AddDefinition(
135 KytheConsumer::Kind::Variable, name, MakeKythePosition(ident_pos));
136 that->local_bindings_.insert(it, std::make_pair(binding_index, binding_id));
137 return binding_id;
138 }
139
AddBindingUse(SourcePosition use_position,Binding<LocalValue> * binding)140 void KytheData::AddBindingUse(SourcePosition use_position,
141 Binding<LocalValue>* binding) {
142 CHECK(binding);
143 KytheData* that = &KytheData::Get();
144 kythe_entity_t binding_id = AddBindingDefinition(binding);
145
146 KythePosition use_pos = MakeKythePosition(use_position);
147 that->consumer_->AddUse(KytheConsumer::Kind::Variable, binding_id, use_pos);
148 }
149
AddBindingUse(SourcePosition use_position,Binding<LocalLabel> * binding)150 void KytheData::AddBindingUse(SourcePosition use_position,
151 Binding<LocalLabel>* binding) {
152 CHECK(binding);
153 KytheData* that = &KytheData::Get();
154 kythe_entity_t binding_id = AddBindingDefinition(binding);
155
156 KythePosition use_pos = MakeKythePosition(use_position);
157 that->consumer_->AddUse(KytheConsumer::Kind::Variable, binding_id, use_pos);
158 }
159
160 // Types
AddTypeDefinition(const Declarable * type_decl)161 kythe_entity_t KytheData::AddTypeDefinition(const Declarable* type_decl) {
162 CHECK(type_decl);
163 KytheData* that = &KytheData::Get();
164 // Check if we know that type already.
165 auto it = that->types_.find(type_decl);
166 if (it != that->types_.end()) return it->second;
167 // Register this type.
168 KythePosition pos = MakeKythePosition(type_decl->IdentifierPosition());
169 kythe_entity_t type_id = that->consumer_->AddDefinition(
170 KytheConsumer::Kind::Type, type_decl->type_name(), pos);
171 that->types_.insert(it, std::make_pair(type_decl, type_id));
172 return type_id;
173 }
174
AddTypeUse(SourcePosition use_position,const Declarable * type_decl)175 void KytheData::AddTypeUse(SourcePosition use_position,
176 const Declarable* type_decl) {
177 CHECK(type_decl);
178 KytheData* that = &KytheData::Get();
179 kythe_entity_t type_id = AddTypeDefinition(type_decl);
180
181 KythePosition use_pos = MakeKythePosition(use_position);
182 that->consumer_->AddUse(KytheConsumer::Kind::Type, type_id, use_pos);
183 }
184
185 } // namespace torque
186 } // namespace internal
187 } // namespace v8
188