| // Copyright 2018 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 <fstream> |
| #include <iostream> |
| |
| #include "src/torque/declarable.h" |
| #include "src/torque/global-context.h" |
| #include "src/torque/type-visitor.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace torque { |
| |
| DEFINE_CONTEXTUAL_VARIABLE(CurrentScope) |
| |
| std::ostream& operator<<(std::ostream& os, const QualifiedName& name) { |
| for (const std::string& qualifier : name.namespace_qualification) { |
| os << qualifier << "::"; |
| } |
| return os << name.name; |
| } |
| |
| std::ostream& operator<<(std::ostream& os, const Callable& m) { |
| os << "callable " << m.ReadableName() << "("; |
| if (m.signature().implicit_count != 0) { |
| os << "implicit "; |
| TypeVector implicit_parameter_types( |
| m.signature().parameter_types.types.begin(), |
| m.signature().parameter_types.types.begin() + |
| m.signature().implicit_count); |
| os << implicit_parameter_types << ")("; |
| TypeVector explicit_parameter_types( |
| m.signature().parameter_types.types.begin() + |
| m.signature().implicit_count, |
| m.signature().parameter_types.types.end()); |
| os << explicit_parameter_types; |
| } else { |
| os << m.signature().parameter_types; |
| } |
| os << "): " << *m.signature().return_type; |
| return os; |
| } |
| |
| std::ostream& operator<<(std::ostream& os, const Builtin& b) { |
| os << "builtin " << *b.signature().return_type << " " << b.ReadableName() |
| << b.signature().parameter_types; |
| return os; |
| } |
| |
| std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) { |
| os << "runtime function " << *b.signature().return_type << " " |
| << b.ReadableName() << b.signature().parameter_types; |
| return os; |
| } |
| |
| std::ostream& operator<<(std::ostream& os, const Generic& g) { |
| os << "generic " << g.name() << "<"; |
| PrintCommaSeparatedList( |
| os, g.declaration()->generic_parameters, |
| [](const Identifier* identifier) { return identifier->value; }); |
| os << ">"; |
| |
| return os; |
| } |
| |
| namespace { |
| base::Optional<const Type*> InferTypeArgument(const std::string& to_infer, |
| TypeExpression* parameter, |
| const Type* argument) { |
| BasicTypeExpression* basic = BasicTypeExpression::DynamicCast(parameter); |
| if (basic && basic->namespace_qualification.empty() && !basic->is_constexpr && |
| basic->name == to_infer) { |
| return argument; |
| } |
| auto* ref = ReferenceTypeExpression::DynamicCast(parameter); |
| if (ref && argument->IsReferenceType()) { |
| return InferTypeArgument(to_infer, ref->referenced_type, |
| ReferenceType::cast(argument)->referenced_type()); |
| } |
| return base::nullopt; |
| } |
| |
| base::Optional<const Type*> InferTypeArgument( |
| const std::string& to_infer, const std::vector<TypeExpression*>& parameters, |
| const TypeVector& arguments) { |
| for (size_t i = 0; i < arguments.size() && i < parameters.size(); ++i) { |
| if (base::Optional<const Type*> inferred = |
| InferTypeArgument(to_infer, parameters[i], arguments[i])) { |
| return *inferred; |
| } |
| } |
| return base::nullopt; |
| } |
| |
| } // namespace |
| |
| base::Optional<TypeVector> Generic::InferSpecializationTypes( |
| const TypeVector& explicit_specialization_types, |
| const TypeVector& arguments) { |
| TypeVector result = explicit_specialization_types; |
| size_t type_parameter_count = declaration()->generic_parameters.size(); |
| if (explicit_specialization_types.size() > type_parameter_count) { |
| return base::nullopt; |
| } |
| for (size_t i = explicit_specialization_types.size(); |
| i < type_parameter_count; ++i) { |
| const std::string type_name = declaration()->generic_parameters[i]->value; |
| size_t implicit_count = |
| declaration()->callable->signature->parameters.implicit_count; |
| const std::vector<TypeExpression*>& parameters = |
| declaration()->callable->signature->parameters.types; |
| std::vector<TypeExpression*> explicit_parameters( |
| parameters.begin() + implicit_count, parameters.end()); |
| base::Optional<const Type*> inferred = |
| InferTypeArgument(type_name, explicit_parameters, arguments); |
| if (!inferred) return base::nullopt; |
| result.push_back(*inferred); |
| } |
| return result; |
| } |
| |
| bool Namespace::IsDefaultNamespace() const { |
| return this == GlobalContext::GetDefaultNamespace(); |
| } |
| |
| bool Namespace::IsTestNamespace() const { return name() == kTestNamespaceName; } |
| |
| const Type* TypeAlias::Resolve() const { |
| if (!type_) { |
| CurrentScope::Scope scope_activator(ParentScope()); |
| CurrentSourcePosition::Scope position_activator(Position()); |
| TypeDeclaration* decl = *delayed_; |
| if (being_resolved_) { |
| std::stringstream s; |
| s << "Cannot create type " << decl->name->value |
| << " due to circular dependencies."; |
| ReportError(s.str()); |
| } |
| type_ = TypeVisitor::ComputeType(decl); |
| } |
| return *type_; |
| } |
| |
| } // namespace torque |
| } // namespace internal |
| } // namespace v8 |