Skip to content

Commit 5d8ebed

Browse files
committed
Prototype HTTP ASIO server
This patch removes the JediHTTP based web service and replaces it with an async HTTP server based on Beast/Boost.ASIO Additionally: - Add the ability to consume semantic diagnostics callbacks via a futures based system. The completer maintains a simple synchronous API which continues to make it easy to integrate the completer into HTTP servers. - Implement a real build system. CMake FTW. - Add driver programs for manual testing. - Start using CXX2017 awesomeness. Whats left before resubmitting to YCMD: - connect this to YCMD via a new completer. - implement hmac signing. - write integration tests, and maybe unit tests. - get clang format working ( maybe fix inconsistent coding style too
1 parent abfe7af commit 5d8ebed

22 files changed

+1605
-127
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
*.so
22
*.o
33
*.pyc
4+
build
45
vendor/
6+

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
[submodule "vendor/jediHttp"]
2-
path = vendor/jediHttp
3-
url = https://github.com/vheon/JediHTTP

.ycm_extra_conf.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# This file is NOT licensed under the GPLv3, which is the license for the rest
2+
# of YouCompleteMe.
3+
#
4+
# Here's the license text for this file:
5+
#
6+
# This is free and unencumbered software released into the public domain.
7+
#
8+
# Anyone is free to copy, modify, publish, use, compile, sell, or
9+
# distribute this software, either in source code form or as a compiled
10+
# binary, for any purpose, commercial or non-commercial, and by any
11+
# means.
12+
#
13+
# In jurisdictions that recognize copyright laws, the author or authors
14+
# of this software dedicate any and all copyright interest in the
15+
# software to the public domain. We make this dedication for the benefit
16+
# of the public at large and to the detriment of our heirs and
17+
# successors. We intend this dedication to be an overt act of
18+
# relinquishment in perpetuity of all present and future rights to this
19+
# software under copyright law.
20+
#
21+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24+
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27+
# OTHER DEALINGS IN THE SOFTWARE.
28+
#
29+
# For more information, please refer to <http://unlicense.org/>
30+
31+
import os
32+
import ycm_core
33+
34+
# These are the compilation flags that will be used in case there's no
35+
# compilation database set (by default, one is not set).
36+
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
37+
flags = [
38+
'-Wall',
39+
'-Wextra',
40+
'-Werror',
41+
'-Wno-long-long',
42+
'-Wno-variadic-macros',
43+
'-fexceptions',
44+
'-DNDEBUG',
45+
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
46+
# source code needs it.
47+
'-DUSE_CLANG_COMPLETER',
48+
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
49+
# language to use when compiling headers. So it will guess. Badly. So C++
50+
# headers will be compiled as C headers. You don't want that so ALWAYS specify
51+
# a "-std=<something>".
52+
# For a C project, you would set this to something like 'c99' instead of
53+
# 'c++11'.
54+
'-std=c++11',
55+
# ...and the same thing goes for the magic -x option which specifies the
56+
# language that the files to be compiled are written in. This is mostly
57+
# relevant for c++ headers.
58+
# For a C project, you would set this to 'c' instead of 'c++'.
59+
'-x',
60+
'c++',
61+
'-isystem',
62+
'../BoostParts',
63+
'-isystem',
64+
# This path will only work on OS X, but extra paths that don't exist are not
65+
# harmful
66+
'/System/Library/Frameworks/Python.framework/Headers',
67+
'-isystem',
68+
'../llvm/include',
69+
'-isystem',
70+
'../llvm/tools/clang/include',
71+
'-I',
72+
'.',
73+
'-I',
74+
'./ClangCompleter',
75+
'-isystem',
76+
'./tests/gmock/gtest',
77+
'-isystem',
78+
'./tests/gmock/gtest/include',
79+
'-isystem',
80+
'./tests/gmock',
81+
'-isystem',
82+
'./tests/gmock/include',
83+
]
84+
85+
86+
# Set this to the absolute path to the folder (NOT the file!) containing the
87+
# compile_commands.json file to use that instead of 'flags'. See here for
88+
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
89+
#
90+
# You can get CMake to generate this file for you by adding:
91+
# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
92+
# to your CMakeLists.txt file.
93+
#
94+
# Most projects will NOT need to set this to anything; you can just change the
95+
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
96+
compilation_database_folder = 'build/'
97+
98+
if os.path.exists( compilation_database_folder ):
99+
database = ycm_core.CompilationDatabase( compilation_database_folder )
100+
else:
101+
database = None
102+
103+
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
104+
105+
def DirectoryOfThisScript():
106+
return os.path.dirname( os.path.abspath( __file__ ) )
107+
108+
109+
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
110+
if not working_directory:
111+
return list( flags )
112+
new_flags = []
113+
make_next_absolute = False
114+
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
115+
for flag in flags:
116+
new_flag = flag
117+
118+
if make_next_absolute:
119+
make_next_absolute = False
120+
if not flag.startswith( '/' ):
121+
new_flag = os.path.join( working_directory, flag )
122+
123+
for path_flag in path_flags:
124+
if flag == path_flag:
125+
make_next_absolute = True
126+
break
127+
128+
if flag.startswith( path_flag ):
129+
path = flag[ len( path_flag ): ]
130+
new_flag = path_flag + os.path.join( working_directory, path )
131+
break
132+
133+
if new_flag:
134+
new_flags.append( new_flag )
135+
return new_flags
136+
137+
138+
def IsHeaderFile( filename ):
139+
extension = os.path.splitext( filename )[ 1 ]
140+
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
141+
142+
143+
def GetCompilationInfoForFile( filename ):
144+
# The compilation_commands.json file generated by CMake does not have entries
145+
# for header files. So we do our best by asking the db for flags for a
146+
# corresponding source file, if any. If one exists, the flags for that file
147+
# should be good enough.
148+
if IsHeaderFile( filename ):
149+
basename = os.path.splitext( filename )[ 0 ]
150+
for extension in SOURCE_EXTENSIONS:
151+
replacement_file = basename + extension
152+
if os.path.exists( replacement_file ):
153+
compilation_info = database.GetCompilationInfoForFile(
154+
replacement_file )
155+
if compilation_info.compiler_flags_:
156+
return compilation_info
157+
return None
158+
return database.GetCompilationInfoForFile( filename )
159+
160+
161+
def FlagsForFile( filename, **kwargs ):
162+
if database:
163+
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
164+
# python list, but a "list-like" StringVec object
165+
compilation_info = GetCompilationInfoForFile( filename )
166+
if not compilation_info:
167+
return None
168+
169+
final_flags = MakeRelativePathsInFlagsAbsolute(
170+
compilation_info.compiler_flags_,
171+
compilation_info.compiler_working_dir_ )
172+
173+
# NOTE: This is just for YouCompleteMe; it's highly likely that your project
174+
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
175+
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
176+
try:
177+
final_flags.remove( '-stdlib=libc++' )
178+
except ValueError:
179+
pass
180+
else:
181+
relative_to = DirectoryOfThisScript()
182+
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
183+
184+
return { 'flags': final_flags }

CMakeLists.txt

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
message("__SSVI CMAKE START")
2+
3+
cmake_minimum_required(VERSION 2.8)
4+
5+
message("parent prefix ${CMAKE_INSTALL_PREFIX}")
6+
7+
# Boost
8+
#
9+
10+
SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/include/boost)
11+
SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/lib)
12+
13+
option (Boost_USE_STATIC_LIBS "Use static libraries for boost" ON)
14+
15+
set (BOOST_INCLUDEDIR /usr/local/Cellar/boost/1.64.0_1)
16+
set (BOOST_ROOT /usr/local/lib)
17+
set (BOOST_USE_MULTITHREADED ON)
18+
19+
find_package (Boost REQUIRED COMPONENTS
20+
coroutine
21+
context
22+
filesystem
23+
program_options
24+
system
25+
thread
26+
)
27+
28+
include_directories (SYSTEM ${Boost_INCLUDE_DIRS})
29+
include_directories(/usr/local/include/boost)
30+
link_libraries (${Boost_LIBRARIES})
31+
add_definitions (-DBOOST_COROUTINES_NO_DEPRECATION_WARNING=1) # for asio
32+
33+
## Beast HTTP
34+
35+
include_directories(vendor/Beast/include/)
36+
37+
set(THREADS_PREFER_PTHREAD_FLAG ON)
38+
find_package(Threads)
39+
40+
# OSX First
41+
# Use Xcode'd sourcekitd build.
42+
execute_process (
43+
COMMAND bash -c "xcode-select --print-path | tr -d '\n'"
44+
OUTPUT_VARIABLE XCODE_PATH
45+
)
46+
#
47+
48+
set(SKT_FLAGS "-framework sourcekitd")
49+
set(SKT_FLAGS " ${SKT_FLAGS} -F ${XCODE_PATH}/Toolchains/XcodeDefault.xctoolchain/usr/lib")
50+
set(SKT_FLAGS " ${SKT_FLAGS} -rpath ${XCODE_PATH}/Toolchains/XcodeDefault.xctoolchain/usr/lib")
51+
message(${XCODE_PATH})
52+
set( XCLIB "-F ${XCODE_PATH}/Toolchains/XcodeDefault.xctoolchain/usr/lib")
53+
54+
set(GLOBAL_CXX_FLAGS "-std=c++1y -stdlib=libc++")
55+
set(GLOBAL_CXX_FLAGS "${GLOBAL_CXX_FLAGS} -std=c++1y -stdlib=libc++")
56+
set(GLOBAL_CXX_FLAGS "${GLOBAL_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wno-unused-parameter")
57+
set(GLOBAL_CXX_FLAGS "${GLOBAL_CXX_FLAGS} -isystem /usr/local/Frameworks")
58+
59+
add_definitions(${GLOBAL_CXX_FLAGS})
60+
set(CMAKE_CXX_FLAGS ${SKT_FLAGS})
61+
62+
add_executable (http_server
63+
file_body.hpp
64+
mime_type.hpp
65+
ssvi_http_server.hpp
66+
ssvi_http_server.cpp
67+
sema_task.cpp
68+
http_server.cpp
69+
SwiftCompleter.h
70+
SwiftCompleter.cpp
71+
)
72+
73+
target_link_libraries(http_server ${Boost_LIBRARIES} Threads::Threads)
74+
75+
INSTALL( TARGETS http_server
76+
RUNTIME DESTINATION bin )
77+
INSTALL( FILES scripts/activate
78+
DESTINATION . )
79+
#INSTALL( PROGRAMS scripts/run.sh
80+
# DESTINATION . )
81+
82+
message("__SSVI CMAKE FINISH")

