[SourceKit] Accept swift_version in requests and use to set the swift version for interface generation of an ObjC header

rdar://31432960
This commit is contained in:
Argyrios Kyrtzidis
2017-05-04 16:53:00 -07:00
parent 0db10e9b60
commit 896c4645df
15 changed files with 302 additions and 8 deletions

View File

@@ -3,3 +3,7 @@ typedef struct {
long width;
long height;
} NUPixelSize;
#if __swift__ >= 40000
void show_only_for_swift_4(void);
#endif

View File

@@ -5,5 +5,9 @@
// RUN: rm %t.m
// RUN: echo '#include "header2.h"' > %t.m
// RUN: %sourcekitd-test -req=interface-gen -header %S/Inputs/header2.h -- -fsyntax-only %t.m -I %S/Inputs > %t.header2.response
// RUN: %sourcekitd-test -req=interface-gen -header %S/Inputs/header2.h -swift-version=3 -- -fsyntax-only %t.m -I %S/Inputs > %t.header2.response
// RUN: diff -u %s.header2.response %t.header2.response
// RUN: echo '#include "header2.h"' > %t.m
// RUN: %sourcekitd-test -req=interface-gen -header %S/Inputs/header2.h -swift-version=4 -- -fsyntax-only %t.m -I %S/Inputs > %t.header2.swift4.response
// RUN: diff -u %s.header2.swift4.response %t.header2.swift4.response

View File

@@ -0,0 +1,236 @@
public struct NUPixelSize {
public var width: Int
public var height: Int
public init()
public init(width: Int, height: Int)
}
public func show_only_for_swift_4()
[
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 1,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 8,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 15,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 34,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 41,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 45,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 52,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 61,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 68,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 72,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 80,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 89,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 96,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 108,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 115,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 120,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 127,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 132,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 140,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 148,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 155,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 160,
key.length: 21
}
]
[
{
key.kind: source.lang.swift.ref.struct,
key.offset: 52,
key.length: 3,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 80,
key.length: 3,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 127,
key.length: 3,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 140,
key.length: 3,
key.is_system: 1
}
]
[
{
key.kind: source.lang.swift.decl.struct,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "NUPixelSize",
key.offset: 8,
key.length: 138,
key.nameoffset: 15,
key.namelength: 11,
key.bodyoffset: 28,
key.bodylength: 117,
key.substructure: [
{
key.kind: source.lang.swift.decl.var.instance,
key.accessibility: source.lang.swift.accessibility.public,
key.setter_accessibility: source.lang.swift.accessibility.public,
key.name: "width",
key.offset: 41,
key.length: 14,
key.typename: "Int",
key.nameoffset: 45,
key.namelength: 5
},
{
key.kind: source.lang.swift.decl.var.instance,
key.accessibility: source.lang.swift.accessibility.public,
key.setter_accessibility: source.lang.swift.accessibility.public,
key.name: "height",
key.offset: 68,
key.length: 15,
key.typename: "Int",
key.nameoffset: 72,
key.namelength: 6
},
{
key.kind: source.lang.swift.decl.function.method.instance,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "init()",
key.offset: 96,
key.length: 6,
key.nameoffset: 96,
key.namelength: 6
},
{
key.kind: source.lang.swift.decl.function.method.instance,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "init(width:height:)",
key.offset: 115,
key.length: 29,
key.nameoffset: 115,
key.namelength: 29,
key.substructure: [
{
key.kind: source.lang.swift.decl.var.parameter,
key.name: "width",
key.offset: 120,
key.length: 10,
key.typename: "Int",
key.nameoffset: 120,
key.namelength: 5
},
{
key.kind: source.lang.swift.decl.var.parameter,
key.name: "height",
key.offset: 132,
key.length: 11,
key.typename: "Int",
key.nameoffset: 132,
key.namelength: 6
}
]
}
]
},
{
key.kind: source.lang.swift.decl.function.free,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "show_only_for_swift_4()",
key.offset: 155,
key.length: 28,
key.nameoffset: 160,
key.namelength: 23
}
]

View File

