mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Re-apply "SwiftSyntax: Teach SwiftSyntax to use SourceKitd to serialize syntax trees. (#14424)" (#14465)
This commit is contained in:
@@ -11,6 +11,8 @@ set_property(GLOBAL PROPERTY JOB_POOLS local_jobs=${localhost_logical_cores})
|
|||||||
# Put linking in that category
|
# Put linking in that category
|
||||||
set_property(GLOBAL PROPERTY JOB_POOL_LINK local_jobs)
|
set_property(GLOBAL PROPERTY JOB_POOL_LINK local_jobs)
|
||||||
|
|
||||||
|
ENABLE_LANGUAGE(C)
|
||||||
|
|
||||||
# First include general CMake utilities.
|
# First include general CMake utilities.
|
||||||
include(SwiftUtils)
|
include(SwiftUtils)
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
@@ -748,10 +750,10 @@ if(swift_build_android AND NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
|
|||||||
|
|
||||||
set(SWIFT_ANDROID_PREBUILT_PATH
|
set(SWIFT_ANDROID_PREBUILT_PATH
|
||||||
"${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_GCC_VERSION}/prebuilt/${_swift_android_prebuilt_suffix}")
|
"${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_GCC_VERSION}/prebuilt/${_swift_android_prebuilt_suffix}")
|
||||||
|
|
||||||
# Resolve the correct linker based on the file name of CMAKE_LINKER (being 'ld' or 'ld.gold' the options)
|
# Resolve the correct linker based on the file name of CMAKE_LINKER (being 'ld' or 'ld.gold' the options)
|
||||||
get_filename_component(SWIFT_ANDROID_LINKER_NAME "${CMAKE_LINKER}" NAME)
|
get_filename_component(SWIFT_ANDROID_LINKER_NAME "${CMAKE_LINKER}" NAME)
|
||||||
set(SWIFT_SDK_ANDROID_ARCH_armv7_LINKER
|
set(SWIFT_SDK_ANDROID_ARCH_armv7_LINKER
|
||||||
"${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_GCC_VERSION}/prebuilt/${_swift_android_prebuilt_suffix}/bin/arm-linux-androideabi-${SWIFT_ANDROID_LINKER_NAME}")
|
"${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_GCC_VERSION}/prebuilt/${_swift_android_prebuilt_suffix}/bin/arm-linux-androideabi-${SWIFT_ANDROID_LINKER_NAME}")
|
||||||
|
|
||||||
configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi" "${SWIFT_ANDROID_SDK_PATH}")
|
configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi" "${SWIFT_ANDROID_SDK_PATH}")
|
||||||
@@ -879,7 +881,7 @@ endif()
|
|||||||
###############
|
###############
|
||||||
#
|
#
|
||||||
# We have to include stdlib/ before tools/.
|
# We have to include stdlib/ before tools/.
|
||||||
# Do not move add_subdirectory(stdlib) after add_subdirectory(tools)!
|
# Do not move add_subdirectory(stdlib) after add_subdirectory(tools)!
|
||||||
#
|
#
|
||||||
# We must include stdlib/ before tools/ because stdlib/CMakeLists.txt
|
# We must include stdlib/ before tools/ because stdlib/CMakeLists.txt
|
||||||
# declares the swift-stdlib-* set of targets. These targets will then
|
# declares the swift-stdlib-* set of targets. These targets will then
|
||||||
@@ -898,7 +900,7 @@ add_subdirectory(stdlib)
|
|||||||
if(SWIFT_INCLUDE_TOOLS)
|
if(SWIFT_INCLUDE_TOOLS)
|
||||||
add_subdirectory(include)
|
add_subdirectory(include)
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
|
|
||||||
# Always include this after including stdlib/!
|
# Always include this after including stdlib/!
|
||||||
# Refer to the large comment above the add_subdirectory(stdlib) call.
|
# Refer to the large comment above the add_subdirectory(stdlib) call.
|
||||||
# https://bugs.swift.org/browse/SR-5975
|
# https://bugs.swift.org/browse/SR-5975
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ function(_add_variant_c_compile_flags)
|
|||||||
else()
|
else()
|
||||||
list(APPEND result "-DNDEBUG")
|
list(APPEND result "-DNDEBUG")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS)
|
if(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS)
|
||||||
list(APPEND result "-DSWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS")
|
list(APPEND result "-DSWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS")
|
||||||
endif()
|
endif()
|
||||||
@@ -320,7 +320,7 @@ function(_add_variant_swift_compile_flags
|
|||||||
if (SWIFT_ENABLE_GUARANTEED_NORMAL_ARGUMENTS)
|
if (SWIFT_ENABLE_GUARANTEED_NORMAL_ARGUMENTS)
|
||||||
list(APPEND result "-Xfrontend" "-enable-guaranteed-normal-arguments")
|
list(APPEND result "-Xfrontend" "-enable-guaranteed-normal-arguments")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS)
|
if(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS)
|
||||||
list(APPEND result "-D" "SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS")
|
list(APPEND result "-D" "SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS")
|
||||||
endif()
|
endif()
|
||||||
@@ -1605,7 +1605,7 @@ function(add_swift_library name)
|
|||||||
if(SWIFTLIB_IS_SDK_OVERLAY)
|
if(SWIFTLIB_IS_SDK_OVERLAY)
|
||||||
list(APPEND swiftlib_swift_compile_flags_all "-Fsystem" "${SWIFT_SDK_${sdk}_PATH}/System/Library/PrivateFrameworks/")
|
list(APPEND swiftlib_swift_compile_flags_all "-Fsystem" "${SWIFT_SDK_${sdk}_PATH}/System/Library/PrivateFrameworks/")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if("${sdk}" STREQUAL "IOS_SIMULATOR")
|
if("${sdk}" STREQUAL "IOS_SIMULATOR")
|
||||||
if("${name}" STREQUAL "swiftMediaPlayer")
|
if("${name}" STREQUAL "swiftMediaPlayer")
|
||||||
message("DISABLING AUTOLINK FOR swiftMediaPlayer")
|
message("DISABLING AUTOLINK FOR swiftMediaPlayer")
|
||||||
@@ -1854,7 +1854,7 @@ function(add_swift_library name)
|
|||||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||||
RUNTIME DESTINATION bin)
|
RUNTIME DESTINATION bin)
|
||||||
swift_is_installing_component(dev is_installing)
|
swift_is_installing_component(dev is_installing)
|
||||||
|
|
||||||
if(NOT is_installing)
|
if(NOT is_installing)
|
||||||
set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${name})
|
set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${name})
|
||||||
else()
|
else()
|
||||||
@@ -2177,7 +2177,7 @@ function(add_swift_host_tool executable)
|
|||||||
|
|
||||||
swift_is_installing_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
|
swift_is_installing_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
|
||||||
is_installing)
|
is_installing)
|
||||||
|
|
||||||
if(NOT is_installing)
|
if(NOT is_installing)
|
||||||
set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${executable})
|
set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${executable})
|
||||||
else()
|
else()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import StdlibUnittest
|
import StdlibUnittest
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftSyntax
|
import SwiftSyntax
|
||||||
|
import SwiftSourceKit
|
||||||
|
|
||||||
func getInput(_ file: String) -> URL {
|
func getInput(_ file: String) -> URL {
|
||||||
var result = URL(fileURLWithPath: #file)
|
var result = URL(fileURLWithPath: #file)
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// REQUIRES: executable_test
|
// REQUIRES: executable_test
|
||||||
// REQUIRES: OS=macosx
|
// REQUIRES: OS=macosx
|
||||||
// REQUIRES: objc_interop
|
// REQUIRES: objc_interop
|
||||||
// REQUIRES: rdar36740859
|
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import StdlibUnittest
|
import StdlibUnittest
|
||||||
import SwiftSyntax
|
import SwiftSyntax
|
||||||
|
import SwiftSourceKit
|
||||||
|
|
||||||
var ParseFile = TestSuite("ParseFile")
|
var ParseFile = TestSuite("ParseFile")
|
||||||
|
|
||||||
@@ -31,7 +31,8 @@ ParseFile.test("ParseSingleFile") {
|
|||||||
let currentFile = URL(fileURLWithPath: #file)
|
let currentFile = URL(fileURLWithPath: #file)
|
||||||
expectDoesNotThrow({
|
expectDoesNotThrow({
|
||||||
let currentFileContents = try String(contentsOf: currentFile)
|
let currentFileContents = try String(contentsOf: currentFile)
|
||||||
let parsed = try SourceFileSyntax.parse(currentFile)
|
let parsed = try SourceFileSyntax.decodeSourceFileSyntax(try
|
||||||
|
SourceKitdService.encodeSourceFileSyntax(currentFile))
|
||||||
expectEqual("\(parsed)", currentFileContents)
|
expectEqual("\(parsed)", currentFileContents)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,10 @@
|
|||||||
// REQUIRES: OS=macosx
|
// REQUIRES: OS=macosx
|
||||||
// REQUIRES: objc_interop
|
// REQUIRES: objc_interop
|
||||||
|
|
||||||
// FIXME: This test fails occassionally in CI with invalid json.
|
|
||||||
// REQUIRES: disabled
|
|
||||||
|
|
||||||
import StdlibUnittest
|
import StdlibUnittest
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftSyntax
|
import SwiftSyntax
|
||||||
|
import SwiftSourceKit
|
||||||
|
|
||||||
func getInput(_ file: String) -> URL {
|
func getInput(_ file: String) -> URL {
|
||||||
var result = URL(fileURLWithPath: #file)
|
var result = URL(fileURLWithPath: #file)
|
||||||
@@ -29,7 +27,8 @@ VisitorTests.test("Basic") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expectDoesNotThrow({
|
expectDoesNotThrow({
|
||||||
let parsed = try SourceFileSyntax.parse(getInput("visitor.swift"))
|
let parsed = try SourceFileSyntax.decodeSourceFileSyntax(try
|
||||||
|
SourceKitdService.encodeSourceFileSyntax(getInput("visitor.swift")))
|
||||||
let counter = FuncCounter()
|
let counter = FuncCounter()
|
||||||
let hashBefore = parsed.hashValue
|
let hashBefore = parsed.hashValue
|
||||||
counter.visit(parsed)
|
counter.visit(parsed)
|
||||||
|
|||||||
@@ -286,6 +286,7 @@ else:
|
|||||||
test_resource_dir = os.path.join(config.swift_lib_dir, 'swift')
|
test_resource_dir = os.path.join(config.swift_lib_dir, 'swift')
|
||||||
resource_dir_opt = ""
|
resource_dir_opt = ""
|
||||||
stdlib_resource_dir_opt = resource_dir_opt
|
stdlib_resource_dir_opt = resource_dir_opt
|
||||||
|
sourcekitd_framework_dir = config.swift_lib_dir
|
||||||
lit_config.note('Using resource dir: ' + test_resource_dir)
|
lit_config.note('Using resource dir: ' + test_resource_dir)
|
||||||
|
|
||||||
# Parse the variant triple.
|
# Parse the variant triple.
|
||||||
@@ -670,12 +671,13 @@ if run_vendor == 'apple':
|
|||||||
(run_cpu, run_os, run_vers, clang_mcp_opt))
|
(run_cpu, run_os, run_vers, clang_mcp_opt))
|
||||||
|
|
||||||
config.target_build_swift = (
|
config.target_build_swift = (
|
||||||
"%s %s %s -F %s -Xlinker -rpath -Xlinker %s %s %s %s %s"
|
"%s %s %s -F %s -Xlinker -rpath -Xlinker %s %s %s %s %s -F %s -Xlinker -rpath -Xlinker %s"
|
||||||
% (xcrun_prefix, config.swiftc, target_options,
|
% (xcrun_prefix, config.swiftc, target_options,
|
||||||
extra_frameworks_dir, extra_frameworks_dir,
|
extra_frameworks_dir, extra_frameworks_dir,
|
||||||
sdk_overlay_linker_opt, config.swift_test_options,
|
sdk_overlay_linker_opt, config.swift_test_options,
|
||||||
config.swift_driver_test_options,
|
config.swift_driver_test_options,
|
||||||
swift_execution_tests_extra_flags))
|
swift_execution_tests_extra_flags, sourcekitd_framework_dir,
|
||||||
|
sourcekitd_framework_dir))
|
||||||
config.target_run = ""
|
config.target_run = ""
|
||||||
|
|
||||||
if 'interpret' in lit_config.params:
|
if 'interpret' in lit_config.params:
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
include(CheckIncludeFiles)
|
||||||
|
check_include_files("xpc/xpc.h" HAVE_XPC_H)
|
||||||
|
|
||||||
|
swift_is_installing_component(sourcekit-inproc SOURCEKIT_INSTALLING_INPROC)
|
||||||
|
|
||||||
|
if(HAVE_XPC_H AND SWIFT_BUILD_SOURCEKIT AND NOT SOURCEKIT_INSTALLING_INPROC)
|
||||||
|
set(BUILD_SOURCEKIT_XPC_SERVICE TRUE)
|
||||||
|
else()
|
||||||
|
set(BUILD_SOURCEKIT_XPC_SERVICE FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add generated libSyntax headers to global dependencies.
|
# Add generated libSyntax headers to global dependencies.
|
||||||
list(APPEND LLVM_COMMON_DEPENDS swift-syntax-generated-headers)
|
list(APPEND LLVM_COMMON_DEPENDS swift-syntax-generated-headers)
|
||||||
|
|
||||||
@@ -16,10 +27,18 @@ add_swift_tool_subdirectory(swift-api-digester)
|
|||||||
add_swift_tool_subdirectory(swift-syntax-test)
|
add_swift_tool_subdirectory(swift-syntax-test)
|
||||||
add_swift_tool_subdirectory(swift-refactor)
|
add_swift_tool_subdirectory(swift-refactor)
|
||||||
|
|
||||||
if(SWIFT_BUILD_SOURCEKIT)
|
if(SWIFT_BUILD_STDLIB AND SWIFT_BUILD_SDK_OVERLAY)
|
||||||
add_swift_tool_subdirectory(SourceKit)
|
set(BUILD_FOUNDATION TRUE)
|
||||||
|
else()
|
||||||
|
set(BUILD_FOUNDATION FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(SWIFT_BUILD_SOURCEKIT)
|
||||||
|
add_swift_tool_subdirectory(SourceKit)
|
||||||
|
if(BUILD_SOURCEKIT_XPC_SERVICE AND BUILD_FOUNDATION)
|
||||||
|
add_subdirectory(SwiftSourceKitClient)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(SWIFT_HOST_VARIANT STREQUAL "macosx")
|
if(SWIFT_HOST_VARIANT STREQUAL "macosx")
|
||||||
# Only build Darwin-specific tools when deploying to OS X.
|
# Only build Darwin-specific tools when deploying to OS X.
|
||||||
@@ -28,7 +47,7 @@ if(SWIFT_HOST_VARIANT STREQUAL "macosx")
|
|||||||
# SwiftSyntax depends on both the standard library (because it's a
|
# SwiftSyntax depends on both the standard library (because it's a
|
||||||
# Swift module), and the SDK overlays (because it depends on Foundation).
|
# Swift module), and the SDK overlays (because it depends on Foundation).
|
||||||
# Ensure we only build SwiftSyntax when we're building both.
|
# Ensure we only build SwiftSyntax when we're building both.
|
||||||
if(SWIFT_BUILD_STDLIB AND SWIFT_BUILD_SDK_OVERLAY)
|
if(BUILD_FOUNDATION)
|
||||||
add_subdirectory(SwiftSyntax)
|
add_subdirectory(SwiftSyntax)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ configure_file(
|
|||||||
set(SOURCEKIT_DEPLOYMENT_OS "${SWIFT_HOST_VARIANT}")
|
set(SOURCEKIT_DEPLOYMENT_OS "${SWIFT_HOST_VARIANT}")
|
||||||
set(SOURCEKIT_DEPLOYMENT_TARGET "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")
|
set(SOURCEKIT_DEPLOYMENT_TARGET "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")
|
||||||
|
|
||||||
swift_is_installing_component(sourcekit-inproc SOURCEKIT_INSTALLING_INPROC)
|
|
||||||
|
|
||||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)
|
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)
|
||||||
set(CMAKE_OSX_SYSROOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}")
|
set(CMAKE_OSX_SYSROOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}")
|
||||||
set(CMAKE_OSX_ARCHITECTURES "${SWIFT_HOST_VARIANT_ARCH}")
|
set(CMAKE_OSX_ARCHITECTURES "${SWIFT_HOST_VARIANT_ARCH}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
add_subdirectory(InProc)
|
add_subdirectory(InProc)
|
||||||
if (HAVE_XPC_H)
|
if(HAVE_XPC_H)
|
||||||
add_subdirectory(XPC)
|
add_subdirectory(XPC)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
include(CheckIncludeFiles)
|
|
||||||
|
|
||||||
check_include_files("xpc/xpc.h" HAVE_XPC_H)
|
|
||||||
|
|
||||||
# If we were going to build for APPLE but don't have XPC, just build inproc.
|
# If we were going to build for APPLE but don't have XPC, just build inproc.
|
||||||
if(APPLE AND NOT HAVE_XPC_H)
|
if(APPLE AND NOT HAVE_XPC_H)
|
||||||
set(SWIFT_SOURCEKIT_USE_INPROC_LIBRARY TRUE)
|
set(SWIFT_SOURCEKIT_USE_INPROC_LIBRARY TRUE)
|
||||||
|
|||||||
17
tools/SwiftSourceKitClient/CMakeLists.txt
Normal file
17
tools/SwiftSourceKitClient/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
set(EXTRA_COMPILE_FLAGS "-F" "${SWIFT_LIBRARY_OUTPUT_INTDIR}")
|
||||||
|
set(EXTRA_LINKER_FLAGS "-Xlinker" "-rpath" "-Xlinker" "${SWIFT_LIBRARY_OUTPUT_INTDIR}"
|
||||||
|
"-Xlinker" "-F" "-Xlinker" "${SWIFT_LIBRARY_OUTPUT_INTDIR}")
|
||||||
|
|
||||||
|
add_swift_library(swiftSwiftSourceKit SHARED
|
||||||
|
SourceKitdClient.swift
|
||||||
|
SourceKitdRequest.swift
|
||||||
|
SourceKitdResponse.swift
|
||||||
|
SourceKitdUID.swift
|
||||||
|
|
||||||
|
DEPENDS SourceKitService
|
||||||
|
SWIFT_COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS}
|
||||||
|
LINK_FLAGS ${EXTRA_LINKER_FLAGS}
|
||||||
|
SWIFT_MODULE_DEPENDS Foundation
|
||||||
|
INSTALL_IN_COMPONENT swift-syntax
|
||||||
|
TARGET_SDKS OSX
|
||||||
|
IS_STDLIB)
|
||||||
48
tools/SwiftSourceKitClient/SourceKitdClient.swift
Normal file
48
tools/SwiftSourceKitClient/SourceKitdClient.swift
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
//===--------------------- SourceKitdClient.swift -------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// This file provides a wrapper of SourceKitd service.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
import sourcekitd
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class SourceKitdService {
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
sourcekitd_initialize()
|
||||||
|
}
|
||||||
|
deinit {
|
||||||
|
sourcekitd_shutdown()
|
||||||
|
}
|
||||||
|
public func sendSyn(request: SourceKitdRequest) -> SourceKitdResponse {
|
||||||
|
return SourceKitdResponse(resp: sourcekitd_send_request_sync(request.rawRequest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SourceKitdService {
|
||||||
|
/// Parses the Swift file at the provided URL into a `Syntax` tree in Json
|
||||||
|
/// serialization format by querying SourceKitd service.
|
||||||
|
/// - Parameter url: The URL you wish to parse.
|
||||||
|
/// - Returns: The syntax tree in Json format string.
|
||||||
|
public static func encodeSourceFileSyntax(_ url: URL) throws -> String {
|
||||||
|
let Service = SourceKitdService()
|
||||||
|
let Request = SourceKitdRequest(uid: .source_request_editor_open)
|
||||||
|
let Path = url.path
|
||||||
|
Request.addParameter(.key_sourcefile, value: Path)
|
||||||
|
Request.addParameter(.key_name, value: Path)
|
||||||
|
Request.addParameter(.key_enable_syntax_tree, value: 1)
|
||||||
|
|
||||||
|
// FIXME: SourceKitd error handling.
|
||||||
|
let Resp = Service.sendSyn(request: Request)
|
||||||
|
return Resp.value.getString(.key_serialized_syntax_tree)
|
||||||
|
}
|
||||||
|
}
|
||||||
154
tools/SwiftSourceKitClient/SourceKitdRequest.swift
Normal file
154
tools/SwiftSourceKitClient/SourceKitdRequest.swift
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
//===--------------- SourceKitdRequest.swift ------------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// This file provides a convenient way to build a sourcekitd request.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
import sourcekitd
|
||||||
|
|
||||||
|
public struct SourceKitdRequest: CustomStringConvertible {
|
||||||
|
|
||||||
|
public class Dictionary: CustomStringConvertible {
|
||||||
|
let dict: sourcekitd_object_t
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
dict = sourcekitd_request_dictionary_create(nil, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
sourcekitd_request_release(UnsafeMutableRawPointer(dict))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ key: SourceKitdUID, value: String) {
|
||||||
|
sourcekitd_request_dictionary_set_string(dict, key.uid, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ key: SourceKitdUID, value: Int) {
|
||||||
|
sourcekitd_request_dictionary_set_int64(dict, key.uid, Int64(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ key: SourceKitdUID, value: SourceKitdUID) {
|
||||||
|
sourcekitd_request_dictionary_set_uid(dict, key.uid, value.uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ key: SourceKitdUID, value: Array) {
|
||||||
|
sourcekitd_request_dictionary_set_value(dict, key.uid, value.arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ key: SourceKitdUID, value: Dictionary) {
|
||||||
|
sourcekitd_request_dictionary_set_value(dict, key.uid, value.dict)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ key: SourceKitdUID, value: Bool) {
|
||||||
|
sourcekitd_request_dictionary_set_int64(dict, key.uid, value ? 1 : 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
let utf8Str = sourcekitd_request_description_copy(dict)!
|
||||||
|
let result = String(cString: utf8Str)
|
||||||
|
free(utf8Str)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Array: CustomStringConvertible {
|
||||||
|
let arr: sourcekitd_object_t
|
||||||
|
private let Append: Int = -1
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
arr = sourcekitd_request_array_create(nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
sourcekitd_request_release(arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ value: String) {
|
||||||
|
sourcekitd_request_array_set_string(arr, Append, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ value: Int) {
|
||||||
|
sourcekitd_request_array_set_int64(arr, Append, Int64(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ value: SourceKitdUID) {
|
||||||
|
sourcekitd_request_array_set_uid(arr, Append, value.uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func add(_ value: Dictionary) {
|
||||||
|
sourcekitd_request_array_set_value(arr, Append, value.dict)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
let utf8Str = sourcekitd_request_description_copy(arr)!
|
||||||
|
let result = String(cString: utf8Str)
|
||||||
|
free(utf8Str)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private let req = Dictionary()
|
||||||
|
|
||||||
|
public init(uid: SourceKitdUID) {
|
||||||
|
req.add(SourceKitdUID.key_request, value: uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addParameter(_ key: SourceKitdUID, value: String) {
|
||||||
|
req.add(key, value: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addParameter(_ key: SourceKitdUID, value: Int) {
|
||||||
|
req.add(key, value: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addParameter(_ key: SourceKitdUID, value: SourceKitdUID) {
|
||||||
|
req.add(key, value: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addArrayParameter(_ key: SourceKitdUID) -> Array {
|
||||||
|
let arr = Array()
|
||||||
|
req.add(key, value: arr)
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addDictionaryParameter(_ key: SourceKitdUID) -> Dictionary {
|
||||||
|
let dict = Dictionary()
|
||||||
|
req.add(key, value: dict)
|
||||||
|
return dict
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return req.description
|
||||||
|
}
|
||||||
|
|
||||||
|
public var rawRequest: sourcekitd_object_t {
|
||||||
|
return req.dict
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addCompilerArgsToRequest(_ compilerArguments: [String]?,
|
||||||
|
_ bufferName: String? = nil) {
|
||||||
|
let args = self.addArrayParameter(SourceKitdUID.key_compilerargs)
|
||||||
|
|
||||||
|
if let compilerArguments = compilerArguments {
|
||||||
|
for argument in compilerArguments {
|
||||||
|
switch argument {
|
||||||
|
// Exclude some arguments which SourceKit doesn't want or need.
|
||||||
|
case "-Xfrontend":
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
args.add(argument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
258
tools/SwiftSourceKitClient/SourceKitdResponse.swift
Normal file
258
tools/SwiftSourceKitClient/SourceKitdResponse.swift
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
//===--------------------- SourceKitdResponse.swift -----------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// This file provides convenient APIs to interpret a SourceKitd response.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import sourcekitd
|
||||||
|
|
||||||
|
public class SourceKitdResponse: CustomStringConvertible {
|
||||||
|
|
||||||
|
public struct Dictionary: CustomStringConvertible, CustomReflectable {
|
||||||
|
private let dict: sourcekitd_variant_t
|
||||||
|
|
||||||
|
public init(dict: sourcekitd_variant_t) {
|
||||||
|
assert(sourcekitd_variant_get_type(dict).rawValue ==
|
||||||
|
SOURCEKITD_VARIANT_TYPE_DICTIONARY.rawValue)
|
||||||
|
self.dict = dict
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getString(_ key: SourceKitdUID) -> String {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_string(dict, key.uid)!
|
||||||
|
return String(cString: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getInt(_ key: SourceKitdUID) -> Int {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_int64(dict, key.uid)
|
||||||
|
return Int(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getBool(_ key: SourceKitdUID) -> Bool {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_bool(dict, key.uid)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getUID(_ key: SourceKitdUID) -> SourceKitdUID {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_uid(dict, key.uid)!
|
||||||
|
return SourceKitdUID(uid: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getArray(_ key: SourceKitdUID) -> Array {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_value(dict, key.uid)
|
||||||
|
return Array(arr: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getDictionary(_ key: SourceKitdUID) -> Dictionary {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_value(dict, key.uid)
|
||||||
|
return Dictionary(dict: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getOptional(_ key: SourceKitdUID) -> Variant? {
|
||||||
|
let value = sourcekitd_variant_dictionary_get_value(dict, key.uid)
|
||||||
|
if sourcekitd_variant_get_type(value).rawValue ==
|
||||||
|
SOURCEKITD_VARIANT_TYPE_NULL.rawValue {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return Variant(val: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return dict.description
|
||||||
|
}
|
||||||
|
|
||||||
|
public var customMirror: Mirror {
|
||||||
|
return Mirror(self, children: [:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Array: CustomStringConvertible {
|
||||||
|
private let arr: sourcekitd_variant_t
|
||||||
|
|
||||||
|
public var count: Int {
|
||||||
|
let count = sourcekitd_variant_array_get_count(arr)
|
||||||
|
return Int(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(arr: sourcekitd_variant_t) {
|
||||||
|
assert(sourcekitd_variant_get_type(arr).rawValue ==
|
||||||
|
SOURCEKITD_VARIANT_TYPE_ARRAY.rawValue)
|
||||||
|
self.arr = arr
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getString(_ index: Int) -> String {
|
||||||
|
let value = sourcekitd_variant_array_get_string(arr, index)!
|
||||||
|
return String(cString: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getInt(_ index: Int) -> Int {
|
||||||
|
let value = sourcekitd_variant_array_get_int64(arr, index)
|
||||||
|
return Int(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getBool(_ index: Int) -> Bool {
|
||||||
|
let value = sourcekitd_variant_array_get_bool(arr, index)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getUID(_ index: Int) -> SourceKitdUID {
|
||||||
|
let value = sourcekitd_variant_array_get_uid(arr, index)!
|
||||||
|
return SourceKitdUID(uid: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getArray(_ index: Int) -> Array {
|
||||||
|
let value = sourcekitd_variant_array_get_value(arr, index)
|
||||||
|
return Array(arr: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getDictionary(_ index: Int) -> Dictionary {
|
||||||
|
let value = sourcekitd_variant_array_get_value(arr, index)
|
||||||
|
return Dictionary(dict: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func enumerate(_ applier: (_ index: Int, _ value: Variant) -> Bool) {
|
||||||
|
// The block passed to sourcekit_variant_array_apply() does not actually
|
||||||
|
// escape, it's synchronous and not called after returning.
|
||||||
|
withoutActuallyEscaping(applier) { escapingApplier in
|
||||||
|
_ = sourcekitd_variant_array_apply(arr) { (index, elem) -> Bool in
|
||||||
|
return escapingApplier(Int(index), Variant(val: elem))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return arr.description
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Variant: CustomStringConvertible {
|
||||||
|
private let val: sourcekitd_variant_t
|
||||||
|
|
||||||
|
fileprivate init(val: sourcekitd_variant_t) {
|
||||||
|
self.val = val
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getString() -> String {
|
||||||
|
let value = sourcekitd_variant_string_get_ptr(val)!
|
||||||
|
let length = sourcekitd_variant_string_get_length(val)
|
||||||
|
return fromCStringLen(value, length: length)!
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getStringBuffer() -> UnsafeBufferPointer<Int8> {
|
||||||
|
return UnsafeBufferPointer(start: sourcekitd_variant_string_get_ptr(val),
|
||||||
|
count: sourcekitd_variant_string_get_length(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getInt() -> Int {
|
||||||
|
let value = sourcekitd_variant_int64_get_value(val)
|
||||||
|
return Int(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getBool() -> Bool {
|
||||||
|
let value = sourcekitd_variant_bool_get_value(val)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getUID() -> SourceKitdUID {
|
||||||
|
let value = sourcekitd_variant_uid_get_value(val)!
|
||||||
|
return SourceKitdUID(uid:value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getArray() -> Array {
|
||||||
|
return Array(arr: val)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getDictionary() -> Dictionary {
|
||||||
|
return Dictionary(dict: val)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return val.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let resp: sourcekitd_response_t
|
||||||
|
|
||||||
|
public var value: Dictionary {
|
||||||
|
return Dictionary(dict: sourcekitd_response_get_value(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copies the raw bytes of the JSON description of this documentation item.
|
||||||
|
/// The caller is responsible for freeing the associated memory.
|
||||||
|
public func copyRawJSONDocumentation() -> UnsafeMutablePointer<Int8>? {
|
||||||
|
return sourcekitd_variant_json_description_copy(
|
||||||
|
sourcekitd_response_get_value(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether or not this response represents an error.
|
||||||
|
public var isError: Bool {
|
||||||
|
return sourcekitd_response_is_error(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether or not this response represents a notification.
|
||||||
|
public var isNotification: Bool {
|
||||||
|
return value.getOptional(.key_notification) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether or not this response represents a connection interruption error.
|
||||||
|
public var isConnectionInterruptionError: Bool {
|
||||||
|
return sourcekitd_response_is_error(resp) &&
|
||||||
|
sourcekitd_response_error_get_kind(resp) ==
|
||||||
|
SOURCEKITD_ERROR_CONNECTION_INTERRUPTED
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether or not this response represents a compiler crash.
|
||||||
|
public var isCompilerCrash: Bool {
|
||||||
|
guard let notification = value.getOptional(.key_notification)?.getUID()
|
||||||
|
else { return false }
|
||||||
|
return notification == .compilerCrashedNotification
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If this is a document update notification, returns the name of the
|
||||||
|
/// document to which this update applies. Otherwise, returns `nil`.
|
||||||
|
public var documentUpdateNotificationDocumentName: String? {
|
||||||
|
let response = value
|
||||||
|
guard let notification = response.getOptional(.key_notification)?.getUID(),
|
||||||
|
notification == .source_notification_editor_documentupdate
|
||||||
|
else { return nil }
|
||||||
|
return response.getOptional(.key_name)?.getString()
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(resp: sourcekitd_response_t) {
|
||||||
|
self.resp = resp
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
sourcekitd_response_dispose(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
let utf8Str = sourcekitd_response_description_copy(resp)!
|
||||||
|
let result = String(cString: utf8Str)
|
||||||
|
free(utf8Str)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension sourcekitd_variant_t: CustomStringConvertible {
|
||||||
|
public var description: String {
|
||||||
|
let utf8Str = sourcekitd_variant_description_copy(self)!
|
||||||
|
let result = String(cString: utf8Str)
|
||||||
|
free(utf8Str)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func fromCStringLen(_ ptr: UnsafePointer<Int8>, length: Int) -> String? {
|
||||||
|
return NSString(bytes: ptr, length: length,
|
||||||
|
encoding: String.Encoding.utf8.rawValue) as String?
|
||||||
|
}
|
||||||
52
tools/SwiftSourceKitClient/SourceKitdUID.swift
Normal file
52
tools/SwiftSourceKitClient/SourceKitdUID.swift
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
//===------------------------ SourceKitdUID.swift -------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
|
||||||
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||||
|
//
|
||||||
|
// See https://swift.org/LICENSE.txt for license information
|
||||||
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// This file provides SourceKitd UIDs.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
import sourcekitd
|
||||||
|
|
||||||
|
public struct SourceKitdUID: Equatable, Hashable, CustomStringConvertible {
|
||||||
|
public let uid: sourcekitd_uid_t
|
||||||
|
|
||||||
|
init(uid: sourcekitd_uid_t) {
|
||||||
|
self.uid = uid
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(string: String) {
|
||||||
|
self.uid = sourcekitd_uid_get_from_cstr(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return String(cString: sourcekitd_uid_get_string_ptr(uid))
|
||||||
|
}
|
||||||
|
|
||||||
|
public var asString: String {
|
||||||
|
return String(cString: sourcekitd_uid_get_string_ptr(uid))
|
||||||
|
}
|
||||||
|
|
||||||
|
public var hashValue: Int {
|
||||||
|
return uid.hashValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SourceKitdUID {
|
||||||
|
public static let key_request = SourceKitdUID(string: "key.request")
|
||||||
|
public static let key_compilerargs = SourceKitdUID(string: "key.compilerargs")
|
||||||
|
public static let key_notification = SourceKitdUID(string: "key.notification")
|
||||||
|
public static let key_name = SourceKitdUID(string: "key.name")
|
||||||
|
public static let key_enable_syntax_tree = SourceKitdUID(string: "key.enablesyntaxtree")
|
||||||
|
public static let key_serialized_syntax_tree = SourceKitdUID(string: "key.serialized_syntax_tree")
|
||||||
|
public static let key_sourcefile = SourceKitdUID(string: "key.sourcefile")
|
||||||
|
public static let compilerCrashedNotification = SourceKitdUID(string: "notification.toolchain-compiler-crashed")
|
||||||
|
public static let source_request_editor_open = SourceKitdUID(string: "source.request.editor.open")
|
||||||
|
public static let source_notification_editor_documentupdate = SourceKitdUID(string: "source.notification.editor.documentupdate")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user