File: RuleBuilder.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (125 lines) | stat: -rw-r--r-- 4,854 bytes parent folder | download
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