@@ -443,7 +443,8 @@ public:
StringRef Name,
StringRef HeaderName,
ArrayRef<const char *> Args,
bool SynthesizedExtensions) = 0;
bool SynthesizedExtensions,
Optional<unsigned> swiftVersion) = 0;
virtual void editorOpenSwiftSourceInterface(StringRef Name,
StringRef SourceName,

View File

@@ -16,6 +16,7 @@
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/ASTWalker.h"
#include "swift/Basic/Version.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/IDE/ModuleInterfacePrinting.h"
@@ -800,7 +801,8 @@ void SwiftLangSupport::editorOpenHeaderInterface(EditorConsumer &Consumer,
StringRef Name,
StringRef HeaderName,
ArrayRef<const char *> Args,
bool SynthesizedExtensions) {
bool SynthesizedExtensions,
Optional<unsigned> swiftVersion) {
CompilerInstance CI;
// Display diagnostics to stderr.
PrintingDiagnosticConsumer PrintDiags;
@@ -831,6 +833,10 @@ void SwiftLangSupport::editorOpenHeaderInterface(EditorConsumer &Consumer,
}
Invocation.getClangImporterOptions().ImportForwardDeclarations = true;
if (swiftVersion.hasValue()) {
auto swiftVer = version::Version({swiftVersion.getValue()});
Invocation.getLangOptions().EffectiveLanguageVersion = swiftVer;
}
auto IFaceGenRef = SwiftInterfaceGenContext::create(Name,
/*IsModule=*/false,
HeaderName,

View File

@@ -358,7 +358,8 @@ public:
StringRef Name,
StringRef HeaderName,
ArrayRef<const char *> Args,
bool SynthesizedExtensions) override;
bool SynthesizedExtensions,
Optional<unsigned> swiftVersion) override;
void editorOpenSwiftSourceInterface(StringRef Name,
StringRef SourceName,

View File

@@ -94,6 +94,9 @@ def async : Flag<["-"], "async">,
def end_pos : Separate<["-"], "end-pos">, HelpText<"line:col">;
def end_pos_EQ : Joined<["-"], "end-pos=">, Alias<end_pos>;
def swift_version : Separate<["-"], "swift-version">, HelpText<"the swift version to use">;
def swift_version_EQ : Joined<["-"], "swift-version=">, Alias<swift_version>;
def swift_name : Separate<["-"], "swift-name">,
HelpText<"Swift name to translate from">;

View File

@@ -179,6 +179,16 @@ bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
break;
}
case OPT_swift_version: {
unsigned ver;
if (StringRef(InputArg->getValue()).getAsInteger(10, ver)) {
llvm::errs() << "error: expected integer for 'swift-version'\n";
return true;
}
SwiftVersion = ver;
break;
}
case OPT_line:
if (StringRef(InputArg->getValue()).getAsInteger(10, Line)) {
llvm::errs() << "error: expected integer for 'line'\n";

View File

@@ -69,6 +69,7 @@ struct TestOptions {
unsigned EndCol = 0;
unsigned Offset = 0;
unsigned Length = 0;
llvm::Optional<unsigned> SwiftVersion;
llvm::Optional<std::string> ReplaceText;
std::string ModuleName;
std::string HeaderPath;

View File

@@ -140,6 +140,7 @@ static sourcekitd_uid_t KeyBaseName;
static sourcekitd_uid_t KeyArgNames;
static sourcekitd_uid_t KeySelectorPieces;
static sourcekitd_uid_t KeyNameKind;
static sourcekitd_uid_t KeySwiftVersion;
static sourcekitd_uid_t RequestProtocolVersion;
static sourcekitd_uid_t RequestDemangle;
@@ -271,6 +272,8 @@ static int skt_main(int argc, const char **argv) {
KeySelectorPieces = sourcekitd_uid_get_from_cstr("key.selectorpieces");
KeyNameKind = sourcekitd_uid_get_from_cstr("key.namekind");
KeySwiftVersion = sourcekitd_uid_get_from_cstr("key.swift_version");
SemaDiagnosticStage = sourcekitd_uid_get_from_cstr("source.diagnostic.stage.swift.sema");
NoteDocUpdate = sourcekitd_uid_get_from_cstr("source.notification.editor.documentupdate");
@@ -826,6 +829,11 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
Opts.HeaderPath.c_str());
}
if (Opts.SwiftVersion.hasValue()) {
sourcekitd_request_dictionary_set_int64(Req, KeySwiftVersion,
Opts.SwiftVersion.getValue());
}
if (Opts.PrintRequest)
sourcekitd_request_description_dump(Req);

View File

@@ -142,6 +142,7 @@ public:
llvm::function_ref<bool(RequestDict)> applier);
bool getInt64(SourceKit::UIdent Key, int64_t &Val, bool isOptional);
Optional<int64_t> getOptionalInt64(SourceKit::UIdent Key);
};
void initialize();

