Skip to content

Commit 8e4e857

Browse files
authored
Merge pull request #5778 from CodaFi/fine-imported-goods
SE-0075 Implement canImport
2 parents eaa7cb9 + cededef commit 8e4e857

27 files changed

+1156
-343
lines changed

include/swift/AST/AST.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/AST/ParameterList.h"
2828
#include "swift/AST/Pattern.h"
2929
#include "swift/AST/Stmt.h"
30+
#include "swift/AST/StmtTransformer.h"
3031
#include "swift/AST/Types.h"
3132
#include "swift/AST/TypeRepr.h"
3233

include/swift/AST/Decl.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,8 +1929,7 @@ struct IfConfigDeclClause {
19291929

19301930
ArrayRef<Decl*> Members;
19311931

1932-
/// True if this is the active clause of the #if block. Since this is
1933-
/// evaluated at parse time, this is always known.
1932+
/// True if this is the active clause of the #if block.
19341933
bool isActive;
19351934

19361935
IfConfigDeclClause(SourceLoc Loc, Expr *Cond, ArrayRef<Decl*> Members,
@@ -1950,13 +1949,13 @@ class IfConfigDecl : public Decl {
19501949
ArrayRef<IfConfigDeclClause> Clauses;
19511950
SourceLoc EndLoc;
19521951
bool HadMissingEnd;
1952+
bool HasBeenResolved = false;
19531953
public:
19541954

19551955
IfConfigDecl(DeclContext *Parent, ArrayRef<IfConfigDeclClause> Clauses,
19561956
SourceLoc EndLoc, bool HadMissingEnd)
1957-
: Decl(DeclKind::IfConfig, Parent), Clauses(Clauses), EndLoc(EndLoc),
1958-
HadMissingEnd(HadMissingEnd) {
1959-
}
1957+
: Decl(DeclKind::IfConfig, Parent), Clauses(Clauses),
1958+
EndLoc(EndLoc), HadMissingEnd(HadMissingEnd) {}
19601959

19611960
ArrayRef<IfConfigDeclClause> getClauses() const { return Clauses; }
19621961

@@ -1966,11 +1965,15 @@ class IfConfigDecl : public Decl {
19661965
if (Clause.isActive) return &Clause;
19671966
return nullptr;
19681967
}
1968+
19691969
const ArrayRef<Decl*> getActiveMembers() const {
19701970
if (auto *Clause = getActiveClause())
19711971
return Clause->Members;
19721972
return {};
19731973
}
1974+
1975+
bool isResolved() const { return HasBeenResolved; }
1976+
void setResolved() { HasBeenResolved = true; }
19741977

19751978
SourceLoc getEndLoc() const { return EndLoc; }
19761979
SourceLoc getLoc() const { return Clauses[0].Loc; }

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,8 @@ ERROR(unsupported_conditional_compilation_binary_expression,none,
13341334
ERROR(unsupported_conditional_compilation_unary_expression,none,
13351335
"expected unary '!' expression", ())
13361336
ERROR(unsupported_platform_condition_expression,none,
1337-
"unexpected platform condition (expected 'os', 'arch', or 'swift')",
1337+
"unexpected platform condition "
1338+
"(expected 'canImport', 'os', 'arch', or 'swift')",
13381339
())
13391340
ERROR(platform_condition_expected_one_argument,none,
13401341
"expected only one argument to platform condition",

include/swift/AST/Module.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,13 +831,13 @@ class SourceFile final : public FileUnit {
831831
std::vector<Decl*> Decls;
832832

833833
/// The list of local type declarations in the source file.
834-
TinyPtrVector<TypeDecl*> LocalTypeDecls;
834+
llvm::SetVector<TypeDecl *> LocalTypeDecls;
835835

836836
/// A set of special declaration attributes which require the
837837
/// Foundation module to be imported to work. If the foundation
838838
/// module is still not imported by the time type checking is
839839
/// complete, we diagnose.
840-
std::map<DeclAttrKind, const DeclAttribute *> AttrsRequiringFoundation;
840+
llvm::SetVector<const DeclAttribute *> AttrsRequiringFoundation;
841841

842842
/// A mapping from Objective-C selectors to the methods that have
843843
/// those selectors.

include/swift/AST/Stmt.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,10 @@ struct IfConfigStmtClause {
667667

668668
/// Elements inside the clause
669669
ArrayRef<ASTNode> Elements;
670-
671-
/// True if this is the active clause of the #if block. Since this is
672-
/// evaluated at parse time, this is always known.
670+
671+
/// True if this is the active clause of the #if block.
673672
bool isActive;
674-
673+
675674
IfConfigStmtClause(SourceLoc Loc, Expr *Cond,
676675
ArrayRef<ASTNode> Elements, bool isActive)
677676
: Loc(Loc), Cond(Cond), Elements(Elements), isActive(isActive) {
@@ -686,6 +685,7 @@ class IfConfigStmt : public Stmt {
686685
ArrayRef<IfConfigStmtClause> Clauses;
687686
SourceLoc EndLoc;
688687
bool HadMissingEnd;
688+
bool HasBeenResolved = false;
689689

690690
public:
691691
IfConfigStmt(ArrayRef<IfConfigStmtClause> Clauses, SourceLoc EndLoc,
@@ -700,8 +700,11 @@ class IfConfigStmt : public Stmt {
700700

701701
bool hadMissingEnd() const { return HadMissingEnd; }
702702

703-
const ArrayRef<IfConfigStmtClause> &getClauses() const { return Clauses; }
703+
bool isResolved() { return HasBeenResolved; }
704+
void setResolved() { HasBeenResolved = true; }
704705

706+
const ArrayRef<IfConfigStmtClause> &getClauses() const { return Clauses; }
707+
705708
ArrayRef<ASTNode> getActiveClauseElements() const {
706709
for (auto &Clause : Clauses)
707710
if (Clause.isActive)

include/swift/AST/StmtTransformer.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===--- StmtTransformer.h - Class for transforming Stmts -------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the StmtTransformer class.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_STMTTRANSFORMER_H
18+
#define SWIFT_AST_STMTTRANSFORMER_H
19+
20+
#include "swift/AST/ASTWalker.h"
21+
#include "swift/AST/Stmt.h"
22+
#include "swift/AST/Expr.h"
23+
24+
#include <forward_list>
25+
26+
namespace swift {
27+
class StmtTransformer {
28+
protected:
29+
class ClosureFinder : public ASTWalker {
30+
StmtTransformer &StmtTrans;
31+
public:
32+
ClosureFinder(StmtTransformer &CCR) : StmtTrans(CCR) { }
33+
virtual std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) {
34+
if (isa<BraceStmt>(S)) {
35+
// To respect nesting, don't walk into brace statements.
36+
return { false, S };
37+
} else {
38+
return { true, S };
39+
}
40+
}
41+
virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) {
42+
if (ClosureExpr *CE = dyn_cast<ClosureExpr>(E)) {
43+
BraceStmt *B = CE->getBody();
44+
if (B) {
45+
BraceStmt *NB = StmtTrans.transformBraceStmt(B, false);
46+
CE->setBody(NB, CE->hasSingleExpressionBody());
47+
}
48+
}
49+
return { true, E };
50+
}
51+
};
52+
ClosureFinder CF;
53+
54+
public:
55+
StmtTransformer() : CF(*this) {}
56+
virtual ~StmtTransformer() {}
57+
58+
const ASTWalker &getClosureFinder() const {
59+
return CF;
60+
}
61+
62+
virtual Stmt *transformStmt(Stmt *S);
63+
virtual BraceStmt *transformBraceStmt(BraceStmt *BS, bool TopLevel);
64+
#define STMT(CLASS, PARENT) \
65+
virtual CLASS##Stmt *transform##CLASS##Stmt(CLASS##Stmt *S);
66+
#include "swift/AST/StmtNodes.def"
67+
};
68+
};
69+
70+
#endif /* SWIFT_AST_STMTTRANSFORMER_H */

include/swift/Parse/Parser.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ namespace swift {
5959
TopLevelCode,
6060
/// The top-level of a file, when in parse-as-library mode.
6161
TopLevelLibrary,
62-
/// The body of the inactive clause of an #if/#else/#endif block
63-
InactiveConditionalBlock,
64-
/// The body of the active clause of an #if/#else/#endif block
65-
ActiveConditionalBlock
62+
/// The body of the clause of an #if/#else/#endif block
63+
ConditionalBlock,
64+
/// The body of the clause of an #if/#else/#endif block that was statically
65+
/// determined to be inactive.
66+
StaticallyInactiveConditionalBlock,
6667
};
6768

6869

@@ -619,7 +620,7 @@ class Parser {
619620
BraceItemListKind::Brace);
620621
ParserResult<BraceStmt> parseBraceItemList(Diag<> ID);
621622

622-
void parseIfConfigClauseElements(bool isActive,
623+
void parseIfConfigClauseElements(bool isInactive,
623624
BraceItemListKind Kind,
624625
SmallVectorImpl<ASTNode> &Elements);
625626

@@ -646,7 +647,7 @@ class Parser {
646647
PD_InExtension = 1 << 8,
647648
PD_InStruct = 1 << 9,
648649
PD_InEnum = 1 << 10,
649-
PD_InLoop = 1 << 11
650+
PD_InLoop = 1 << 11,
650651
};
651652

652653
/// Options that control the parsing of declarations.
@@ -1229,9 +1230,14 @@ class Parser {
12291230
ParserResult<Stmt> parseStmtSwitch(LabeledStmtInfo LabelInfo);
12301231
ParserResult<CaseStmt> parseStmtCase();
12311232

1232-
/// Evaluate the condition of an #if directive.
1233-
ConditionalCompilationExprState
1234-
evaluateConditionalCompilationExpr(Expr *condition);
1233+
/// Classify the condition of an #if directive according to whether it can
1234+
/// be evaluated statically. If evaluation is not possible, the result is
1235+
/// 'None'.
1236+
static Optional<bool>
1237+
classifyConditionalCompilationExpr(Expr *condition,
1238+
ASTContext &context,
1239+
DiagnosticEngine &diags,
1240+
bool fullCheck = false);
12351241

12361242
//===--------------------------------------------------------------------===//
12371243
// Generics Parsing

include/swift/Parse/ParserResult.h

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -217,74 +217,6 @@ template <typename T> ParserResult<T>::ParserResult(ParserStatus Status) {
217217
setHasCodeCompletion();
218218
}
219219

220-
enum class ConditionalCompilationExprKind {
221-
Unknown,
222-
Error,
223-
OS,
224-
Arch,
225-
LanguageVersion,
226-
CompilerVersion,
227-
Binary,
228-
Paren,
229-
DeclRef,
230-
Boolean,
231-
Integer
232-
};
233-
234-
class ConditionalCompilationExprState {
235-
236-
uint8_t ConditionActive : 1;
237-
uint8_t Kind : 7;
238-
public:
239-
ConditionalCompilationExprState() : ConditionActive(false) {
240-
setKind(ConditionalCompilationExprKind::Unknown);
241-
}
242-
243-
ConditionalCompilationExprState(bool ConditionActive,
244-
ConditionalCompilationExprKind Kind)
245-
: ConditionActive(ConditionActive) {
246-
setKind(Kind);
247-
}
248-
249-
bool isConditionActive() const {
250-
return ConditionActive;
251-
}
252-
253-
void setConditionActive(bool A) {
254-
ConditionActive = A;
255-
}
256-
257-
ConditionalCompilationExprKind getKind() const {
258-
return static_cast<ConditionalCompilationExprKind>(Kind);
259-
}
260-
261-
void setKind(ConditionalCompilationExprKind K) {
262-
Kind = static_cast<uint8_t>(K);
263-
assert(getKind() == K);
264-
}
265-
266-
bool shouldParse() const {
267-
if (getKind() == ConditionalCompilationExprKind::Error)
268-
return true;
269-
return ConditionActive ||
270-
(getKind() != ConditionalCompilationExprKind::CompilerVersion &&
271-
getKind() != ConditionalCompilationExprKind::LanguageVersion);
272-
}
273-
274-
static ConditionalCompilationExprState error() {
275-
return {false, ConditionalCompilationExprKind::Error};
276-
}
277-
};
278-
279-
ConditionalCompilationExprState
280-
operator&&(const ConditionalCompilationExprState lhs,
281-
const ConditionalCompilationExprState rhs);
282-
ConditionalCompilationExprState
283-
operator||(const ConditionalCompilationExprState lhs,
284-
const ConditionalCompilationExprState rhs);
285-
ConditionalCompilationExprState
286-
operator!(const ConditionalCompilationExprState Result);
287-
288220
} // namespace swift
289221

290222
#endif // LLVM_SWIFT_PARSER_PARSER_RESULT_H

include/swift/Parse/Scope.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ class ScopeInfo {
5454
/// scope.
5555
void addToScope(ValueDecl *D, Parser &TheParser);
5656

57-
bool isInactiveConfigBlock() const;
58-
57+
bool isStaticallyInactiveConfigBlock() const;
58+
5959
SavedScope saveCurrentScope();
6060
};
6161

@@ -91,7 +91,7 @@ class SavedScope {
9191
ScopeInfo::ScopedHTDetachedScopeTy HTDetachedScope;
9292
unsigned Depth;
9393
ScopeKind Kind;
94-
bool IsInactiveConfigBlock;
94+
bool IsStaticallyInactiveConfigBlock;
9595

9696
SavedScope() = delete;
9797
SavedScope(const SavedScope &) = delete;
@@ -103,9 +103,9 @@ class SavedScope {
103103
~SavedScope() = default;
104104

105105
SavedScope(ScopeInfo::ScopedHTDetachedScopeTy &&HTDetachedScope,
106-
unsigned Depth, ScopeKind Kind, bool IsInactiveConfigBlock)
106+
unsigned Depth, ScopeKind Kind, bool IsStaticallyInactiveConfigBlock)
107107
: HTDetachedScope(std::move(HTDetachedScope)), Depth(Depth), Kind(Kind),
108-
IsInactiveConfigBlock(IsInactiveConfigBlock) {}
108+
IsStaticallyInactiveConfigBlock(IsStaticallyInactiveConfigBlock) {}
109109
};
110110

111111
/// Scope - This class represents lexical scopes. These objects are created
@@ -125,12 +125,13 @@ class Scope {
125125
unsigned PrevResolvableDepth;
126126
unsigned Depth;
127127
ScopeKind Kind;
128-
bool IsInactiveConfigBlock;
128+
bool IsStaticallyInactiveConfigBlock;
129129

130130
/// \brief Save this scope so that it can be re-entered later. Transfers the
131131
/// ownership of the scope frame to returned object.
132132
SavedScope saveScope() {
133-
return SavedScope(HTScope.detach(), Depth, Kind, IsInactiveConfigBlock);
133+
return SavedScope(HTScope.detach(), Depth, Kind,
134+
IsStaticallyInactiveConfigBlock);
134135
}
135136

136137
unsigned getDepth() const {
@@ -141,7 +142,7 @@ class Scope {
141142

142143
public:
143144
/// \brief Create a lexical scope of the specified kind.
144-
Scope(Parser *P, ScopeKind SC, bool IsInactiveConfigBlock = false);
145+
Scope(Parser *P, ScopeKind SC, bool IsStaticallyInactiveConfigBlock = false);
145146

146147
/// \brief Re-enter the specified scope, transferring the ownership of the
147148
/// scope frame to the new object.
@@ -174,10 +175,15 @@ inline ValueDecl *ScopeInfo::lookupValueName(DeclName Name) {
174175
return Res.second;
175176
}
176177

177-
inline bool ScopeInfo::isInactiveConfigBlock() const {
178-
if (!CurScope)
179-
return false;
180-
return CurScope->IsInactiveConfigBlock;
178+
inline bool ScopeInfo::isStaticallyInactiveConfigBlock() const {
179+
auto scope = CurScope;
180+
while (scope) {
181+
if (scope->IsStaticallyInactiveConfigBlock) {
182+
return true;
183+
}
184+
scope = scope->PrevScope;
185+
}
186+
return false;
181187
}
182188

183189
inline SavedScope ScopeInfo::saveCurrentScope() {

0 commit comments

Comments
 (0)