// Copyright 2021 the V8 project 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/torque/kythe-data.h" namespace v8 { namespace internal { namespace torque { DEFINE_CONTEXTUAL_VARIABLE(KytheData) namespace { KythePosition MakeKythePosition(const SourcePosition& pos) { KythePosition p; if (pos.source.IsValid()) { p.file_path = SourceFileMap::PathFromV8Root(pos.source); } else { p.file_path = "UNKNOWN"; } p.start_offset = pos.start.offset; p.end_offset = pos.end.offset; return p; } } // namespace // Constants kythe_entity_t KytheData::AddConstantDefinition(const Value* constant) { DCHECK(constant->IsNamespaceConstant() || constant->IsExternConstant()); KytheData* that = &KytheData::Get(); // Check if we know the constant already. auto it = that->constants_.find(constant); if (it != that->constants_.end()) return it->second; // Register this constant. KythePosition pos = MakeKythePosition(constant->name()->pos); kythe_entity_t constant_id = that->consumer_->AddDefinition( KytheConsumer::Kind::Constant, constant->name()->value, pos); that->constants_.insert(it, std::make_pair(constant, constant_id)); return constant_id; } void KytheData::AddConstantUse(SourcePosition use_position, const Value* constant) { DCHECK(constant->IsNamespaceConstant() || constant->IsExternConstant()); KytheData* that = &Get(); kythe_entity_t constant_id = AddConstantDefinition(constant); KythePosition use_pos = MakeKythePosition(use_position); that->consumer_->AddUse(KytheConsumer::Kind::Constant, constant_id, use_pos); } // Callables kythe_entity_t KytheData::AddFunctionDefinition(Callable* callable) { KytheData* that = &KytheData::Get(); // Check if we know the caller already. auto it = that->callables_.find(callable); if (it != that->callables_.end()) return it->second; // Register this callable. auto ident_pos = callable->IdentifierPosition(); kythe_entity_t callable_id = that->consumer_->AddDefinition( KytheConsumer::Kind::Function, callable->ExternalName(), MakeKythePosition(ident_pos)); that->callables_.insert(it, std::make_pair(callable, callable_id)); return callable_id; } void KytheData::AddCall(Callable* caller, SourcePosition call_position, Callable* callee) { if (!caller) return; // Ignore those for now. DCHECK_NOT_NULL(caller); DCHECK_NOT_NULL(callee); KytheData* that = &Get(); if (call_position.source.IsValid()) { kythe_entity_t caller_id = AddFunctionDefinition(caller); kythe_entity_t callee_id = AddFunctionDefinition(callee); KythePosition call_pos = MakeKythePosition(call_position); that->consumer_->AddCall(KytheConsumer::Kind::Function, caller_id, call_pos, callee_id); } } // Class fields kythe_entity_t KytheData::AddClassFieldDefinition(const Field* field) { DCHECK(field); KytheData* that = &KytheData::Get(); // Check if we know that field already. auto it = that->class_fields_.find(field); if (it != that->class_fields_.end()) return it->second; // Register this field. KythePosition pos = MakeKythePosition(field->pos); kythe_entity_t field_id = that->consumer_->AddDefinition( KytheConsumer::Kind::ClassField, field->name_and_type.name, pos); that->class_fields_.insert(it, std::make_pair(field, field_id)); return field_id; } void KytheData::AddClassFieldUse(SourcePosition use_position, const Field* field) { DCHECK(field); KytheData* that = &KytheData::Get(); kythe_entity_t field_id = AddClassFieldDefinition(field); KythePosition use_pos = MakeKythePosition(use_position); that->consumer_->AddUse(KytheConsumer::Kind::ClassField, field_id, use_pos); } // Bindings kythe_entity_t KytheData::AddBindingDefinition(Binding* binding) { CHECK(binding); const uint64_t binding_index = binding->unique_index(); return AddBindingDefinitionImpl(binding_index, binding->name(), binding->declaration_position()); } kythe_entity_t KytheData::AddBindingDefinition(Binding* binding) { CHECK(binding); const uint64_t binding_index = binding->unique_index(); return AddBindingDefinitionImpl(binding_index, binding->name(), binding->declaration_position()); } kythe_entity_t KytheData::AddBindingDefinitionImpl( uint64_t binding_index, const std::string& name, const SourcePosition& ident_pos) { KytheData* that = &KytheData::Get(); // Check if we know the binding already. auto it = that->local_bindings_.find(binding_index); if (it != that->local_bindings_.end()) return it->second; // Register this binding. kythe_entity_t binding_id = that->consumer_->AddDefinition( KytheConsumer::Kind::Variable, name, MakeKythePosition(ident_pos)); that->local_bindings_.insert(it, std::make_pair(binding_index, binding_id)); return binding_id; } void KytheData::AddBindingUse(SourcePosition use_position, Binding* binding) { CHECK(binding); KytheData* that = &KytheData::Get(); kythe_entity_t binding_id = AddBindingDefinition(binding); KythePosition use_pos = MakeKythePosition(use_position); that->consumer_->AddUse(KytheConsumer::Kind::Variable, binding_id, use_pos); } void KytheData::AddBindingUse(SourcePosition use_position, Binding* binding) { CHECK(binding); KytheData* that = &KytheData::Get(); kythe_entity_t binding_id = AddBindingDefinition(binding); KythePosition use_pos = MakeKythePosition(use_position); that->consumer_->AddUse(KytheConsumer::Kind::Variable, binding_id, use_pos); } // Types kythe_entity_t KytheData::AddTypeDefinition(const Declarable* type_decl) { CHECK(type_decl); KytheData* that = &KytheData::Get(); // Check if we know that type already. auto it = that->types_.find(type_decl); if (it != that->types_.end()) return it->second; // Register this type. KythePosition pos = MakeKythePosition(type_decl->IdentifierPosition()); kythe_entity_t type_id = that->consumer_->AddDefinition( KytheConsumer::Kind::Type, type_decl->type_name(), pos); that->types_.insert(it, std::make_pair(type_decl, type_id)); return type_id; } void KytheData::AddTypeUse(SourcePosition use_position, const Declarable* type_decl) { CHECK(type_decl); KytheData* that = &KytheData::Get(); kythe_entity_t type_id = AddTypeDefinition(type_decl); KythePosition use_pos = MakeKythePosition(use_position); that->consumer_->AddUse(KytheConsumer::Kind::Type, type_id, use_pos); } } // namespace torque } // namespace internal } // namespace v8