forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIterativeTypeChecker.cpp
92 lines (78 loc) · 3.26 KB
/
IterativeTypeChecker.cpp
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
//===--- IterativeTypeChecker.cpp - Iterative Type Checker ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements the IterativeTypeChecker class, which
// performs iterative type checking by tracking the set of
// outstanding type-checking requests and servicing them as needed.
//
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
#include "swift/Sema/IterativeTypeChecker.h"
#include "swift/AST/Decl.h"
using namespace swift;
ASTContext &IterativeTypeChecker::getASTContext() const {
return TC.Context;
}
DiagnosticEngine &IterativeTypeChecker::getDiags() const {
return getASTContext().Diags;
}
/// Determine whether the given request has already been satisfied.
bool IterativeTypeChecker::isSatisfied(TypeCheckRequest request) {
switch (request.getKind()) {
#define TYPE_CHECK_REQUEST(Request,PayloadName) \
case TypeCheckRequest::Request: \
return is##Request##Satisfied(request.get##PayloadName##Payload());
#include "swift/Sema/TypeCheckRequestKinds.def"
}
}
void IterativeTypeChecker::enumerateDependenciesOf(
TypeCheckRequest request,
llvm::function_ref<void(TypeCheckRequest)> fn) {
switch (request.getKind()) {
#define TYPE_CHECK_REQUEST(Request,PayloadName) \
case TypeCheckRequest::Request: \
return enumerateDependenciesOf##Request( \
request.get##PayloadName##Payload(), \
fn);
#include "swift/Sema/TypeCheckRequestKinds.def"
}
}
void IterativeTypeChecker::satisfy(TypeCheckRequest request) {
// If the request has already been satisfied, we're done.
if (isSatisfied(request)) return;
// Make sure all of the dependencies have been satisfied before continuing.
while (true) {
// Enumerate all of the dependencies of this request and capture
// those that have not been satisfied.
SmallVector<TypeCheckRequest, 4> unsatisfied;
enumerateDependenciesOf(request, [&](TypeCheckRequest dependency) {
// If the dependency has already been satisfied, there's nothing to do.
if (isSatisfied(dependency)) return;
// Record the unsatisfied dependency.
unsatisfied.push_back(dependency);
});
// If all dependencies were satisfied, we're done.
if (unsatisfied.empty()) break;
// Recurse to satisfy any unsatisfied dependencies.
// FIXME: Don't recurse in the iterative type checker, silly!
for (auto dependency: unsatisfied) {
satisfy(dependency);
}
}
// Satisfy this request.
switch (request.getKind()) {
#define TYPE_CHECK_REQUEST(Request,PayloadName) \
case TypeCheckRequest::Request: \
return satisfy##Request(request.get##PayloadName##Payload());
#include "swift/Sema/TypeCheckRequestKinds.def"
}
}