mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
382 lines
12 KiB
C++
382 lines
12 KiB
C++
//===--- NameLookup.h - Swift Name Lookup Routines --------------*- C++ -*-===//
|
|
//
|
|
// 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 defines interfaces for performing name lookup.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_AST_NAME_LOOKUP_H
|
|
#define SWIFT_AST_NAME_LOOKUP_H
|
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "swift/AST/Identifier.h"
|
|
#include "swift/Basic/SourceLoc.h"
|
|
|
|
namespace swift {
|
|
class ASTContext;
|
|
class DeclContext;
|
|
class Expr;
|
|
class ValueDecl;
|
|
class Type;
|
|
class TypeAliasDecl;
|
|
class TypeDecl;
|
|
class Module;
|
|
class TupleType;
|
|
|
|
/// MemberLookupResult - One result of member name lookup.
|
|
struct MemberLookupResult {
|
|
/// D - The decl found.
|
|
ValueDecl *D;
|
|
|
|
/// Kind - The kind of reference.
|
|
enum KindTy {
|
|
/// MemberProperty - "a.x" refers to an "x" which is an instance property
|
|
/// of "a".
|
|
MemberProperty,
|
|
|
|
/// MemberFunction - "a.x" refers to an "x" which is an instance function
|
|
/// of "a". "A.x" refers to a curried function such that "A.x(a)" is
|
|
/// equivalent to "x.a" if "A" is the metatype of the type of "a".
|
|
MemberFunction,
|
|
|
|
/// MetatypeMember - "A.x" refers to an "x" which is a member of the
|
|
/// metatype "A". "a.x" is illegal.
|
|
MetatypeMember,
|
|
|
|
/// ExistentialMember - "a.x" refers to a member of an existential type.
|
|
ExistentialMember,
|
|
|
|
/// ArchetypeMember - "a.x" refers to a member of an archetype (which was
|
|
/// actually found in a protocol to which that archetype conforms).
|
|
ArchetypeMember,
|
|
|
|
/// MetaArchetypeMember - "A.x" refers to an "x" which is a member of
|
|
/// the metatype A of an archetype (A'). May also occur for "a.x" when "x"
|
|
/// is not an instance member, e.g., it is a type or a static function.
|
|
/// In either case, the base is evaluated and ignored.
|
|
MetaArchetypeMember,
|
|
|
|
/// \brief Lookup has found a generic parameter.
|
|
GenericParameter
|
|
} Kind;
|
|
|
|
static MemberLookupResult getMemberProperty(ValueDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = D;
|
|
R.Kind = MemberProperty;
|
|
return R;
|
|
}
|
|
static MemberLookupResult getMemberFunction(ValueDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = D;
|
|
R.Kind = MemberFunction;
|
|
return R;
|
|
}
|
|
static MemberLookupResult getMetatypeMember(ValueDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = D;
|
|
R.Kind = MetatypeMember;
|
|
return R;
|
|
}
|
|
static MemberLookupResult getExistentialMember(ValueDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = D;
|
|
R.Kind = ExistentialMember;
|
|
return R;
|
|
}
|
|
static MemberLookupResult getArchetypeMember(ValueDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = D;
|
|
R.Kind = ArchetypeMember;
|
|
return R;
|
|
}
|
|
|
|
static MemberLookupResult getMetaArchetypeMember(ValueDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = D;
|
|
R.Kind = MetaArchetypeMember;
|
|
return R;
|
|
}
|
|
|
|
static MemberLookupResult getGenericParameter(TypeAliasDecl *D) {
|
|
MemberLookupResult R;
|
|
R.D = reinterpret_cast<ValueDecl *>(D);
|
|
R.Kind = GenericParameter;
|
|
return R;
|
|
}
|
|
};
|
|
|
|
/// MemberLookup - This class implements and represents the result of performing
|
|
/// "dot" style member lookup.
|
|
class MemberLookup {
|
|
MemberLookup(const MemberLookup&) = delete;
|
|
void operator=(const MemberLookup&) = delete;
|
|
public:
|
|
MemberLookup(MemberLookup&&) = default;
|
|
MemberLookup &operator=(MemberLookup&&) = default;
|
|
|
|
/// MemberLookup ctor - Lookup a member 'Name' in 'BaseTy' within the context
|
|
/// of a given module 'M'. This operation corresponds to a standard "dot"
|
|
/// lookup operation like "a.b" where 'this' is the type of 'a'. This
|
|
/// operation is only valid after name binding.
|
|
MemberLookup(Type BaseTy, Identifier Name, Module &M,
|
|
bool IsTypeLookup = false);
|
|
|
|
/// Results - The constructor fills this vector in with all of the results.
|
|
/// If name lookup failed, this is empty.
|
|
llvm::SmallVector<MemberLookupResult, 4> Results;
|
|
|
|
/// isSuccess - Return true if anything was found by the name lookup.
|
|
bool isSuccess() const { return !Results.empty(); }
|
|
|
|
/// getMemberName - Retrieve the name of the member this lookup searched for.
|
|
Identifier getMemberName() const { return MemberName; }
|
|
|
|
private:
|
|
Identifier MemberName;
|
|
bool IsTypeLookup;
|
|
typedef llvm::SmallPtrSet<TypeDecl *, 8> VisitedSet;
|
|
void doIt(Type BaseTy, Module &M, bool OnlyInstanceMembers,
|
|
VisitedSet &Visited);
|
|
void lookupMembers(Type BaseType, Module &M,
|
|
SmallVectorImpl<ValueDecl*> &Result);
|
|
};
|
|
|
|
/// ConstructorLookup - This class implements and represents the result of
|
|
/// looking up a constructor for a type.
|
|
class ConstructorLookup {
|
|
ConstructorLookup(const ConstructorLookup&) = delete;
|
|
void operator=(const ConstructorLookup&) = delete;
|
|
public:
|
|
/// ConstructorLookup ctor - Lookup constructors for the given type in the
|
|
/// given module.
|
|
ConstructorLookup(Type BaseTy, Module &M);
|
|
|
|
/// Results - The constructor fills this vector in with all of the results.
|
|
/// If name lookup failed, this is empty.
|
|
llvm::SmallVector<ValueDecl*, 4> Results;
|
|
|
|
/// isSuccess - Return true if anything was found by the name lookup.
|
|
bool isSuccess() const { return !Results.empty(); }
|
|
};
|
|
|
|
/// UnqualifiedLookupResult - One result of unqualified lookup.
|
|
struct UnqualifiedLookupResult {
|
|
private:
|
|
ValueDecl *Base;
|
|
union {
|
|
ValueDecl *Value;
|
|
Module *NamedModule;
|
|
};
|
|
|
|
public:
|
|
/// Kind - The kind of reference.
|
|
enum KindTy {
|
|
/// ModuleMember - "x" refers to a value declared at module scope.
|
|
ModuleMember,
|
|
|
|
/// LocalDecl - "x" refers to a value declared in a local scope.
|
|
LocalDecl,
|
|
|
|
/// MemberProperty - "x" refers to an instance property of a type which
|
|
/// is a containing scope.
|
|
MemberProperty,
|
|
|
|
/// MemberFunction - "x" refers to an instance function of a type
|
|
/// is a containing scope. If the lookup is inside an instance function
|
|
/// of the containing type, it refers to the instance function; otherwise,
|
|
/// it refers to the curried function on the metatype.
|
|
MemberFunction,
|
|
|
|
/// MetatypeMember - "x" refers to a member of a metatype "A", which is a
|
|
/// referred to by BaseDecl.
|
|
MetatypeMember,
|
|
|
|
/// ExistentialMember - "x" refers to a member of an existential type,
|
|
/// which is referred to by BaseDecl.
|
|
ExistentialMember,
|
|
|
|
/// ArchetypeMember - "x" refers to a member of an archetype type,
|
|
/// which is referred to by BaseDecl.
|
|
ArchetypeMember,
|
|
|
|
/// MetaArchetypeMember - "x" refers to a member of the metatype of an
|
|
/// archetype type, which is referred to by BaseDecl. The base is evaluated
|
|
/// and ignored.
|
|
MetaArchetypeMember,
|
|
|
|
/// ModuleName - "x" refers to a module, either the current
|
|
/// module or an imported module.
|
|
ModuleName
|
|
} Kind;
|
|
|
|
bool hasValueDecl() {
|
|
return Kind != ModuleName;
|
|
}
|
|
|
|
ValueDecl *getValueDecl() {
|
|
assert(hasValueDecl());
|
|
return Value;
|
|
}
|
|
|
|
Module *getNamedModule() {
|
|
assert(Kind == ModuleName);
|
|
return NamedModule;
|
|
}
|
|
|
|
ValueDecl *getBaseDecl() {
|
|
return Base;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getModuleMember(ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = nullptr;
|
|
R.Value = value;
|
|
R.Kind = ModuleMember;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getLocalDecl(ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = nullptr;
|
|
R.Value = value;
|
|
R.Kind = LocalDecl;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getMemberProperty(ValueDecl *base,
|
|
ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = base;
|
|
R.Value = value;
|
|
R.Kind = MemberProperty;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getMemberFunction(ValueDecl *base,
|
|
ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = base;
|
|
R.Value = value;
|
|
R.Kind = MemberFunction;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getMetatypeMember(ValueDecl *base,
|
|
ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = base;
|
|
R.Value = value;
|
|
R.Kind = MetatypeMember;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getExistentialMember(ValueDecl *base,
|
|
ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = base;
|
|
R.Value = value;
|
|
R.Kind = ExistentialMember;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getArchetypeMember(ValueDecl *base,
|
|
ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = base;
|
|
R.Value = value;
|
|
R.Kind = ArchetypeMember;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getMetaArchetypeMember(ValueDecl *base,
|
|
ValueDecl *value) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = base;
|
|
R.Value = value;
|
|
R.Kind = MetaArchetypeMember;
|
|
return R;
|
|
}
|
|
|
|
static UnqualifiedLookupResult getModuleName(Module *m) {
|
|
UnqualifiedLookupResult R;
|
|
R.Base = nullptr;
|
|
R.NamedModule = m;
|
|
R.Kind = ModuleName;
|
|
return R;
|
|
}
|
|
};
|
|
|
|
/// UnqualifiedLookup - This class implements and represents the result of
|
|
/// performing unqualified lookup (i.e. lookup for a plain identifier).
|
|
class UnqualifiedLookup {
|
|
UnqualifiedLookup(const MemberLookup&) = delete;
|
|
void operator=(const MemberLookup&) = delete;
|
|
public:
|
|
/// UnqualifiedLookup ctor - Lookup an unqualfied identifier 'Name' in the
|
|
/// context. If the current DeclContext is nested in a FuncExpr, the
|
|
/// SourceLoc is used to determine which declarations in that FuncExpr's
|
|
/// context are visible.
|
|
UnqualifiedLookup(Identifier Name, DeclContext *DC,
|
|
SourceLoc Loc = SourceLoc(),
|
|
bool IsTypeLookup = false);
|
|
|
|
llvm::SmallVector<UnqualifiedLookupResult, 4> Results;
|
|
|
|
/// isSuccess - Return true if anything was found by the name lookup.
|
|
bool isSuccess() const { return !Results.empty(); }
|
|
|
|
/// getSingleTypeResult - Get the result as a single type, or
|
|
/// a null type if that fails.
|
|
TypeDecl* getSingleTypeResult();
|
|
};
|
|
|
|
/// VisibleDeclConsumer - An abstract base class for a visitor that consumes
|
|
/// visible declarations found within a given context. Subclasses of this class
|
|
/// can be used with lookupVisibleDecls().
|
|
class VisibleDeclConsumer {
|
|
public:
|
|
virtual ~VisibleDeclConsumer();
|
|
|
|
/// This method is called by findVisibleDecls() every time it finds a decl.
|
|
virtual void foundDecl(ValueDecl *decl) = 0;
|
|
};
|
|
|
|
/// \brief Remove any declarations in the given set that are shadowed by
|
|
/// other declarations in that set.
|
|
///
|
|
/// \param decls The set of declarations being considered.
|
|
/// \param isTypeLookup Whether the declarations are the result of type lookup.
|
|
/// \param curModule The current module.
|
|
void removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
|
|
bool isTypeLookup,
|
|
Module *curModule);
|
|
|
|
/// Finds decls visible in the given context and feeds them to the given
|
|
/// VisibleDeclConsumer. If the current DeclContext is nested in a FuncExpr, the
|
|
/// SourceLoc is used to determine which declarations in that FuncExpr's
|
|
/// context are visible.
|
|
void lookupVisibleDecls(VisibleDeclConsumer &Consumer,
|
|
DeclContext *DC, SourceLoc Loc = SourceLoc(),
|
|
bool IsTypeLookup = false);
|
|
|
|
/// Finds decls visible as members of the given type and feeds them to the given
|
|
/// VisibleDeclConsumer.
|
|
void lookupVisibleDecls(VisibleDeclConsumer &Consumer,
|
|
Type BaseTy,
|
|
bool IsTypeLookup = false);
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|