1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
//===--- RuleBuilder.h - Lowering desugared requirements to rules ---------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_RULEBUILDER_H
#define SWIFT_RULEBUILDER_H
#include "swift/AST/ASTContext.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
#include "RewriteContext.h"
#include "Rule.h"
#include "Symbol.h"
#include "Term.h"
namespace llvm {
class raw_ostream;
}
namespace swift {
class AssociatedTypeDecl;
class ProtocolDecl;
class ProtocolTypeAlias;
class Requirement;
namespace rewriting {
/// A utility class for building rewrite rules from the top-level requirements
/// of a generic signature.
///
/// This also collects requirements from the transitive closure of all protocols
/// appearing on the right hand side of conformance requirements.
struct RuleBuilder {
RewriteContext &Context;
/// The transitive closure of all protocols appearing on the right hand
/// side of conformance requirements.
llvm::DenseSet<const ProtocolDecl *> &ReferencedProtocols;
/// A subset of the above in insertion order, consisting of the protocols
/// whose rules we are going to import.
///
/// If this is a rewrite system built from a generic signature, this vector
/// contains all elements in the above set.
///
/// If this is a rewrite system built from a strongly connected component
/// of the protocol, this vector contains all elements in the above set
/// except for the protocols belonging to the component representing the
/// rewrite system itself; those protocols are added directly instead of
/// being imported.
std::vector<const ProtocolDecl *> ProtocolsToImport;
/// The rules representing a complete rewrite system for the above vector,
/// pulled in by collectRulesFromReferencedProtocols().
std::vector<Rule> ImportedRules;
/// New rules to add which will be marked 'permanent'. These are rules for
/// introducing associated types, and relationships between layout,
/// superclass and concrete type symbols. They are not eliminated by
/// homotopy reduction, since they are always added when the rewrite system
/// is built.
std::vector<std::pair<MutableTerm, MutableTerm>> PermanentRules;
/// New rules derived from requirements written by the user, which can be
/// eliminated by homotopy reduction.
std::vector<std::pair<MutableTerm, MutableTerm>> RequirementRules;
/// Enables debugging output. Controlled by the -dump-requirement-machine
/// frontend flag.
unsigned Dump : 1;
/// Used to ensure the initWith*() methods are only called once.
unsigned Initialized : 1;
RuleBuilder(RewriteContext &ctx,
llvm::DenseSet<const ProtocolDecl *> &referencedProtocols)
: Context(ctx), ReferencedProtocols(referencedProtocols) {
Dump = ctx.getASTContext().LangOpts.DumpRequirementMachine;
Initialized = 0;
}
void initWithGenericSignature(ArrayRef<GenericTypeParamType *> genericParams,
ArrayRef<Requirement> requirements);
void initWithWrittenRequirements(ArrayRef<GenericTypeParamType *> genericParams,
ArrayRef<StructuralRequirement> requirements);
void initWithProtocolSignatureRequirements(ArrayRef<const ProtocolDecl *> proto);
void initWithProtocolWrittenRequirements(
ArrayRef<const ProtocolDecl *> component,
const llvm::DenseMap<const ProtocolDecl *,
SmallVector<StructuralRequirement, 4>> protos);
void initWithConditionalRequirements(ArrayRef<Requirement> requirements,
ArrayRef<Term> substitutions);
void addReferencedProtocol(const ProtocolDecl *proto);
void collectRulesFromReferencedProtocols();
void collectPackShapeRules(ArrayRef<GenericTypeParamType *> genericParams);
private:
void addPermanentProtocolRules(const ProtocolDecl *proto);
void addAssociatedType(const AssociatedTypeDecl *type,
const ProtocolDecl *proto);
void
addRequirement(const Requirement &req, const ProtocolDecl *proto,
std::optional<ArrayRef<Term>> substitutions = std::nullopt);
void addRequirement(const StructuralRequirement &req,
const ProtocolDecl *proto);
void addTypeAlias(const ProtocolTypeAlias &alias,
const ProtocolDecl *proto);
};
} // end namespace rewriting
} // end namespace swift
#endif
|