View File

@@ -132,6 +132,8 @@ extern SourceKit::UIdent KeySelectorPieces;
extern SourceKit::UIdent KeyNameKind;
extern SourceKit::UIdent KeyLocalizationKey;
extern SourceKit::UIdent KeySwiftVersion;
/// \brief Used for determining the printing order of dictionary keys.
bool compareDictKeys(SourceKit::UIdent LHS, SourceKit::UIdent RHS);

View File

@@ -225,7 +225,8 @@ editorOpenInterface(StringRef Name, StringRef ModuleName,
static sourcekitd_response_t
editorOpenHeaderInterface(StringRef Name, StringRef HeaderName,
ArrayRef<const char *> Args,
bool SynthesizedExtensions);
bool SynthesizedExtensions,
Optional<unsigned> swiftVersion);
static void
editorOpenSwiftSourceInterface(StringRef Name, StringRef SourceName,
@@ -524,8 +525,12 @@ void handleRequestImpl(sourcekitd_object_t ReqObj, ResponseReceiver Rec) {
int64_t SynthesizedExtension = false;
Req.getInt64(KeySynthesizedExtension, SynthesizedExtension,
/*isOptional=*/true);
Optional<int64_t> swiftVerVal = Req.getOptionalInt64(KeySwiftVersion);
Optional<unsigned> swiftVer;
if (swiftVerVal.hasValue())
swiftVer = *swiftVerVal;
return Rec(editorOpenHeaderInterface(*Name, *HeaderName, Args,
SynthesizedExtension));
SynthesizedExtension, swiftVer));
}
if (ReqUID == RequestEditorOpenSwiftSourceInterface) {
@@ -2016,14 +2021,15 @@ static sourcekitd_response_t editorConvertMarkupToXML(StringRef Source) {
static sourcekitd_response_t
editorOpenHeaderInterface(StringRef Name, StringRef HeaderName,
ArrayRef<const char *> Args,
bool SynthesizedExtensions) {
bool SynthesizedExtensions,
Optional<unsigned> swiftVersion) {
SKEditorConsumer EditC(/*EnableSyntaxMap=*/true,
/*EnableStructure=*/true,
/*EnableDiagnostics=*/false,
/*SyntacticOnly=*/false);
LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
Lang.editorOpenHeaderInterface(EditC, Name, HeaderName, Args,
SynthesizedExtensions);
SynthesizedExtensions, swiftVersion);
return EditC.createResponse();
}

View File

@@ -145,6 +145,8 @@ UIdent sourcekitd::KeySelectorPieces("key.selectorpieces");
UIdent sourcekitd::KeyNameKind("key.namekind");
UIdent sourcekitd::KeyLocalizationKey("key.localization_key");
UIdent sourcekitd::KeySwiftVersion("key.swift_version");
/// \brief Order for the keys to use when emitting the debug description of
/// dictionaries.
static UIdent *OrderedKeys[] = {
@@ -243,7 +245,9 @@ static UIdent *OrderedKeys[] = {
&KeyArgNames,
&KeySelectorPieces,
&KeyNameKind,
&KeyLocalizationKey,
&KeySwiftVersion,
};
static unsigned findPrintOrderForDictKey(UIdent Key) {

View File

@@ -351,6 +351,13 @@ bool RequestDict::getInt64(SourceKit::UIdent Key, int64_t &Val,
return false;
}
Optional<int64_t> RequestDict::getOptionalInt64(SourceKit::UIdent Key) {
xpc_object_t xobj = xpc_dictionary_get_value(Dict, Key.c_str());
if (!xobj)
return None;
return xpc_int64_get_value(xobj);
}
sourcekitd_response_t
sourcekitd::createErrorRequestInvalid(const char *Description) {
return CustomXPCData::createErrorRequestInvalid(Description).getXObj();