Driver.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "SwiftCompleter.h"
2+
#include <string>
3+
#include <iostream>
4+
#include <dispatch/dispatch.h>
5+
6+
using namespace ssvim;
7+
using namespace std;
8+
9+
struct Runner {
10+
std::string complete(std::string fileName, std::string fileContents,
11+
std::vector<std::string> flags, unsigned line,
12+
unsigned column) {
13+
auto completer = SwiftCompleter();
14+
auto files = std::vector<UnsavedFile>();
15+
auto unsavedFile = UnsavedFile();
16+
unsavedFile.contents = fileContents;
17+
unsavedFile.fileName = fileName;
18+
19+
files.push_back(unsavedFile);
20+
auto result = completer.CandidatesForLocationInFile(fileName,
21+
line,
22+
column,
23+
files,
24+
flags);
25+
26+
return result;
27+
}
28+
};
29+
30+
std::string contents = "// \n\
31+
// some_swift.swift \n\
32+
// Swift Completer \n\
33+
// \n\
34+
// Created by Jerry Marino on 4/30/16. \n\
35+
// Copyright © 2016 Jerry Marino. All rights reserved. \n\
36+
// \n\
37+
\n\
38+
\n\
39+
func someOtherFunc(){ \n\
40+
} \n\
41+
\n\
42+
func anotherFunction(){ \n\
43+
someOther()\n\
44+
} \n\
45+
\n";
46+
47+
int wrapped_main(){
48+
Runner runner;
49+
std::cout << contents;
50+
vector<string> flags;
51+
flags.push_back("-sdk");
52+
flags.push_back(
53+
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk");
54+
flags.push_back("-target");
55+
flags.push_back("x86_64-apple-macosx10.12");
56+
assert(0 && "missing path to examples FIXME");
57+
58+
auto exampleFilePath = "/tmp/x";
59+
auto result = runner.complete(
60+
exampleFilePath,
61+
contents,
62+
flags,
63+
19,
64+
13
65+
);
66+
std::cout << result;
67+
std::cout << "__DONE";
68+
exit(0);
69+
}
70+
71+
int main(){
72+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
73+
wrapped_main();
74+
});
75+
dispatch_main();
76+
}
77+

Examples/some_swift.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ class MySwift : NSObject {
1616
}
1717

1818
func anotherFunction(){
19+
self.someOtherFunc()
1920
}
2021
}
22+

PythonExtensions.cpp

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)