blob: 307a1ef4f87bc07437c7c57ccee30622528e7933 [file] [log] [blame]
//===--- SwiftLangSupport.cpp ---------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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
//
//===----------------------------------------------------------------------===//
#include "SwiftLangSupport.h"
#include "SwiftASTManager.h"
#include "SourceKit/Core/Context.h"
#include "SourceKit/SwiftLang/Factory.h"
#include "SourceKit/Support/UIdent.h"
#include "swift/AST/AST.h"
#include "swift/AST/ASTVisitor.h"
#include "swift/AST/USRGeneration.h"
#include "swift/Basic/Fallthrough.h"
#include "swift/Config.h"
#include "swift/IDE/CodeCompletion.h"
#include "swift/IDE/CodeCompletionCache.h"
#include "swift/IDE/SyntaxModel.h"
#include "swift/IDE/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <sys/param.h>
using namespace SourceKit;
using namespace swift;
using namespace swift::ide;
using swift::index::SymbolKind;
using swift::index::SymbolSubKind;
using swift::index::SymbolSubKindSet;
using swift::index::SymbolRole;
using swift::index::SymbolRoleSet;
static UIdent KindDeclFunctionFree("source.lang.swift.decl.function.free");
static UIdent KindRefFunctionFree("source.lang.swift.ref.function.free");
static UIdent KindDeclMethodInstance(
"source.lang.swift.decl.function.method.instance");
static UIdent KindRefMethodInstance(
"source.lang.swift.ref.function.method.instance");
static UIdent KindDeclMethodStatic(
"source.lang.swift.decl.function.method.static");
static UIdent KindRefMethodStatic(
"source.lang.swift.ref.function.method.static");
static UIdent KindDeclMethodClass(
"source.lang.swift.decl.function.method.class");
static UIdent KindRefMethodClass(
"source.lang.swift.ref.function.method.class");
static UIdent KindDeclAccessorGetter(
"source.lang.swift.decl.function.accessor.getter");
static UIdent KindRefAccessorGetter(
"source.lang.swift.ref.function.accessor.getter");
static UIdent KindDeclAccessorSetter(
"source.lang.swift.decl.function.accessor.setter");
static UIdent KindRefAccessorSetter(
"source.lang.swift.ref.function.accessor.setter");
static UIdent KindDeclAccessorWillSet(
"source.lang.swift.decl.function.accessor.willset");
static UIdent KindRefAccessorWillSet(
"source.lang.swift.ref.function.accessor.willset");
static UIdent KindDeclAccessorDidSet(
"source.lang.swift.decl.function.accessor.didset");
static UIdent KindRefAccessorDidSet(
"source.lang.swift.ref.function.accessor.didset");
static UIdent KindDeclAccessorAddress(
"source.lang.swift.decl.function.accessor.address");
static UIdent KindRefAccessorAddress(
"source.lang.swift.ref.function.accessor.address");
static UIdent KindDeclAccessorMutableAddress(
"source.lang.swift.decl.function.accessor.mutableaddress");
static UIdent KindRefAccessorMutableAddress(
"source.lang.swift.ref.function.accessor.mutableaddress");
static UIdent KindDeclConstructor("source.lang.swift.decl.function.constructor");
static UIdent KindRefConstructor("source.lang.swift.ref.function.constructor");
static UIdent KindDeclDestructor("source.lang.swift.decl.function.destructor");
static UIdent KindRefDestructor("source.lang.swift.ref.function.destructor");
static UIdent KindDeclFunctionPrefixOperator("source.lang.swift.decl.function.operator.prefix");
static UIdent KindDeclFunctionPostfixOperator("source.lang.swift.decl.function.operator.postfix");
static UIdent KindDeclFunctionInfixOperator("source.lang.swift.decl.function.operator.infix");
static UIdent KindRefFunctionPrefixOperator("source.lang.swift.ref.function.operator.prefix");
static UIdent KindRefFunctionPostfixOperator("source.lang.swift.ref.function.operator.postfix");
static UIdent KindRefFunctionInfixOperator("source.lang.swift.ref.function.operator.infix");
static UIdent KindDeclPrecedenceGroup("source.lang.swift.decl.precedencegroup");
static UIdent KindRefPrecedenceGroup("source.lang.swift.ref.precedencegroup");
static UIdent KindDeclSubscript("source.lang.swift.decl.function.subscript");
static UIdent KindRefSubscript("source.lang.swift.ref.function.subscript");
static UIdent KindDeclVarGlobal("source.lang.swift.decl.var.global");
static UIdent KindRefVarGlobal("source.lang.swift.ref.var.global");
static UIdent KindDeclVarInstance("source.lang.swift.decl.var.instance");
static UIdent KindRefVarInstance("source.lang.swift.ref.var.instance");
static UIdent KindDeclVarStatic("source.lang.swift.decl.var.static");
static UIdent KindRefVarStatic("source.lang.swift.ref.var.static");
static UIdent KindDeclVarClass("source.lang.swift.decl.var.class");
static UIdent KindRefVarClass("source.lang.swift.ref.var.class");
static UIdent KindDeclVarLocal("source.lang.swift.decl.var.local");
static UIdent KindRefVarLocal("source.lang.swift.ref.var.local");
static UIdent KindDeclVarParam("source.lang.swift.decl.var.parameter");
static UIdent KindDeclModule("source.lang.swift.decl.module");
static UIdent KindDeclClass("source.lang.swift.decl.class");
static UIdent KindRefClass("source.lang.swift.ref.class");
static UIdent KindDeclStruct("source.lang.swift.decl.struct");
static UIdent KindRefStruct("source.lang.swift.ref.struct");
static UIdent KindDeclEnum("source.lang.swift.decl.enum");
static UIdent KindRefEnum("source.lang.swift.ref.enum");
static UIdent KindDeclEnumCase("source.lang.swift.decl.enumcase");
static UIdent KindDeclEnumElement("source.lang.swift.decl.enumelement");
static UIdent KindRefEnumElement("source.lang.swift.ref.enumelement");
static UIdent KindDeclProtocol("source.lang.swift.decl.protocol");
static UIdent KindRefProtocol("source.lang.swift.ref.protocol");
static UIdent KindDeclExtension("source.lang.swift.decl.extension");
static UIdent KindDeclExtensionStruct("source.lang.swift.decl.extension.struct");
static UIdent KindDeclExtensionClass("source.lang.swift.decl.extension.class");
static UIdent KindDeclExtensionEnum("source.lang.swift.decl.extension.enum");
static UIdent KindDeclExtensionProtocol("source.lang.swift.decl.extension.protocol");
static UIdent KindDeclAssociatedType("source.lang.swift.decl.associatedtype");
static UIdent KindRefAssociatedType("source.lang.swift.ref.associatedtype");
static UIdent KindDeclTypeAlias("source.lang.swift.decl.typealias");
static UIdent KindRefTypeAlias("source.lang.swift.ref.typealias");
static UIdent KindDeclGenericTypeParam("source.lang.swift.decl.generic_type_param");
static UIdent KindRefGenericTypeParam("source.lang.swift.ref.generic_type_param");
static UIdent KindRefModule("source.lang.swift.ref.module");
static UIdent KindStmtForEach("source.lang.swift.stmt.foreach");
static UIdent KindStmtFor("source.lang.swift.stmt.for");
static UIdent KindStmtWhile("source.lang.swift.stmt.while");
static UIdent KindStmtRepeatWhile("source.lang.swift.stmt.repeatwhile");
static UIdent KindStmtIf("source.lang.swift.stmt.if");
static UIdent KindStmtGuard("source.lang.swift.stmt.guard");
static UIdent KindStmtSwitch("source.lang.swift.stmt.switch");
static UIdent KindStmtCase("source.lang.swift.stmt.case");
static UIdent KindStmtBrace("source.lang.swift.stmt.brace");
static UIdent KindExprCall("source.lang.swift.expr.call");
static UIdent KindExprArg("source.lang.swift.expr.argument");
static UIdent KindExprArray("source.lang.swift.expr.array");
static UIdent KindExprDictionary("source.lang.swift.expr.dictionary");
static UIdent KindExprObjectLiteral("source.lang.swift.expr.object_literal");
static UIdent KindStructureElemId("source.lang.swift.structure.elem.id");
static UIdent KindStructureElemExpr("source.lang.swift.structure.elem.expr");
static UIdent KindStructureElemInitExpr("source.lang.swift.structure.elem.init_expr");
static UIdent KindStructureElemCondExpr("source.lang.swift.structure.elem.condition_expr");
static UIdent KindStructureElemPattern("source.lang.swift.structure.elem.pattern");
static UIdent KindStructureElemTypeRef("source.lang.swift.structure.elem.typeref");
std::unique_ptr<LangSupport>
SourceKit::createSwiftLangSupport(SourceKit::Context &SKCtx) {
return std::unique_ptr<LangSupport>(new SwiftLangSupport(SKCtx));
}
const std::string LangSupport::SynthesizedUSRSeparator = "::SYNTHESIZED::";
namespace {
class UIdentVisitor : public ASTVisitor<UIdentVisitor,
UIdent, UIdent, UIdent, UIdent > {
const bool IsRef;
public:
explicit UIdentVisitor(bool IsRef) : IsRef(IsRef) { }
/// TODO: reconsider whether having a default case is a good idea.
UIdent visitDecl(const Decl *D) { return UIdent(); }
UIdent visitFuncDecl(const FuncDecl *D);
UIdent visitVarDecl(const VarDecl *D);
UIdent visitParamDecl(const ParamDecl *D);
UIdent visitExtensionDecl(const ExtensionDecl *D);
#define UID_FOR(CLASS) \
UIdent visit##CLASS##Decl(const CLASS##Decl *) { \
return IsRef ? KindRef##CLASS : KindDecl##CLASS; \
}
UID_FOR(Class)
UID_FOR(Struct)
UID_FOR(Enum)
UID_FOR(EnumElement)
UID_FOR(Protocol)
UID_FOR(TypeAlias)
UID_FOR(AssociatedType)
UID_FOR(GenericTypeParam)
UID_FOR(Constructor)
UID_FOR(Destructor)
UID_FOR(Subscript)
#undef UID_FOR
};
} // anonymous namespace
UIdent UIdentVisitor::visitFuncDecl(const FuncDecl *D) {
if (D->isAccessor()) {
return SwiftLangSupport::getUIDForAccessor(D->getAccessorStorageDecl(),
D->getAccessorKind(),
IsRef);
}
if (auto *Op = D->getOperatorDecl()) {
switch (Op->getKind()) {
case DeclKind::PrefixOperator:
return IsRef ? KindRefFunctionPrefixOperator : KindDeclFunctionPrefixOperator;
case DeclKind::PostfixOperator:
return IsRef ? KindRefFunctionPostfixOperator : KindDeclFunctionPostfixOperator;
case DeclKind::InfixOperator:
return IsRef ? KindRefFunctionInfixOperator : KindDeclFunctionInfixOperator;
default:
llvm_unreachable("unexpected operator kind");
}
}
const DeclContext *DC = D->getDeclContext();
if (DC->isTypeContext()) {
if (D->isStatic()) {
if (D->getCorrectStaticSpelling() == StaticSpellingKind::KeywordClass)
return IsRef ? KindRefMethodClass : KindDeclMethodClass;
else
return IsRef ? KindRefMethodStatic : KindDeclMethodStatic;
}
return IsRef ? KindRefMethodInstance : KindDeclMethodInstance;
}
return IsRef ? KindRefFunctionFree : KindDeclFunctionFree;
}
UIdent UIdentVisitor::visitVarDecl(const VarDecl *D) {
const DeclContext *DC = D->getDeclContext();
if (DC->isTypeContext()) {
if (D->isStatic()) {
if (D->getCorrectStaticSpelling() == StaticSpellingKind::KeywordClass)
return IsRef ? KindRefVarClass : KindDeclVarClass;
else
return IsRef ? KindRefVarStatic : KindDeclVarStatic;
}
return IsRef ? KindRefVarInstance : KindDeclVarInstance;
}
if (DC->isLocalContext())
return IsRef ? KindRefVarLocal : KindDeclVarLocal;
return IsRef ? KindRefVarGlobal : KindDeclVarGlobal;
}
UIdent UIdentVisitor::visitParamDecl(const ParamDecl *D) {
// There is no KindRefVarParam. It's not usually an interesting difference.
return IsRef ? KindRefVarLocal : KindDeclVarParam;
}
UIdent UIdentVisitor::visitExtensionDecl(const ExtensionDecl *D) {
assert(!IsRef && "reference to an extension ?");
if (NominalTypeDecl *NTD = D->getExtendedType()->getAnyNominal()) {
if (isa<StructDecl>(NTD))
return KindDeclExtensionStruct;
if (isa<ClassDecl>(NTD))
return KindDeclExtensionClass;
if (isa<EnumDecl>(NTD))
return KindDeclExtensionEnum;
if (isa<ProtocolDecl>(NTD))
return KindDeclExtensionProtocol;
}
return UIdent();
}
SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
: SKCtx(SKCtx), CCCache(new SwiftCompletionCache) {
llvm::SmallString<128> LibPath(SKCtx.getRuntimeLibPath());
llvm::sys::path::append(LibPath, "swift");
RuntimeResourcePath = LibPath.str();
ASTMgr.reset(new SwiftASTManager(*this));
// By default, just use the in-memory cache.
CCCache->inMemory = llvm::make_unique<ide::CodeCompletionCache>();
}
SwiftLangSupport::~SwiftLangSupport() {
}
UIdent SwiftLangSupport::getUIDForDecl(const Decl *D, bool IsRef) {
return UIdentVisitor(IsRef).visit(const_cast<Decl*>(D));
}
UIdent SwiftLangSupport::getUIDForExtensionOfDecl(const Decl *D) {
switch (D->getKind()) {
case swift::DeclKind::Struct:
return KindDeclExtensionStruct;
case swift::DeclKind::Enum:
return KindDeclExtensionEnum;
case swift::DeclKind::Class:
return KindDeclExtensionClass;
case swift::DeclKind::Protocol:
return KindDeclExtensionProtocol;
default:
llvm_unreachable("cannot have extension.");
}
}
UIdent SwiftLangSupport::getUIDForLocalVar(bool IsRef) {
return IsRef ? KindRefVarLocal : KindDeclVarLocal;
}
UIdent SwiftLangSupport::getUIDForAccessor(const ValueDecl *D,
AccessorKind AccKind,
bool IsRef) {
switch (AccKind) {
case AccessorKind::NotAccessor:
llvm_unreachable("expected accessor");
case AccessorKind::IsMaterializeForSet:
llvm_unreachable("unexpected MaterializeForSet");
case AccessorKind::IsGetter:
return IsRef ? KindRefAccessorGetter : KindDeclAccessorGetter;
case AccessorKind::IsSetter:
return IsRef ? KindRefAccessorSetter : KindDeclAccessorSetter;
case AccessorKind::IsWillSet:
return IsRef ? KindRefAccessorWillSet : KindDeclAccessorWillSet;
case AccessorKind::IsDidSet:
return IsRef ? KindRefAccessorDidSet : KindDeclAccessorDidSet;
case AccessorKind::IsAddressor:
return IsRef ? KindRefAccessorAddress : KindDeclAccessorAddress;
case AccessorKind::IsMutableAddressor:
return IsRef ? KindRefAccessorMutableAddress
: KindDeclAccessorMutableAddress;
}
}
SourceKit::UIdent SwiftLangSupport::getUIDForModuleRef() {
return KindRefModule;
}
UIdent SwiftLangSupport::getUIDForCodeCompletionDeclKind(
ide::CodeCompletionDeclKind Kind, bool IsRef) {
if (IsRef) {
// FIXME: The code-completion kind is also used for semantic annotations.
// We should either create a new kind or rename the code-completion kind to
// something more general.
switch (Kind) {
case CodeCompletionDeclKind::Module: return KindRefModule;
case CodeCompletionDeclKind::Class: return KindRefClass;
case CodeCompletionDeclKind::Struct: return KindRefStruct;
case CodeCompletionDeclKind::Enum: return KindRefEnum;
case CodeCompletionDeclKind::EnumElement: return KindRefEnumElement;
case CodeCompletionDeclKind::Protocol: return KindRefProtocol;
case CodeCompletionDeclKind::AssociatedType: return KindRefAssociatedType;
case CodeCompletionDeclKind::TypeAlias: return KindRefTypeAlias;
case CodeCompletionDeclKind::GenericTypeParam: return KindRefGenericTypeParam;
case CodeCompletionDeclKind::Constructor: return KindRefConstructor;
case CodeCompletionDeclKind::Destructor: return KindRefDestructor;
case CodeCompletionDeclKind::Subscript: return KindRefSubscript;
case CodeCompletionDeclKind::StaticMethod: return KindRefMethodClass;
case CodeCompletionDeclKind::InstanceMethod: return KindRefMethodInstance;
case CodeCompletionDeclKind::PrefixOperatorFunction: return KindRefFunctionPrefixOperator;
case CodeCompletionDeclKind::PostfixOperatorFunction: return KindRefFunctionPostfixOperator;
case CodeCompletionDeclKind::InfixOperatorFunction: return KindRefFunctionInfixOperator;
case CodeCompletionDeclKind::PrecedenceGroup: return KindRefPrecedenceGroup;
case CodeCompletionDeclKind::FreeFunction: return KindRefFunctionFree;
case CodeCompletionDeclKind::StaticVar: return KindRefVarClass;
case CodeCompletionDeclKind::InstanceVar: return KindRefVarInstance;
case CodeCompletionDeclKind::LocalVar: return KindRefVarLocal;
case CodeCompletionDeclKind::GlobalVar: return KindRefVarGlobal;
}
}
switch (Kind) {
case CodeCompletionDeclKind::Module: return KindDeclModule;
case CodeCompletionDeclKind::Class: return KindDeclClass;
case CodeCompletionDeclKind::Struct: return KindDeclStruct;
case CodeCompletionDeclKind::Enum: return KindDeclEnum;
case CodeCompletionDeclKind::EnumElement: return KindDeclEnumElement;
case CodeCompletionDeclKind::Protocol: return KindDeclProtocol;
case CodeCompletionDeclKind::AssociatedType: return KindDeclAssociatedType;
case CodeCompletionDeclKind::TypeAlias: return KindDeclTypeAlias;
case CodeCompletionDeclKind::GenericTypeParam: return KindDeclGenericTypeParam;
case CodeCompletionDeclKind::Constructor: return KindDeclConstructor;
case CodeCompletionDeclKind::Destructor: return KindDeclDestructor;
case CodeCompletionDeclKind::Subscript: return KindDeclSubscript;
case CodeCompletionDeclKind::StaticMethod: return KindDeclMethodClass;
case CodeCompletionDeclKind::InstanceMethod: return KindDeclMethodInstance;
case CodeCompletionDeclKind::PrefixOperatorFunction: return KindDeclFunctionPrefixOperator;
case CodeCompletionDeclKind::PostfixOperatorFunction: return KindDeclFunctionPostfixOperator;
case CodeCompletionDeclKind::InfixOperatorFunction: return KindDeclFunctionInfixOperator;
case CodeCompletionDeclKind::PrecedenceGroup: return KindDeclPrecedenceGroup;
case CodeCompletionDeclKind::FreeFunction: return KindDeclFunctionFree;
case CodeCompletionDeclKind::StaticVar: return KindDeclVarClass;
case CodeCompletionDeclKind::InstanceVar: return KindDeclVarInstance;
case CodeCompletionDeclKind::LocalVar: return KindDeclVarLocal;
case CodeCompletionDeclKind::GlobalVar: return KindDeclVarGlobal;
}
}
UIdent SwiftLangSupport::getUIDForSyntaxNodeKind(SyntaxNodeKind SC) {
static UIdent KindKeyword("source.lang.swift.syntaxtype.keyword");
static UIdent KindIdentifier("source.lang.swift.syntaxtype.identifier");
static UIdent KindTypeIdentifier("source.lang.swift.syntaxtype.typeidentifier");
static UIdent KindBuildConfigKeyword("source.lang.swift.syntaxtype.buildconfig.keyword");
static UIdent KindBuildConfigId("source.lang.swift.syntaxtype.buildconfig.id");
static UIdent KindAttributeId("source.lang.swift.syntaxtype.attribute.id");
static UIdent KindAttributeBuiltin("source.lang.swift.syntaxtype.attribute.builtin");
static UIdent KindNumber("source.lang.swift.syntaxtype.number");
static UIdent KindString("source.lang.swift.syntaxtype.string");
static UIdent KindStringInterpolation("source.lang.swift.syntaxtype.string_interpolation_anchor");
static UIdent KindComment("source.lang.swift.syntaxtype.comment");
static UIdent KindDocComment("source.lang.swift.syntaxtype.doccomment");
static UIdent KindDocCommentField("source.lang.swift.syntaxtype.doccomment.field");
static UIdent KindCommentMarker("source.lang.swift.syntaxtype.comment.mark");
static UIdent KindCommentURL("source.lang.swift.syntaxtype.comment.url");
static UIdent KindPlaceholder("source.lang.swift.syntaxtype.placeholder");
static UIdent KindObjectLiteral("source.lang.swift.syntaxtype.objectliteral");
switch (SC) {
case SyntaxNodeKind::Keyword:
return KindKeyword;
case SyntaxNodeKind::Identifier:
case SyntaxNodeKind::DollarIdent:
return KindIdentifier;
case SyntaxNodeKind::Integer:
case SyntaxNodeKind::Floating:
return KindNumber;
case SyntaxNodeKind::String:
return KindString;
case SyntaxNodeKind::StringInterpolationAnchor:
return KindStringInterpolation;
case SyntaxNodeKind::CommentLine:
case SyntaxNodeKind::CommentBlock:
return KindComment;
case SyntaxNodeKind::CommentMarker:
return KindCommentMarker;
case SyntaxNodeKind::CommentURL:
return KindCommentURL;
case SyntaxNodeKind::DocCommentLine:
case SyntaxNodeKind::DocCommentBlock:
return KindDocComment;
case SyntaxNodeKind::DocCommentField:
return KindDocCommentField;
case SyntaxNodeKind::TypeId:
return KindTypeIdentifier;
case SyntaxNodeKind::BuildConfigKeyword:
return KindBuildConfigKeyword;
case SyntaxNodeKind::BuildConfigId:
return KindBuildConfigId;
case SyntaxNodeKind::AttributeId:
return KindAttributeId;
case SyntaxNodeKind::AttributeBuiltin:
return KindAttributeBuiltin;
case SyntaxNodeKind::EditorPlaceholder:
return KindPlaceholder;
case SyntaxNodeKind::ObjectLiteral:
return KindObjectLiteral;
}
}
UIdent SwiftLangSupport::getUIDForSyntaxStructureKind(
SyntaxStructureKind Kind) {
switch (Kind) {
case SyntaxStructureKind::Class:
return KindDeclClass;
case SyntaxStructureKind::Struct:
return KindDeclStruct;
case SyntaxStructureKind::Protocol:
return KindDeclProtocol;
case SyntaxStructureKind::Enum:
return KindDeclEnum;
case SyntaxStructureKind::Extension:
return KindDeclExtension;
case SyntaxStructureKind::FreeFunction:
return KindDeclFunctionFree;
case SyntaxStructureKind::InstanceFunction:
return KindDeclMethodInstance;
case SyntaxStructureKind::StaticFunction:
return KindDeclMethodStatic;
case SyntaxStructureKind::ClassFunction:
return KindDeclMethodClass;
case SyntaxStructureKind::GlobalVariable:
return KindDeclVarGlobal;
case SyntaxStructureKind::InstanceVariable:
return KindDeclVarInstance;
case SyntaxStructureKind::StaticVariable:
return KindDeclVarStatic;
case SyntaxStructureKind::ClassVariable:
return KindDeclVarClass;
case SyntaxStructureKind::EnumCase:
return KindDeclEnumCase;
case SyntaxStructureKind::EnumElement:
return KindDeclEnumElement;
case SyntaxStructureKind::Parameter:
return KindDeclVarParam;
case SyntaxStructureKind::ForEachStatement:
return KindStmtForEach;
case SyntaxStructureKind::ForStatement:
return KindStmtFor;
case SyntaxStructureKind::WhileStatement:
return KindStmtWhile;
case SyntaxStructureKind::RepeatWhileStatement:
return KindStmtRepeatWhile;
case SyntaxStructureKind::IfStatement:
return KindStmtIf;
case SyntaxStructureKind::GuardStatement:
return KindStmtGuard;
case SyntaxStructureKind::SwitchStatement:
return KindStmtSwitch;
case SyntaxStructureKind::CaseStatement:
return KindStmtCase;
case SyntaxStructureKind::BraceStatement:
return KindStmtBrace;
case SyntaxStructureKind::CallExpression:
return KindExprCall;
case SyntaxStructureKind::ArrayExpression:
return KindExprArray;
case SyntaxStructureKind::DictionaryExpression:
return KindExprDictionary;
case SyntaxStructureKind::ObjectLiteralExpression:
return KindExprObjectLiteral;
case SyntaxStructureKind::Argument:
return KindExprArg;
}
}
UIdent SwiftLangSupport::getUIDForSyntaxStructureElementKind(
SyntaxStructureElementKind Kind) {
switch (Kind) {
case SyntaxStructureElementKind::Id: return KindStructureElemId;
case SyntaxStructureElementKind::Expr: return KindStructureElemExpr;
case SyntaxStructureElementKind::InitExpr: return KindStructureElemInitExpr;
case SyntaxStructureElementKind::ConditionExpr: return KindStructureElemCondExpr;
case SyntaxStructureElementKind::Pattern: return KindStructureElemPattern;
case SyntaxStructureElementKind::TypeRef: return KindStructureElemTypeRef;
}
}
UIdent SwiftLangSupport::getUIDForSymbol(SymbolKind kind, SymbolSubKindSet subKinds,
bool isRef) {
#define UID_FOR(CLASS) isRef ? KindRef##CLASS : KindDecl##CLASS;
#define SIMPLE_CASE(KIND) \
case SymbolKind::KIND: \
return UID_FOR(KIND);
switch (kind) {
SIMPLE_CASE(Enum)
SIMPLE_CASE(Struct)
SIMPLE_CASE(Class)
SIMPLE_CASE(Protocol)
SIMPLE_CASE(TypeAlias)
SIMPLE_CASE(AssociatedType)
SIMPLE_CASE(GenericTypeParam)
SIMPLE_CASE(Subscript)
SIMPLE_CASE(EnumElement)
SIMPLE_CASE(Constructor)
SIMPLE_CASE(Destructor)
case SymbolKind::Function:
return UID_FOR(FunctionFree);
case SymbolKind::PrefixOperator:
return UID_FOR(FunctionPrefixOperator);
case SymbolKind::PostfixOperator:
return UID_FOR(FunctionPostfixOperator);
case SymbolKind::InfixOperator:
return UID_FOR(FunctionInfixOperator);
case SymbolKind::Variable:
return UID_FOR(VarGlobal);
case SymbolKind::InstanceMethod:
return UID_FOR(MethodInstance);
case SymbolKind::ClassMethod:
return UID_FOR(MethodClass);
case SymbolKind::StaticMethod:
return UID_FOR(MethodStatic);
case SymbolKind::InstanceProperty:
return UID_FOR(VarInstance);
case SymbolKind::ClassProperty:
return UID_FOR(VarClass);
case SymbolKind::StaticProperty:
return UID_FOR(VarStatic);
case SymbolKind::Extension:
assert(!isRef && "reference to extension decl?");
SWIFT_FALLTHROUGH;
case SymbolKind::Accessor:
if (subKinds & SymbolSubKind::AccessorGetter) {
return UID_FOR(AccessorGetter);
} else if (subKinds & SymbolSubKind::AccessorSetter) {
return UID_FOR(AccessorSetter);
} else if (subKinds & SymbolSubKind::AccessorWillSet) {
return UID_FOR(AccessorWillSet);
} else if (subKinds & SymbolSubKind::AccessorDidSet) {
return UID_FOR(AccessorDidSet);
} else if (subKinds & SymbolSubKind::AccessorAddressor) {
return UID_FOR(AccessorAddress);
} else if (subKinds & SymbolSubKind::AccessorMutableAddressor) {
return UID_FOR(AccessorMutableAddress);
} else if (subKinds & SymbolSubKind::ExtensionOfStruct) {
return KindDeclExtensionStruct;
} else if (subKinds & SymbolSubKind::ExtensionOfClass) {
return KindDeclExtensionClass;
} else if (subKinds & SymbolSubKind::ExtensionOfEnum) {
return KindDeclExtensionEnum;
} else if (subKinds & SymbolSubKind::ExtensionOfProtocol) {
return KindDeclExtensionProtocol;
} else {
llvm_unreachable("missing sub kind");
}
default:
// TODO: reconsider whether having a default case is a good idea.
return UIdent();
}
#undef SIMPLE_CASE
#undef UID_FOR
}
std::vector<UIdent> SwiftLangSupport::UIDsFromDeclAttributes(const DeclAttributes &Attrs) {
std::vector<UIdent> AttrUIDs;
#define ATTR(X) \
if (Attrs.has(AK_##X)) { \
static UIdent Attr_##X("source.decl.attribute."#X); \
AttrUIDs.push_back(Attr_##X); \
}
#include "swift/AST/Attr.def"
for (auto Attr : Attrs) {
// Check special-case names first.
switch (Attr->getKind()) {
case DAK_IBAction: {
static UIdent Attr_IBAction("source.decl.attribute.ibaction");
AttrUIDs.push_back(Attr_IBAction);
continue;
}
case DAK_IBOutlet: {
static UIdent Attr_IBOutlet("source.decl.attribute.iboutlet");
AttrUIDs.push_back(Attr_IBOutlet);
continue;
}
case DAK_IBDesignable: {
static UIdent Attr_IBDesignable("source.decl.attribute.ibdesignable");
AttrUIDs.push_back(Attr_IBDesignable);
continue;
}
case DAK_IBInspectable: {
static UIdent Attr_IBInspectable("source.decl.attribute.ibinspectable");
AttrUIDs.push_back(Attr_IBInspectable);
continue;
}
case DAK_GKInspectable: {
static UIdent Attr_GKInspectable("source.decl.attribute.gkinspectable");
AttrUIDs.push_back(Attr_GKInspectable);
continue;
}
case DAK_ObjC: {
static UIdent Attr_Objc("source.decl.attribute.objc");
static UIdent Attr_ObjcNamed("source.decl.attribute.objc.name");
if (cast<ObjCAttr>(Attr)->hasName()) {
AttrUIDs.push_back(Attr_ObjcNamed);
} else {
AttrUIDs.push_back(Attr_Objc);
}
continue;
}
// We handle accessibility explicitly.
case DAK_Accessibility:
case DAK_SetterAccessibility:
// Ignore these.
case DAK_ShowInInterface:
case DAK_RawDocComment:
continue;
default:
break;
}
switch (Attr->getKind()) {
case DAK_Count:
break;
#define DECL_ATTR(X, CLASS, ...)\
case DAK_##CLASS: {\
static UIdent Attr_##X("source.decl.attribute."#X); \
AttrUIDs.push_back(Attr_##X); \
break;\
}
#include "swift/AST/Attr.def"
}
}
return AttrUIDs;
}
bool SwiftLangSupport::printDisplayName(const swift::ValueDecl *D,
llvm::raw_ostream &OS) {
if (!D->hasName())
return true;
OS << D->getFullName();
return false;
}
bool SwiftLangSupport::printUSR(const ValueDecl *D, llvm::raw_ostream &OS) {
return ide::printDeclUSR(D, OS);
}
bool SwiftLangSupport::printDeclTypeUSR(const ValueDecl *D, llvm::raw_ostream &OS) {
return ide::printDeclTypeUSR(D, OS);
}
bool SwiftLangSupport::printTypeUSR(Type Ty, llvm::raw_ostream &OS) {
return ide::printTypeUSR(Ty, OS);
}
bool SwiftLangSupport::printAccessorUSR(const AbstractStorageDecl *D,
AccessorKind AccKind,
llvm::raw_ostream &OS) {
return ide::printAccessorUSR(D, AccKind, OS);
}
std::string SwiftLangSupport::resolvePathSymlinks(StringRef FilePath) {
std::string InputPath = FilePath;
char full_path[MAXPATHLEN];
if (const char *path = realpath(InputPath.c_str(), full_path))
return path;
return InputPath;
}
CloseClangModuleFiles::~CloseClangModuleFiles() {
clang::Preprocessor &PP = loader.getClangPreprocessor();
clang::ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
for (auto I = ModMap.module_begin(), E = ModMap.module_end(); I != E; ++I) {
clang::Module *M = I->second;
if (!M->isSubModule() && M->getASTFile())
M->getASTFile()->closeFile();
}
}