ycmd-0+20160327+gitc3e6904.orig/ 0000700 0001750 0001750 00000000000 12677434542 014237 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/run_tests.py 0000755 0001750 0001750 00000016015 12677434535 016661 0 ustar onur onur #!/usr/bin/env python
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import * # noqa
import platform
import os
import subprocess
import os.path as p
import sys
DIR_OF_THIS_SCRIPT = p.dirname( p.abspath( __file__ ) )
DIR_OF_THIRD_PARTY = p.join( DIR_OF_THIS_SCRIPT, 'third_party' )
python_path = []
for folder in os.listdir( DIR_OF_THIRD_PARTY ):
# We skip python-future because it needs to be inserted in sys.path AFTER
# the standard library imports but we can't do that with PYTHONPATH because
# the std lib paths are always appended to PYTHONPATH. We do it correctly in
# prod in ycmd/utils.py because we have access to the right sys.path.
# So for dev, we rely on python-future being installed correctly with
# pip install -r test_requirements.txt
#
# Pip knows how to install this correctly so that it doesn't matter where in
# sys.path the path is.
if folder == 'python-future':
continue
python_path.append( p.abspath( p.join( DIR_OF_THIRD_PARTY, folder ) ) )
if os.environ.get( 'PYTHONPATH' ) is not None:
python_path.append( os.environ['PYTHONPATH'] )
os.environ[ 'PYTHONPATH' ] = os.pathsep.join( python_path )
sys.path.insert( 1, p.abspath( p.join( DIR_OF_THIRD_PARTY, 'argparse' ) ) )
import argparse
def RunFlake8():
print( 'Running flake8' )
subprocess.check_call( [
'flake8',
p.join( DIR_OF_THIS_SCRIPT, 'ycmd' )
] )
COMPLETERS = {
'cfamily': {
'build': [ '--clang-completer' ],
'test': [ '--exclude-dir=ycmd/tests/clang' ],
'aliases': [ 'c', 'cpp', 'c++', 'objc', 'clang', ]
},
'cs': {
'build': [ '--omnisharp-completer' ],
'test': [ '--exclude-dir=ycmd/tests/cs' ],
'aliases': [ 'omnisharp', 'csharp', 'c#' ]
},
'javascript': {
'build': [ '--tern-completer' ],
'test': [ '--exclude-dir=ycmd/tests/javascript' ],
'aliases': [ 'js', 'tern' ]
},
'go': {
'build': [ '--gocode-completer' ],
'test': [ '--exclude-dir=ycmd/tests/go' ],
'aliases': [ 'gocode' ]
},
'rust': {
'build': [ '--racer-completer' ],
'test': [ '--exclude-dir=ycmd/tests/rust' ],
'aliases': [ 'racer', 'racerd', ]
},
'typescript': {
'build': [],
'test': [ '--exclude-dir=ycmd/tests/typescript' ],
'aliases': []
},
'python': {
'build': [],
'test': [ '--exclude-dir=ycmd/tests/python' ],
'aliases': [ 'jedi', 'jedihttp', ]
},
}
def CompleterType( value ):
value = value.lower()
if value in COMPLETERS:
return value
else:
aliases_to_completer = dict( ( i, k ) for k, v in COMPLETERS.items()
for i in v[ 'aliases' ] )
if value in aliases_to_completer:
return aliases_to_completer[ value ]
else:
raise argparse.ArgumentTypeError(
'{0} is not a valid completer - should be one of {1}'.format(
value, COMPLETERS.keys() ) )
def ParseArguments():
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument( '--no-clang-completer', action = 'store_true',
help = argparse.SUPPRESS ) # deprecated
group.add_argument( '--no-completers', nargs ='*', type = CompleterType,
help = 'Do not build or test with listed semantic '
'completion engine(s). Valid values: {0}'.format(
COMPLETERS.keys()) )
group.add_argument( '--completers', nargs ='*', type = CompleterType,
help = 'Only build and test with listed semantic '
'completion engine(s). Valid values: {0}'.format(
COMPLETERS.keys()) )
parser.add_argument( '--skip-build', action = 'store_true',
help = 'Do not build ycmd before testing.' )
parser.add_argument( '--msvc', type = int, choices = [ 11, 12, 14 ],
help = 'Choose the Microsoft Visual '
'Studio version. (default: 14).' )
parser.add_argument( '--arch', type = int, choices = [ 32, 64 ],
help = 'Force architecture to 32 or 64 bits on '
'Windows (default: python interpreter architecture).' )
parser.add_argument( '--coverage', action = 'store_true',
help = 'Enable coverage report (requires coverage pkg)' )
parser.add_argument( '--no-flake8', action = 'store_true',
help = 'Disable flake8 run.' )
parsed_args, nosetests_args = parser.parse_known_args()
parsed_args.completers = FixupCompleters( parsed_args )
if 'COVERAGE' in os.environ:
parsed_args.coverage = ( os.environ[ 'COVERAGE' ] == 'true' )
return parsed_args, nosetests_args
def FixupCompleters( parsed_args ):
completers = set( COMPLETERS.keys() )
if parsed_args.completers is not None:
completers = set( parsed_args.completers )
elif parsed_args.no_completers is not None:
completers = completers.difference( parsed_args.no_completers )
elif parsed_args.no_clang_completer:
print( 'WARNING: The "--no-clang-completer" flag is deprecated. '
'Please use "--no-completer cfamily" instead.' )
completers.remove( 'cfamily' )
if 'USE_CLANG_COMPLETER' in os.environ:
if os.environ[ 'USE_CLANG_COMPLETER' ] == 'false':
completers.remove( 'cfamily' )
else:
completers.add( 'cfamily' )
return list( completers )
def BuildYcmdLibs( args ):
if not args.skip_build:
if 'EXTRA_CMAKE_ARGS' in os.environ:
os.environ[ 'EXTRA_CMAKE_ARGS' ] += ' -DUSE_DEV_FLAGS=ON'
else:
os.environ[ 'EXTRA_CMAKE_ARGS' ] = '-DUSE_DEV_FLAGS=ON'
os.environ[ 'YCM_TESTRUN' ] = '1'
build_cmd = [
sys.executable,
p.join( DIR_OF_THIS_SCRIPT, 'build.py' ),
]
for key in COMPLETERS:
if key in args.completers:
build_cmd.extend( COMPLETERS[ key ][ 'build' ] )
if args.msvc:
build_cmd.extend( [ '--msvc', str( args.msvc ) ] )
if args.arch:
build_cmd.extend( [ '--arch', str( args.arch ) ] )
subprocess.check_call( build_cmd )
def NoseTests( parsed_args, extra_nosetests_args ):
# Always passing --with-id to nosetests enables non-surprising usage of
# its --failed flag.
nosetests_args = [ '-v', '--with-id' ]
for key in COMPLETERS:
if key not in parsed_args.completers:
nosetests_args.extend( COMPLETERS[ key ][ 'test' ] )
if parsed_args.coverage:
nosetests_args += [ '--with-coverage', '--cover-package=ycmd',
'--cover-html' ]
if extra_nosetests_args:
nosetests_args.extend( extra_nosetests_args )
else:
nosetests_args.append( p.join( DIR_OF_THIS_SCRIPT, 'ycmd' ) )
subprocess.check_call( [ 'nosetests' ] + nosetests_args )
def Main():
parsed_args, nosetests_args = ParseArguments()
print( 'Running tests on Python', platform.python_version() )
if not parsed_args.no_flake8:
RunFlake8()
BuildYcmdLibs( parsed_args )
NoseTests( parsed_args, nosetests_args )
if __name__ == "__main__":
Main()
ycmd-0+20160327+gitc3e6904.orig/DEV_SETUP.md 0000644 0001750 0001750 00000002136 12677434535 016175 0 ustar onur onur # Setting up for ycmd development
We use Vagrant for development. The VM will have **all** dependencies already
set up correctly so you won't have to do anything. (If you find something
missing, please file a bug.)
NOTE: The virtual machine that is created requires 3GB of RAM, so you likely
need at least 8GB of RAM to use this environment.
1. Install [Vagrant][].
2. `cd` into the folder where you checked out ycmd.
3. `$ vagrant up && vagrant ssh`. This will take a while because the VM is being
built and set up. Only needs to happen once though.
4. You are now in the VM. Run the tests with `$ ./run_tests.py`.
5. Hack away. When done, exit the ssh connection with `exit`.
6. `$ vagrant suspend` so that you can quickly get back to hacking later.
7. Later on: `$ vagrant resume && vagrant ssh`. This will be _much_ faster.
That's it!
You can switch between Python versions with `pyenv global 2.6.6` and `pyenv
global 3.3.0`.
If you ever feel like you've screwed up the VM, just kill it with
`vagrant destroy` and then run `vagrant up` again to get to a clean state.
[vagrant]: https://www.vagrantup.com/
ycmd-0+20160327+gitc3e6904.orig/tox.ini 0000644 0001750 0001750 00000000274 12677434535 015571 0 ustar onur onur [flake8]
ignore = E111,E114,E121,E125,E126,E127,E128,E129,E131,E133,E201,E202,E203,E211,E221,E222,E241,E251,E261,E303,E402,W503
max-complexity = 10
max-line-length = 80
exclude = testdata
ycmd-0+20160327+gitc3e6904.orig/Vagrantfile 0000644 0001750 0001750 00000001251 12677434535 016437 0 ustar onur onur # -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
# TODO: update to xenial64 when that comes out
config.vm.box = "ubuntu/trusty64"
# On startup, run our bootstrap script to setup the VM
config.vm.provision :shell, :path => "vagrant_bootstrap.sh"
config.vm.provider "virtualbox" do |v|
# MAGIC for faster guest networking
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
v.customize ["modifyvm", :id, "--nictype1", "virtio"]
# We need quite a bit of memory to compile more than one ycmd C++ file at a
# time.
v.memory = 3072
v.cpus = 2
end
end
ycmd-0+20160327+gitc3e6904.orig/CORE_VERSION 0000644 0001750 0001750 00000000003 12677434535 016124 0 ustar onur onur 20
ycmd-0+20160327+gitc3e6904.orig/.coveragerc 0000644 0001750 0001750 00000000060 12677434535 016370 0 ustar onur onur [report]
omit =
*/tests/*
*/__init__.py
ycmd-0+20160327+gitc3e6904.orig/COPYING.txt 0000644 0001750 0001750 00000104513 12677434535 016130 0 ustar onur onur GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
ycmd-0+20160327+gitc3e6904.orig/third_party/ 0000755 0001750 0001750 00000000000 12677434535 016604 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/tern_runtime/ 0000755 0001750 0001750 00000000000 12677434535 021317 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/tern_runtime/package.json 0000644 0001750 0001750 00000000203 12677434535 023600 0 ustar onur onur {
"description": "ycmd tern runtime area with required tern version and plugins",
"dependencies": {
"tern": "0.17.0"
}
}
ycmd-0+20160327+gitc3e6904.orig/third_party/waitress/ 0000755 0001750 0001750 00000000000 12677434535 020445 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/OmniSharpServer/ 0000755 0001750 0001750 00000000000 12677434535 021673 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/argparse/ 0000755 0001750 0001750 00000000000 12677434535 020410 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/bottle/ 0000755 0001750 0001750 00000000000 12677434535 020075 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/ 0000755 0001750 0001750 00000000000 12677434542 020155 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/tox.ini 0000644 0001750 0001750 00000000426 12677434540 021470 0 ustar onur onur [tox]
envlist = py26, py27, py33
skipsdist = True
[testenv]
deps = -r{toxinidir}/test_requirements.txt
commands =
nosetests -v
flake8 --select=F,C9 --max-complexity=10 --exclude=fixtures jedihttp tests
[testenv:py26]
deps =
{[testenv]deps}
unittest2
ordereddict
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/LICENSE 0000644 0001750 0001750 00000026136 12677434540 021170 0 ustar onur onur
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/ 0000755 0001750 0001750 00000000000 12677434540 021766 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/ 0000755 0001750 0001750 00000000000 12677434540 023130 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/end_to_end_test.py 0000644 0001750 0001750 00000012347 12677434540 026646 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from . import utils
from .utils import with_jedihttp, py2only
import requests
import subprocess
from jedihttp import hmaclib
from os import path
from hamcrest import assert_that, equal_to
try:
from http import client as httplib
except ImportError:
import httplib
class HmacAuth( requests.auth.AuthBase ):
def __init__( self, secret ):
self._hmac_helper = hmaclib.JediHTTPHmacHelper( secret )
def __call__( self, req ):
self._hmac_helper.SignRequestHeaders( req.headers,
req.method,
req.path_url,
req.body )
return req
PORT = 50000
SECRET = 'secret'
PATH_TO_JEDIHTTP = path.abspath( path.join( path.dirname( __file__ ),
'..', '..', 'jedihttp.py' ) )
def wait_for_jedihttp_to_start( jedihttp ):
line = jedihttp.stdout.readline().decode( 'utf8' )
good_start = line.startswith( 'serving on' )
reason = jedihttp.stdout.read().decode( 'utf8' ) if not good_start else ''
return good_start, reason
def setup_jedihttp():
with hmaclib.TemporaryHmacSecretFile( SECRET ) as hmac_file:
command = [ utils.python(),
'-u', # this flag makes stdout non buffered
PATH_TO_JEDIHTTP,
'--port', str( PORT ),
'--hmac-file-secret', hmac_file.name ]
return utils.SafePopen( command,
stderr = subprocess.STDOUT,
stdout = subprocess.PIPE )
def teardown_jedihttp( jedihttp ):
utils.TerminateProcess( jedihttp.pid )
@with_jedihttp( setup_jedihttp, teardown_jedihttp )
def test_client_request_without_parameters( jedihttp ):
good_start, reason = wait_for_jedihttp_to_start( jedihttp )
assert_that( good_start, reason )
response = requests.post( 'http://127.0.0.1:{0}/ready'.format( PORT ),
auth = HmacAuth( SECRET ) )
assert_that( response.status_code, equal_to( httplib.OK ) )
hmachelper = hmaclib.JediHTTPHmacHelper( SECRET )
assert_that( hmachelper.IsResponseAuthenticated( response.headers,
response.content ) )
@with_jedihttp( setup_jedihttp, teardown_jedihttp )
def test_client_request_with_parameters( jedihttp ):
good_start, reason = wait_for_jedihttp_to_start( jedihttp )
assert_that( good_start, reason )
filepath = utils.fixture_filepath( 'goto.py' )
request_data = {
'source': open( filepath ).read(),
'line': 10,
'col': 3,
'source_path': filepath
}
response = requests.post( 'http://127.0.0.1:{0}/gotodefinition'.format( PORT ),
json = request_data,
auth = HmacAuth( SECRET ) )
assert_that( response.status_code, equal_to( httplib.OK ) )
hmachelper = hmaclib.JediHTTPHmacHelper( SECRET )
assert_that( hmachelper.IsResponseAuthenticated( response.headers,
response.content ) )
@with_jedihttp( setup_jedihttp, teardown_jedihttp )
def test_client_bad_request_with_parameters( jedihttp ):
good_start, reason = wait_for_jedihttp_to_start( jedihttp )
assert_that( good_start, reason )
filepath = utils.fixture_filepath( 'goto.py' )
request_data = {
'source': open( filepath ).read(),
'line': 100,
'col': 1,
'source_path': filepath
}
response = requests.post( 'http://127.0.0.1:{0}/gotodefinition'.format( PORT ),
json = request_data,
auth = HmacAuth( SECRET ) )
assert_that( response.status_code, equal_to( httplib.INTERNAL_SERVER_ERROR ) )
hmachelper = hmaclib.JediHTTPHmacHelper( SECRET )
assert_that( hmachelper.IsResponseAuthenticated( response.headers,
response.content ) )
@py2only
@with_jedihttp( setup_jedihttp, teardown_jedihttp )
def test_client_python3_specific_syntax_completion( jedihttp ):
good_start, reason = wait_for_jedihttp_to_start( jedihttp )
assert_that( good_start, reason )
filepath = utils.fixture_filepath( 'py3.py' )
request_data = {
'source': open( filepath ).read(),
'line': 19,
'col': 11,
'source_path': filepath
}
response = requests.post( 'http://127.0.0.1:{0}/completions'.format( PORT ),
json = request_data,
auth = HmacAuth( SECRET ) )
assert_that( response.status_code, equal_to( httplib.OK ) )
hmachelper = hmaclib.JediHTTPHmacHelper( SECRET )
assert_that( hmachelper.IsResponseAuthenticated( response.headers,
response.content ) )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/__init__.py 0000644 0001750 0001750 00000000000 12677434540 025227 0 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/utils.py 0000644 0001750 0001750 00000011141 12677434540 024640 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Almost all the functions are taken from
# https://github.com/Valloric/ycmd/blob/master/ycmd/utils.py
import sys
import os
import signal
import subprocess
# python3 compatibility
try:
basestring
except NameError:
basestring = str
try:
import unittest2 as unittest
except ImportError:
import unittest
py3only = unittest.skipIf( sys.version_info < ( 3, 0 ), "Python 3.x only test" )
py2only = unittest.skipIf( sys.version_info >= ( 3, 0 ), "Python 2.x only test" )
def python3():
if OnWindows():
return os.path.abspath( '/Python33/python' )
else:
return 'python3'
def python():
if sys.version_info < ( 3, 0 ) and 'CROSS_PYTHON_TESTS' in os.environ:
return python3()
else:
return sys.executable
def with_jedihttp( setup, teardown ):
"""Decorator which pass the return value of the setup function to the test
function and to the teardown function."""
def decorate( func ):
class Namespace: pass
ns = Namespace()
ns.jedihttp = None
def test_wrapped(): func( ns.jedihttp )
def setup_wrapped(): ns.jedihttp = setup()
def teardown_wrapped(): teardown( ns.jedihttp )
test_wrapped.__name__ = func.__name__
test_wrapped.setup = setup_wrapped
test_wrapped.teardown = teardown_wrapped
return test_wrapped
return decorate
def fixture_filepath( filename ):
dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) )
return os.path.join( dir_of_current_script, 'fixtures', filename )
# Creation flag to disable creating a console window on Windows. See
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx
CREATE_NO_WINDOW = 0x08000000
def OnWindows():
return sys.platform == 'win32'
# Convert paths in arguments command to short path ones
def ConvertArgsToShortPath( args ):
def ConvertIfPath( arg ):
if os.path.exists( arg ):
return GetShortPathName( arg )
return arg
if isinstance( args, basestring ):
return ConvertIfPath( args )
return [ ConvertIfPath( arg ) for arg in args ]
# Get the Windows short path name.
# Based on http://stackoverflow.com/a/23598461/200291
def GetShortPathName( path ):
from ctypes import windll, wintypes, create_unicode_buffer
# Set the GetShortPathNameW prototype
_GetShortPathNameW = windll.kernel32.GetShortPathNameW
_GetShortPathNameW.argtypes = [ wintypes.LPCWSTR,
wintypes.LPWSTR,
wintypes.DWORD]
_GetShortPathNameW.restype = wintypes.DWORD
output_buf_size = 0
while True:
output_buf = create_unicode_buffer( output_buf_size )
needed = _GetShortPathNameW( path, output_buf, output_buf_size )
if output_buf_size >= needed:
return output_buf.value
else:
output_buf_size = needed
# A wrapper for subprocess.Popen that fixes quirks on Windows.
def SafePopen( args, **kwargs ):
if OnWindows():
# We need this to start the server otherwise bad things happen.
# See issue #637.
if kwargs.get( 'stdin_windows' ) is subprocess.PIPE:
kwargs[ 'stdin' ] = subprocess.PIPE
# Do not create a console window
kwargs[ 'creationflags' ] = CREATE_NO_WINDOW
# Python 2 fails to spawn a process from a command containing unicode
# characters on Windows. See https://bugs.python.org/issue19264 and
# http://bugs.python.org/issue1759845.
# Since paths are likely to contains such characters, we convert them to
# short ones to obtain paths with only ascii characters.
args = ConvertArgsToShortPath( args )
kwargs.pop( 'stdin_windows', None )
return subprocess.Popen( args, **kwargs )
# From here: http://stackoverflow.com/a/8536476/1672783
def TerminateProcess( pid ):
if OnWindows():
import ctypes
PROCESS_TERMINATE = 1
handle = ctypes.windll.kernel32.OpenProcess( PROCESS_TERMINATE,
False,
pid )
ctypes.windll.kernel32.TerminateProcess( handle, -1 )
ctypes.windll.kernel32.CloseHandle( handle )
else:
os.kill( pid, signal.SIGTERM )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/fixtures/ 0000755 0001750 0001750 00000000000 12677434540 025001 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/fixtures/basic.py 0000644 0001750 0001750 00000000125 12677434540 026432 0 ustar onur onur class Foo(object):
def __init__(self):
self.a = 1
self.b = 2
f = Foo()
f.
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/fixtures/usages.py 0000644 0001750 0001750 00000000163 12677434540 026642 0 ustar onur onur def f():
""" Module method docs
Are dedented, like you might expect"""
return 1
a = f()
b = f()
c = f()
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/fixtures/goto.py 0000644 0001750 0001750 00000000445 12677434540 026326 0 ustar onur onur def f():
""" Module method docs
Are dedented, like you might expect"""
pass
class C:
""" Class Documentation"""
pass
variable = f if random.choice( [ 0, 1 ] ) else C
def foo():
print 'foo'
alias = foo
_list = [ 1, None, alias ]
inception = _list[ 2 ]
inception()
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/fixtures/py3.py 0000644 0001750 0001750 00000000611 12677434540 026064 0 ustar onur onur def make_scoreboard( frame, score = 0 ):
label = Label( frame )
label.pack()
for i in [ -10, -1, 1, 10 ]:
def increment(step=i):
nonlocal score
score = score + step
label['text'] = score
button = Button( frame, text='%+d' % i, command=increment )
button.pack()
return label
d = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
}
values = d.
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/tests/handlers_test.py 0000644 0001750 0001750 00000017140 12677434540 026344 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from .utils import fixture_filepath, py3only
from webtest import TestApp
from jedihttp import handlers
from nose.tools import ok_
from hamcrest import ( assert_that, only_contains, all_of, is_not, has_key,
has_item, has_items, has_entry, has_length, equal_to,
is_, empty )
import bottle
bottle.debug( True )
def CompletionEntry( name ):
return has_entry( 'name', name )
def valid_completions():
return all_of( has_key( 'docstring' ),
has_key( 'name' ),
has_key( 'description' ) )
def test_healthy():
app = TestApp( handlers.app )
ok_( app.post( '/healthy' ) )
def test_ready():
app = TestApp( handlers.app )
ok_( app.post( '/ready' ) )
# XXX(vheon): test for unicode, specially for python3
# where encoding must be specified
def test_completion():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'basic.py' )
request_data = {
'source': open( filepath ).read(),
'line': 7,
'col': 2,
'source_path': filepath
}
completions = app.post_json( '/completions',
request_data ).json[ 'completions' ]
assert_that( completions, only_contains( valid_completions() ) )
assert_that( completions, has_items( CompletionEntry( 'a' ),
CompletionEntry( 'b' ) ) )
def test_good_gotodefinition():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'goto.py' )
request_data = {
'source': open( filepath ).read(),
'line': 10,
'col': 3,
'source_path': filepath
}
definitions = app.post_json( '/gotodefinition',
request_data ).json[ 'definitions' ]
assert_that( definitions, has_length( 2 ) )
assert_that( definitions, has_items(
{
'description': 'def f',
'line': 1,
'in_builtin_module': False,
'column': 4,
'is_keyword': False,
'module_path': filepath,
'docstring': 'f()\n\nModule method docs\nAre '
'dedented, like you might expect'
},
{
'description': 'class C',
'line': 6,
'in_builtin_module': False,
'column': 6,
'is_keyword': False,
'module_path': filepath,
'docstring': 'Class Documentation'
} ) )
def test_bad_gotodefinitions_blank_line():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'goto.py' )
request_data = {
'source': open( filepath ).read(),
'line': 9,
'col': 1,
'source_path': filepath
}
definitions = app.post_json( '/gotodefinition', request_data ).json[ 'definitions' ]
assert_that( definitions, is_( empty() ) )
def test_bad_gotodefinitions_not_on_valid_position():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'goto.py' )
request_data = {
'source': open( filepath ).read(),
'line': 100,
'col': 1,
'source_path': filepath
}
response = app.post_json( '/gotodefinition', request_data, expect_errors = True )
assert_that( response.status_int, equal_to( 500 ) )
def test_good_gotoassignment():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'goto.py' )
request_data = {
'source': open( filepath ).read(),
'line': 20,
'col': 1,
'source_path': filepath
}
definitions = app.post_json( '/gotoassignment',
request_data ).json[ 'definitions' ]
assert_that( definitions, has_length( 1 ) )
assert_that( definitions, has_item( {
'in_builtin_module': False,
'is_keyword': False,
'module_path': filepath,
'column': 0,
'line': 18,
'description': 'inception = _list[ 2 ]',
'docstring': ''
} ) )
def test_usages():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'usages.py' )
request_data = {
'source': open( filepath ).read(),
'line': 8,
'col': 5,
'source_path': filepath
}
definitions = app.post_json( '/usages',
request_data ).json[ 'definitions' ]
assert_that( definitions, has_length( 4 ) )
assert_that( definitions, has_items(
{
'description': 'def f',
'in_builtin_module': False,
'is_keyword': False,
'module_path': filepath,
'column': 4,
'line': 1,
'docstring': 'f()\n\nModule method docs\nAre dedented, like you might expect'
},
{
'description': 'a = f()',
'in_builtin_module': False,
'is_keyword': False,
'module_path': filepath,
'column': 4,
'line': 6,
'docstring': ''
},
{
'description': 'b = f()',
'in_builtin_module': False,
'is_keyword': False,
'module_path': filepath,
'column': 4,
'line': 7,
'docstring': ''
},
{
'description': 'c = f()',
'in_builtin_module': False,
'is_keyword': False,
'module_path': filepath,
'column': 4,
'line': 8,
'docstring': ''
} ) )
@py3only
def test_py3():
app = TestApp( handlers.app )
filepath = fixture_filepath( 'py3.py' )
request_data = {
'source': open( filepath ).read(),
'line': 19,
'col': 11,
'source_path': filepath
}
completions = app.post_json( '/completions',
request_data ).json[ 'completions' ]
assert_that( completions, has_item( CompletionEntry( 'values' ) ) )
assert_that( completions,
is_not( has_item( CompletionEntry( 'itervalues' ) ) ) )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/__init__.py 0000644 0001750 0001750 00000000000 12677434540 024065 0 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/handlers.py 0000644 0001750 0001750 00000007556 12677434540 024155 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from jedihttp import utils
utils.AddVendorFolderToSysPath()
import jedi
import logging
import json
import bottle
from jedihttp import hmaclib
from bottle import response, request, Bottle
try:
import httplib
except ImportError:
from http import client as httplib
# num bytes for the request body buffer; request.json only works if the request
# size is less than this
bottle.Request.MEMFILE_MAX = 1000 * 1024
logger = logging.getLogger( __name__ )
app = Bottle( __name__ )
@app.post( '/healthy' )
def healthy():
logger.debug( 'received /healthy request' )
return _JsonResponse( True )
@app.post( '/ready' )
def ready():
logger.debug( 'received /ready request' )
return _JsonResponse( True )
@app.post( '/completions' )
def completions():
logger.debug( 'received /completions request' )
script = _GetJediScript( request.json )
return _JsonResponse( {
'completions': [ {
'name': completion.name,
'description': completion.description,
'docstring': completion.docstring(),
'module_path': completion.module_path,
'line': completion.line,
'column': completion.column
} for completion in script.completions() ]
} )
@app.post( '/gotodefinition' )
def gotodefinition():
logger.debug( 'received /gotodefinition request' )
script = _GetJediScript( request.json )
return _JsonResponse( _FormatDefinitions( script.goto_definitions() ) )
@app.post( '/gotoassignment' )
def gotoassignments():
logger.debug( 'received /gotoassignment request' )
script = _GetJediScript( request.json )
return _JsonResponse( _FormatDefinitions( script.goto_assignments() ) )
@app.post( '/usages' )
def usages():
logger.debug( 'received /usages request' )
script = _GetJediScript( request.json )
return _JsonResponse( _FormatDefinitions( script.usages() ) )
def _FormatDefinitions( definitions ):
return {
'definitions': [ {
'module_path': definition.module_path,
'line': definition.line,
'column': definition.column,
'in_builtin_module': definition.in_builtin_module(),
'is_keyword': definition.is_keyword,
'description': definition.description,
'docstring': definition.docstring()
} for definition in definitions ]
}
def _GetJediScript( request_data ):
return jedi.Script( request_data[ 'source' ],
request_data[ 'line' ],
request_data[ 'col' ],
request_data[ 'source_path' ] )
@app.error( httplib.INTERNAL_SERVER_ERROR )
def ErrorHandler( httperror ):
body = _JsonResponse( {
'exception': httperror.exception,
'message': str( httperror.exception ),
'traceback': httperror.traceback
} )
if 'jedihttp.hmac_secret' in app.config:
hmac_secret = app.config[ 'jedihttp.hmac_secret' ]
hmachelper = hmaclib.JediHTTPHmacHelper( hmac_secret )
hmachelper.SignResponseHeaders( response.headers, body )
return body
def _JsonResponse( data ):
response.content_type = 'application/json'
return json.dumps( data, default = _Serializer )
def _Serializer( obj ):
try:
serialized = obj.__dict__.copy()
serialized[ 'TYPE' ] = type( obj ).__name__
return serialized
except AttributeError:
return str( obj )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/compatibility.py 0000644 0001750 0001750 00000004074 12677434540 025216 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
if sys.version_info[0] >= 3:
basestring = str
unicode = str
def encode_string( value ):
return value.encode('utf-8') if isinstance(value, unicode) else value
def decode_string(value):
return value if isinstance(value, basestring) else value.decode('utf-8')
# hmac.compare_digest were introduced in python 2.7.7
if sys.version_info >= ( 2, 7, 7 ):
from hmac import compare_digest as SecureStringsEqual
else:
# This is the compare_digest function from python 3.4, adapted for 2.6:
# http://hg.python.org/cpython/file/460407f35aa9/Lib/hmac.py#l16
#
# Stolen from https://github.com/Valloric/ycmd
def SecureStringsEqual( a, b ):
"""Returns the equivalent of 'a == b', but avoids content based short
circuiting to reduce the vulnerability to timing attacks."""
# Consistent timing matters more here than data type flexibility
if not ( isinstance( a, str ) and isinstance( b, str ) ):
raise TypeError( "inputs must be str instances" )
# We assume the length of the expected digest is public knowledge,
# thus this early return isn't leaking anything an attacker wouldn't
# already know
if len( a ) != len( b ):
return False
# We assume that integers in the bytes range are all cached,
# thus timing shouldn't vary much due to integer object creation
result = 0
for x, y in zip( a, b ):
result |= ord( x ) ^ ord( y )
return result == 0
def compare_digest( a, b ):
return SecureStringsEqual( a, b )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/utils.py 0000644 0001750 0001750 00000001731 12677434540 023502 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
def AddVendorFolderToSysPath():
vendor_folder = os.path.join( os.path.dirname( __file__ ),
'..',
'vendor' )
for folder in os.listdir( vendor_folder ):
sys.path.insert( 0, os.path.realpath( os.path.join( vendor_folder,
folder ) ) )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/hmac_plugin.py 0000644 0001750 0001750 00000004570 12677434540 024634 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from bottle import request, response, abort
from jedihttp import hmaclib
try:
from urlparse import urlparse
import httplib
except ImportError:
from urllib.parse import urlparse
from http import client as httplib
class HmacPlugin( object ):
"""
Bottle plugin for hmac request authentication
http://bottlepy.org/docs/dev/plugindev.html
"""
name = 'hmac'
api = 2
def __init__( self ):
self._logger = logging.getLogger( __name__ )
def setup( self, app ):
hmac_secret = app.config[ 'jedihttp.hmac_secret' ]
self._hmachelper = hmaclib.JediHTTPHmacHelper( hmac_secret )
def __call__( self, callback ):
def wrapper( *args, **kwargs ):
if not IsLocalRequest():
self._logger.info( 'Dropping request with bad Host header.' )
abort( httplib.UNAUTHORIZED,
'Unauthorized, received request from non-local Host.' )
return
if not self.IsRequestAuthenticated():
self._logger.info( 'Dropping request with bad HMAC.' )
abort( httplib.UNAUTHORIZED, 'Unauthorized, received bad HMAC.' )
return
body = callback( *args, **kwargs )
self.SignResponseHeaders( response.headers, body )
return body
return wrapper
def IsRequestAuthenticated( self ):
return self._hmachelper.IsRequestAuthenticated( request.headers,
request.method,
request.path,
request.body.read() )
def SignResponseHeaders( self, headers, body ):
self._hmachelper.SignResponseHeaders( headers, body )
def IsLocalRequest():
host = urlparse( 'http://' + request.headers[ 'host' ] ).hostname
return host == '127.0.0.1' or host == 'localhost'
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp/hmaclib.py 0000644 0001750 0001750 00000006137 12677434540 023746 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import hmac
import hashlib
import tempfile
from base64 import b64encode, b64decode
from jedihttp.compatibility import encode_string, decode_string, compare_digest
def TemporaryHmacSecretFile( secret ):
"""Helper function for passing the hmac secret when starting a JediHTTP server
with TemporaryHmacSecretFile( 'mysecret' ) as hmac_file:
jedihttp = subprocess.Popen( ['python',
'jedihttp',
'--hmac-file-secret', hmac_file.name ] )
The JediHTTP Server as soon as it reads the hmac secret will remove the file
"""
hmac_file = tempfile.NamedTemporaryFile( 'w', delete = False )
encoded_secret = decode_string( b64encode( encode_string( secret ) ) )
json.dump( { 'hmac_secret': encoded_secret }, hmac_file )
return hmac_file
_HMAC_HEADER = 'x-jedihttp-hmac'
class JediHTTPHmacHelper( object ):
"""Helper class to correctly signing requests and validating responses when
communicating with a JediHTTP server."""
def __init__( self, secret ):
self._secret = encode_string( secret )
def _HasHeader( self, headers ):
return _HMAC_HEADER in headers
def _SetHmacHeader( self, headers, hmac ):
headers[ _HMAC_HEADER ] = decode_string( b64encode( hmac ) )
def _GetHmacHeader( self, headers ):
return b64decode( headers[ _HMAC_HEADER ] )
def _Hmac( self, content ):
return hmac.new( self._secret,
msg = encode_string( content ),
digestmod = hashlib.sha256 ).digest()
def _ComputeRequestHmac( self, method, path, body ):
if not body:
body = ''
return self._Hmac( b''.join( ( self._Hmac( method ),
self._Hmac( path ),
self._Hmac( body ) ) ) )
def SignRequestHeaders( self, headers, method, path, body ):
self._SetHmacHeader( headers, self._ComputeRequestHmac( method, path, body ) )
def IsRequestAuthenticated( self, headers, method, path, body ):
if not self._HasHeader( headers ):
return False
return compare_digest( self._GetHmacHeader( headers ),
self._ComputeRequestHmac( method, path, body ) )
def SignResponseHeaders( self, headers, body ):
self._SetHmacHeader( headers, self._Hmac( body ) )
def IsResponseAuthenticated( self, headers, content ):
if not self._HasHeader( headers ):
return False
return compare_digest( self._GetHmacHeader( headers ),
self._Hmac( content ) )
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/.travis.yml 0000644 0001750 0001750 00000002122 12677434540 022261 0 ustar onur onur language: python
sudo: false
matrix:
include:
# TOXENV specify under which environment tox should launch the tests
# https://testrun.org/tox/latest/
- python: 2.6
env: TOXENV=py26
- python: 2.7
env: TOXENV=py27
- python: 3.3
env: TOXENV=py33
- python: 2.6
env:
- TOXENV=py26
- CROSS_PYTHON_TESTS=true
- python: 2.7
env:
- TOXENV=py27
- CROSS_PYTHON_TESTS=true
- language: generic
os: osx
osx_image: xcode7
env: TOXENV=py26
- language: generic
os: osx
osx_image: xcode7
env: TOXENV=py27
- language: generic
os: osx
osx_image: xcode7
env:
- TOXENV=py26
- CROSS_PYTHON_TESTS=true
- language: generic
os: osx
osx_image: xcode7
env:
- TOXENV=py27
- CROSS_PYTHON_TESTS=true
- language: generic
os: osx
osx_image: xcode7
env: TOXENV=py33
before_install: git submodule update --init --recursive
install: ./travis/install.sh
script: ./travis/run.sh
notifications:
email: false
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/appveyor.yml 0000644 0001750 0001750 00000003600 12677434540 022542 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# used https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor.yml
# for guidance
environment:
matrix:
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "32"
TOXENV: "py27"
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "64"
TOXENV: "py27"
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "32"
TOXENV: "py27"
CROSS_PYTHON_TESTS: "true"
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "64"
TOXENV: "py27"
CROSS_PYTHON_TESTS: "true"
- PYTHON: "C:\\Python33"
PYTHON_VERSION: "3.3.x"
PYTHON_ARCH: "32"
TOXENV: "py33"
- PYTHON: "C:\\Python33-x64"
PYTHON_VERSION: "3.3.x"
PYTHON_ARCH: "64"
TOXENV: "py33"
install:
- git submodule update --init --recursive
# Prepend newly installed Python to the PATH of this build (this cannot be
# done from inside the powershell script as it would require to restart
# the parent CMD process).
- set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- pip install --disable-pip-version-check --user --upgrade pip
- pip install tox
build_script:
- tox
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/README.md 0000644 0001750 0001750 00000012374 12677434540 021441 0 ustar onur onur # JediHTTP
[](https://travis-ci.org/vheon/JediHTTP)
[](https://ci.appveyor.com/project/vheon/jedihttp/branch/master)
A simple http/json wrapper around [jedi][].
## Why
It's only purpose for me is to integrate it with [YouCompleteMe][] allowing to
run [jedi][] under python3 and get python3 completions, but that would not
exclude other uses :). At the moment not all the API It has been wrapped.
## Command-line
For starting the server, after you have cloned it somewhere:
```
python /path/to/JediHTTP/jedihttp.py [options]
```
### Options
#### `--host` ADDRESS
If not specified, 127.0.0.1 is used.
#### `--port` PORT
Listen on PORT. If not specified, will use any available port.
#### `--hmac-secret-file` PATH
PATH is the path of a JSON file containing a key named `hmac_secret`. Its value
will be used as the secret for HMAC Auth and the file will be deleted as soon
as it's read.
## API
I thought JediHTTP as a simple wrapper around Jedi so its JSON API resembles
the original python one very much so for more information about what the
parameters are and what they represent look at the original docs
[jedi-plugin-api][].
### POST /healthy
Return a 200 status code if the server is up.
### POST /ready
Return a 200 status code if the server is up. Is the same as `/healthy`.
### POST /completions
Parameters:
```javascript
{
"source": "def f():\n pass",
"line": 1,
"col": 0,
"path": "/home/user/code/src/file.py"
}
```
Response:
```javascript
{
"completions": [
{
"name": "name", // Name of variable/function/class/module.
"description": "A textual description of the object.",
"docstring": "A document string for this completion object.",
"module_path": "/usr/lib/python2.7/os.py", // Shows the file path of a module
"line": 4, // The line where the definition occurs (starting with 1).
"column": 2 // The column where the definition occurs (starting with 0).
},
...
]
}
```
### POST /gotodefinition
Parameters:
```javascript
{
"source": "def f():\n pass",
"line": 1,
"col": 0,
"path": "/home/user/code/src/file.py"
}
```
Response:
```javascript
{
"definitions": [
{
"module_path": "/usr/lib/python2.7/os.py", // Shows the file path of a module
"line": 3, // The line where the definition occurs (starting with 1).
"column": 1 // The column where the definition occurs (starting with 0).
"in_builtin_module": false, // Whether this is a builtin module.
"is_keyword": false,
"description": "A description of the Definition object",
"docstring": "A document string for this Definition object.",
}
]
}
```
### POST /gotoassignment
Parameters:
```javascript
{
"source": "def f():\n pass",
"line": 1,
"col": 0,
"path": "/home/user/code/src/file.py"
}
```
Response:
```javascript
{
"definitions": [
{
"module_path": "/usr/lib/python2.7/os.py", // Shows the file path of a module
"line": 3, // The line where the definition occurs (starting with 1).
"column": 1 // The column where the definition occurs (starting with 0).
"in_builtin_module": false, // Whether this is a builtin module.
"is_keyword": false,
"description": "A description of the Definition object",
"docstring": "A document string for this Definition object.",
}
]
}
```
### POST /usages
Parameters:
```javascript
{
"source": "def f():\n pass\n\na = f()\nb = f()",
"line": 1,
"col": 4,
"path": "/home/user/code/src/file.py"
}
```
Response:
```javascript
{
"definitions": [
{
'description': 'def f',
'in_builtin_module': False,
'is_keyword': False,
'module_path': '/home/user/code/src/file.py',
'column': 4,
'line': 1,
'docstring': ''
},
{
'description': 'a = f()',
'in_builtin_module': False,
'is_keyword': False,
'module_path': /home/user/code/src/file.py,
'column': 4,
'line': 4,
'docstring': ''
},
{
'description': 'b = f()',
'in_builtin_module': False,
'is_keyword': False,
'module_path': '/home/user/code/src/file.py',
'column': 4,
'line': 5,
'docstring': ''
}
]
}
```
### In case of errors
Response:
```javascript
{
"exception": "ValueError"
"message": "`column` parameter is not in a valid range.",
"traceback": "Traceback ..."
}
```
status code: 500
## HMAC Auth
If the server is started with the `--hmac-file-secret` then the JediHTTP will
require every request and response has to be HMAC signed based on the secred
provided in the file putting the HMAC signature in a header called `x-jedihttp-hmac`
Assuming `||` stands for concatenation:
- requests signature: HMAC( HMAC( body ) || HMAC( http method ) || HMAC( request path ) ).
For example, HMAC(HMAC('foo') || HMAC('GET') || HMAC('/healthy'))
- Responses: HMAC( body )
## Disclaimer
I'm not a python programmer but I'm using this to experiment with python a bit.
[jedi]: http://github.com/davidhalter/jedi
[jedi-plugin-api]: http://jedi.jedidjah.ch/en/latest/docs/plugin-api.html#module-jedi.api
[YouCompleteMe]: http://github.com/Valloric/YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/travis/ 0000755 0001750 0001750 00000000000 12677434540 021463 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/travis/run.sh 0000755 0001750 0001750 00000001217 12677434540 022627 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash
set -e
source ~/.venv/bin/activate
tox
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/travis/install.sh 0000755 0001750 0001750 00000002631 12677434540 023472 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash
# Adapted from:
# https://github.com/pyca/cryptography/blob/master/.travis/install.sh
set -e
if [[ ${TRAVIS_OS_NAME} == "osx" ]]; then
# install pyenv
git clone --branch=v20151103 --depth=1 https://github.com/yyuu/pyenv.git ~/.pyenv
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
pyenv install 3.3.6
echo "3.3.6" >> .python-version
case "${TOXENV}" in
py26)
curl -O https://bootstrap.pypa.io/get-pip.py
python get-pip.py --user
;;
py27)
curl -O https://bootstrap.pypa.io/get-pip.py
python get-pip.py --user
;;
py33)
pyenv global 3.3.6
;;
esac
pyenv rehash
python -m pip install --user virtualenv
else
pip install virtualenv
fi
python -m virtualenv ~/.venv
source ~/.venv/bin/activate
pip install tox
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/jedihttp.py 0000644 0001750 0001750 00000004065 12677434540 022345 0 ustar onur onur # Copyright 2015 Cedraro Andrea
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from jedihttp import utils
utils.AddVendorFolderToSysPath()
import sys
import os
import json
from base64 import b64decode
from argparse import ArgumentParser
from waitress import serve
from jedihttp import handlers
from jedihttp.hmac_plugin import HmacPlugin
def ParseArgs():
parser = ArgumentParser()
parser.add_argument( '--host', type = str, default = '127.0.0.1',
help = 'server host' )
parser.add_argument( '--port', type = int, default = 0,
help = 'server port' )
parser.add_argument( '--hmac-file-secret', type = str,
help = 'file containing hmac secret' )
return parser.parse_args()
def GetSecretFromTempFile( tfile ):
key = 'hmac_secret'
with open( tfile ) as hmac_file:
try:
data = json.load( hmac_file )
if key not in data:
sys.exit( "A json file with a key named 'secret' was expected for "
"the secret exchange, but wasn't found" )
hmac_secret = data[ key ]
except ValueError:
sys.exit( "A JSON was expected for the secret exchange" )
os.remove( tfile )
return hmac_secret
def Main():
args = ParseArgs()
if args.hmac_file_secret:
hmac_secret = GetSecretFromTempFile( args.hmac_file_secret )
handlers.app.config[ 'jedihttp.hmac_secret' ] = b64decode( hmac_secret )
handlers.app.install( HmacPlugin() )
serve( handlers.app,
host = args.host,
port = args.port )
if __name__ == "__main__":
Main()
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/vendor/ 0000755 0001750 0001750 00000000000 12677434540 021450 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/vendor/waitress/ 0000755 0001750 0001750 00000000000 12677434540 023311 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/vendor/argparse/ 0000755 0001750 0001750 00000000000 12677434540 023254 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/vendor/bottle/ 0000755 0001750 0001750 00000000000 12677434540 022741 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/vendor/jedi/ 0000755 0001750 0001750 00000000000 12677434540 022363 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/test_requirements.txt 0000644 0001750 0001750 00000000111 12677434540 024467 0 ustar onur onur flake8>=2.0
nose>=1.3.0
WebTest>=2.0.0
PyHamcrest>=1.8.0
requests>=2.8.1
ycmd-0+20160327+gitc3e6904.orig/third_party/JediHTTP/NOTICE 0000644 0001750 0001750 00000001561 12677434540 021062 0 ustar onur onur Copyright 2015 Cedraro Andrea
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This project includes Jedi (http://jedi.jedidjah.ch)
Copyright (c) 2013 David Halter and others
This project includes Bottle (http://bottlepy.org/)
Copyright (c) 2012, Marcel Hellkamp.
This project includes Waitress (http://docs.pylonsproject.org/projects/waitress)
Zope Foundation and Contributors
ycmd-0+20160327+gitc3e6904.orig/third_party/python-future/ 0000755 0001750 0001750 00000000000 12677434535 021435 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/godef/ 0000755 0001750 0001750 00000000000 12677434535 017670 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/gocode/ 0000755 0001750 0001750 00000000000 12677434535 020044 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/racerd/ 0000755 0001750 0001750 00000000000 12677434535 020044 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/requests/ 0000755 0001750 0001750 00000000000 12677434535 020457 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/ 0000755 0001750 0001750 00000000000 12677434542 020751 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/README.txt 0000644 0001750 0001750 00000002072 12677434537 022454 0 ustar onur onur ==========
frozendict
==========
``frozendict`` is an immutable wrapper around dictionaries that implements the
complete mapping interface. It can be used as a drop-in replacement for
dictionaries where immutability is desired.
Of course, this is ``python``, and you can still poke around the object's
internals if you want.
The ``frozendict`` constructor mimics ``dict``, and all of the expected
interfaces (``iter``, ``len``, ``repr``, ``hash``, ``getitem``) are provided.
Note that a ``frozendict`` does not guarantee the immutability of its values, so
the utility of ``hash`` method is restricted by usage.
The only difference is that the ``copy()`` method of ``frozendict`` takes
variable keyword arguments, which will be present as key/value pairs in the new,
immutable copy.
Example shell usage::
from frozendict import frozendict
fd = frozendict({ 'hello': 'World' })
print fd
#
print fd['hello']
# 'World'
print fd.copy(another='key/value')
#
ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/setup.py 0000644 0001750 0001750 00000000620 12677434537 022465 0 ustar onur onur from distutils.core import setup
setup(
name = 'frozendict',
version = '0.3',
url = 'https://github.com/slezica/python-frozendict',
author = 'Santiago Lezica',
author_email = 'slezica89@gmail.com',
packages = ['frozendict'],
license = 'MIT License',
description = 'An immutable dictionary',
long_description = open('README.txt').read()
)
ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/LICENSE.txt 0000644 0001750 0001750 00000002043 12677434537 022577 0 ustar onur onur Copyright (c) 2012 Santiago Lezica
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/MANIFEST.in 0000644 0001750 0001750 00000000016 12677434537 022510 0 ustar onur onur include *.txt
ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/README.md 0000644 0001750 0001750 00000002024 12677434537 022232 0 ustar onur onur frozendict
==========
`frozendict` is an immutable wrapper around dictionaries that implements the
complete mapping interface. It can be used as a drop-in replacement for
dictionaries where immutability is desired.
Of course, this is `python`, and you can still poke around the object's
internals if you want.
The `frozendict` constructor mimics `dict`, and all of the expected
interfaces (`iter`, `len`, `repr`, `hash`, `getitem`) are provided.
Note that a `frozendict` does not guarantee the immutability of its values, so
the utility of `hash` method is restricted by usage.
The only difference is that the `copy()` method of `frozendict` takes
variable keyword arguments, which will be present as key/value pairs in the new,
immutable copy.
Example shell usage:
from frozendict import frozendict
fd = frozendict({ 'hello': 'World' })
print fd
#
print fd['hello']
# 'World'
print fd.copy(another='key/value')
#
ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/frozendict/ 0000755 0001750 0001750 00000000000 12677434537 023124 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/third_party/frozendict/frozendict/__init__.py 0000644 0001750 0001750 00000001264 12677434537 025240 0 ustar onur onur import collections, operator
class frozendict(collections.Mapping):
def __init__(self, *args, **kwargs):
self.__dict = dict(*args, **kwargs)
self.__hash = None
def __getitem__(self, key):
return self.__dict[key]
def copy(self, **add_or_replace):
return frozendict(self, **add_or_replace)
def __iter__(self):
return iter(self.__dict)
def __len__(self):
return len(self.__dict)
def __repr__(self):
return '' % repr(self.__dict)
def __hash__(self):
if self.__hash is None:
self.__hash = reduce(operator.xor, map(hash, self.iteritems()), 0)
return self.__hash
ycmd-0+20160327+gitc3e6904.orig/ci/ 0000755 0001750 0001750 00000000000 12677434535 014646 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/ci/appveyor/ 0000755 0001750 0001750 00000000000 12677434535 016513 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/ci/appveyor/appveyor_install.bat 0000644 0001750 0001750 00000003667 12677434535 022612 0 ustar onur onur :: Since we are caching target folder in racerd submodule and git cannot clone
:: a submodule in a non-empty folder, we move out the cached folder and move it
:: back after cloning submodules.
if exist third_party\racerd\target (
move third_party\racerd\target racerd_target
)
git submodule update --init --recursive
:: Batch script will not exit if a command returns an error, so we manually do
:: it for commands that may fail.
if %errorlevel% neq 0 exit /b %errorlevel%
if exist racerd_target (
move racerd_target third_party\racerd\target
)
::
:: Python configuration
::
if %arch% == 32 (
set python_path=C:\Python%python%
) else (
set python_path=C:\Python%python%-x64
)
set PATH=%python_path%;%python_path%\Scripts;%PATH%
python --version
:: Manually setting PYTHONHOME for python 2.7.11 fix the following error when
:: running core tests: "ImportError: No module named site"
:: TODO: check if this is still needed when python 2.7.12 is released.
if %python% == 27 (
set PYTHONHOME=%python_path%
)
:: When using Python 3 on AppVeyor, CMake will always pick the 64 bits
:: libraries. We specifically tell CMake the right path to the libraries
:: according to the architecture.
if %python% == 35 (
set EXTRA_CMAKE_ARGS="-DPYTHON_LIBRARY=%python_path%\libs\python%python%.lib"
)
appveyor DownloadFile https://bootstrap.pypa.io/get-pip.py
python get-pip.py
pip install -r test_requirements.txt
if %errorlevel% neq 0 exit /b %errorlevel%
::
:: Typescript configuration
::
:: Since npm executable is a batch file, we need to prefix it with a call
:: statement. See https://github.com/npm/npm/issues/2938
call npm install -g typescript
if %errorlevel% neq 0 exit /b %errorlevel%
::
:: Rust configuration
::
appveyor DownloadFile https://static.rust-lang.org/dist/rust-1.6.0-x86_64-pc-windows-msvc.exe
rust-1.6.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files\Rust"
set PATH=C:\Program Files\Rust\bin;%PATH%
rustc -Vv
cargo -V
ycmd-0+20160327+gitc3e6904.orig/ci/README.md 0000644 0001750 0001750 00000000267 12677434535 016132 0 ustar onur onur Travis and AppVeyor Scripts
===========================
This directory contains scripts used for testing `ycmd` on Travis and AppVeyor CIs. They
should not normally be run by users.
ycmd-0+20160327+gitc3e6904.orig/ci/travis/ 0000755 0001750 0001750 00000000000 12677434535 016156 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/ci/travis/travis_install.linux.sh 0000644 0001750 0001750 00000001052 12677434535 022704 0 ustar onur onur # Linux-specific installation
# We can't use sudo, so we have to approximate the behaviour of the following:
# $ sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.7 100
mkdir ${HOME}/bin
ln -s /usr/bin/clang++-3.7 ${HOME}/bin/clang++
ln -s /usr/bin/clang-3.7 ${HOME}/bin/clang
ln -s /usr/bin/clang++-3.7 ${HOME}/bin/c++
ln -s /usr/bin/clang-3.7 ${HOME}/bin/cc
# These shouldn't be necessary, but just in case.
ln -s /usr/bin/clang++-3.7 ${HOME}/bin/g++
ln -s /usr/bin/clang-3.7 ${HOME}/bin/gcc
export PATH=${HOME}/bin:${PATH}
ycmd-0+20160327+gitc3e6904.orig/ci/travis/travis_install.sh 0000644 0001750 0001750 00000004140 12677434535 021547 0 ustar onur onur #!/bin/bash
set -ev
####################
# OS-specific setup
####################
# Requirements of OS-specific install:
# - install any software which is not installed by Travis configuration
# - set up everything necessary so that pyenv can build python
source ci/travis/travis_install.${TRAVIS_OS_NAME}.sh
#############
# pyenv setup
#############
# DON'T exit if error
set +e
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
git fetch --tags
git checkout v20160202
# Exit if error
set -e
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
if [ "${YCMD_PYTHON_VERSION}" == "2.6" ]; then
PYENV_VERSION="2.6.6"
elif [ "${YCMD_PYTHON_VERSION}" == "2.7" ]; then
PYENV_VERSION="2.7.6"
else
PYENV_VERSION="3.3.6"
fi
pyenv install --skip-existing ${PYENV_VERSION}
pyenv rehash
pyenv global ${PYENV_VERSION}
# It is quite easy to get the above series of steps wrong. Verify that the
# version of python actually in the path and used is the version that was
# requested, and fail the build if we broke the travis setup
python_version=$(python -c 'import sys; print( "{0}.{1}".format( sys.version_info[0], sys.version_info[1] ) )')
echo "Checking python version (actual ${python_version} vs expected ${YCMD_PYTHON_VERSION})"
test ${python_version} == ${YCMD_PYTHON_VERSION}
############
# pip setup
############
pip install -U pip wheel setuptools
pip install -r test_requirements.txt
npm install -g typescript
# We run coverage tests only on a single build, where COVERAGE=true
if [ x"${COVERAGE}" = x"true" ]; then
pip install coveralls
fi
############
# rust setup
############
# Need rust available, but travis doesn't give it to you without language: rust
pushd ${HOME}
git clone --recursive https://github.com/brson/multirust
cd multirust
git reset --hard f3974f2b966476ad656afba311b50a9c23fe6d2e
./build.sh
./install.sh --prefix=${HOME}
popd
multirust update stable
multirust default stable
# The build infrastructure prints a lot of spam after this script runs, so make
# sure to disable printing, and failing on non-zero exit code after this script
# finishes
set +ev
ycmd-0+20160327+gitc3e6904.orig/ci/travis/travis_install.osx.sh 0000644 0001750 0001750 00000001742 12677434535 022364 0 ustar onur onur # OS X-specific installation
# There's a homebrew bug which causes brew update to fail the first time. Run
# it twice to workaround. https://github.com/Homebrew/homebrew/issues/42553
brew update || brew update
# List of homebrew formulae to install in the order they appear.
# We require node, go and ninja for our build and tests, and all the others are
# dependencies of pyenv.
REQUIREMENTS="node.js
go
ninja
readline
autoconf
pkg-config
openssl"
# Install node, go, ninja, pyenv and dependencies
for pkg in $REQUIREMENTS; do
# Install package, or upgrade it if it is already installed
brew install $pkg || brew outdated $pkg || brew upgrade $pkg
done
# In order to work with ycmd, python *must* be built as a shared library. The
# most compatible way to do this on OS X is with --enable-framework. This is
# set via the PYTHON_CONFIGURE_OPTS option
export PYTHON_CONFIGURE_OPTS="--enable-framework"
ycmd-0+20160327+gitc3e6904.orig/appveyor.yml 0000644 0001750 0001750 00000001646 12677434535 016652 0 ustar onur onur version: '{build}'
branches:
# Since Homu does not support AppVeyor, we ignore the branch it uses.
except:
- auto
environment:
USE_CLANG_COMPLETER: true
matrix:
# We only test MSVC 11 and 12 with Python 3.5 on 64 bits.
- msvc: 11
arch: 64
python: 35
- msvc: 12
arch: 64
python: 35
- msvc: 14
arch: 32
python: 35
# We only test Python 2.7 with MSVC 14 on 64 bits.
- msvc: 14
arch: 64
python: 27
- msvc: 14
arch: 64
python: 35
install:
- ci\appveyor\appveyor_install.bat
build_script:
- python run_tests.py --msvc %MSVC%
# Disable automatic tests
test: off
cache:
- '%LOCALAPPDATA%\pip\cache' # Python packages from pip
- '%APPDATA%\npm-cache' # Node packages from npm
- '%USERPROFILE%\.cargo' # Cargo package deps
- '%APPVEYOR_BUILD_FOLDER%\clang_archives' # Clang downloads
- '%APPVEYOR_BUILD_FOLDER%\third_party\racerd\target' # Racerd compilation
ycmd-0+20160327+gitc3e6904.orig/check_core_version.py 0000755 0001750 0001750 00000002356 12677434535 020470 0 ustar onur onur # Copyright (C) 2015 Google Inc.
#
# This file is part of ycmd.
#
# ycmd is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ycmd is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ycmd. If not, see .
import sys
import os
import ycm_core
VERSION_FILENAME = 'CORE_VERSION'
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def ExpectedCoreVersion():
return int( open( os.path.join( DirectoryOfThisScript(),
VERSION_FILENAME ) ).read() )
def CompatibleWithCurrentCoreVersion():
try:
current_core_version = ycm_core.YcmCoreVersion()
except AttributeError:
return False
return ExpectedCoreVersion() == current_core_version
if not CompatibleWithCurrentCoreVersion():
sys.exit( 2 )
sys.exit( 0 )
ycmd-0+20160327+gitc3e6904.orig/CODE_OF_CONDUCT.md 0000644 0001750 0001750 00000004521 12677434535 017054 0 ustar onur onur # Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all people who
contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to
fairly and consistently applying these principles to every aspect of managing
this project. Project maintainers who do not follow or enforce the Code of
Conduct may be permanently removed from the project team.
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer at val@markovic.io. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. Maintainers are
obligated to maintain confidentiality with regard to the reporter of an
incident.
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.3.0, available at
[http://contributor-covenant.org/version/1/3/0/][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/3/0/
ycmd-0+20160327+gitc3e6904.orig/CONTRIBUTING.md 0000644 0001750 0001750 00000017771 12677434535 016521 0 ustar onur onur Writing good issue reports
==========================
First things first: **the issue tracker is NOT for tech support**. It is for
reporting bugs and requesting features. If your issue amounts to "I can't get
ycmd to work on my machine" and the reason why is obviously related to your
machine configuration and the problem would not be resolved with _reasonable_
changes to the ycmd codebase, then the issue is likely to be closed.
**A good place to ask questions is the [ycmd-users][] Google group**. Rule of
thumb: if you're not sure whether your problem is a real bug, ask on the group.
**ycmd compiles just fine**; [the build bots say so][build-bots]. If the bots are
green and ycmd doesn't compile on your machine, then _your machine is the root
cause_. Now read the first paragraph again.
Realize that quite literally _thousands_ of people have gotten ycmd to work
successfully so if you can't, it's probably because you have a peculiar
system/Vim configuration or you didn't go through the docs carefully enough.
It's very unlikely to be caused by an actual bug in ycmd because someone would
have already found it and reported it.
This leads us to point #2: **make sure you have checked the docs before
reporting an issue**. The docs are extensive and cover a ton of things; there's
also an FAQ at the bottom that quite possibly addresses your problem.
Further, **search the issue tracker for similar issues** before creating a new
one. There's no point in duplication; if an existing issue addresses your
problem, please comment there instead of creating a duplicate.
You should also **search the archives of the [ycmd-users][] mailing list**.
Lastly, **make sure you are running the latest version of ycmd**. The issue you
have encountered may have already been fixed. **Don't forget to recompile
ycm_core.so too** (usually by just running `install.py` again).
OK, so we've reached this far. You need to create an issue. First realize that
the time it takes to fix your issue is a multiple of how long it takes the
developer to reproduce it. The easier it is to reproduce, the quicker it'll be
fixed.
Here are the things you should do when creating an issue:
1. **Write a step-by-step procedure that when performed repeatedly reproduces
your issue.** If we can't reproduce the issue, then we can't fix it. It's
that simple.
2. **Create a test case for your issue**. This is critical. Don't talk about how
"when I have X in my file" or similar, _create a file with X in it_ and put
the contents inside code blocks in your issue description. Try to make this
test file _as small as possible_. Don't just paste a huge, 500 line source
file you were editing and present that as a test. _Minimize_ the file so that
the problem is reproduced with the smallest possible amount of test data.
3. **Include your OS and OS version.**
Creating good pull requests
===========================
1. **Follow the code style of the existing codebase.**
- The Python code **DOES NOT** follow PEP 8. This is not an oversight, this
is by choice. You can dislike this as much as you want, but you still need
to follow the existing style. Look at other Python files to see what the
style is.
- The C++ code has an automated formatter (`style_format.sh` that runs
`astyle`) but it's not perfect. Again, look at the other C++ files and
match the code style you see.
2. **Your code needs to be well written and easy to maintain**. This is of the
_utmost_ importance. Other people will have to maintain your code so don't
just throw stuff against the wall until things kinda work.
3. **Split your pull request into several smaller ones if possible.** This
makes it easier to review your changes, which means they will be merged
faster.
4. **Write tests for your code**. Your pull request is unlikely to be merged
without tests. See [TESTS.md][ycmd-tests] for instructions on running the
tests.
5. **Explain in detail why your pull request makes sense.** Ask yourself, would
this feature be helpful to others? Not just a few people, but a lot of
ycmd's users? See, good features are useful to many. If your feature is only
useful to you and _maybe_ a couple of others, then that's not a good
feature. There is such a thing as “feature overload”. When software
accumulates so many features of which most are only useful to a handful,
then that software has become “bloated”. We don't want that.
Requests for features that are obscure or are helpful to but a few, or are
not part of ycmd's "vision" will be rejected. Yes, even if you provide a
patch that completely implements it.
Please include details on exactly what you would like to see, and why. The
why is important - it's not always clear why a feature is really useful. And
sometimes what you want can be done in a different way if the reason for the
change is known. _What goal is your change trying to accomplish?_
You should also use our [Vagrant config when working on ycmd][dev-setup].
There's _tons_ of gotchas when setting up the correct environment and they've
all been worked out for you with Vagrant. Save yourself the trouble and use it.
Writing code that runs on Python 2 & 3
======================================
We support Python 2.6, 2.7 and 3.3+. Since we use
[`python-future`][python-future], you should mostly write Python 3 as normal.
Here's what you should watch out for:
- New files should start with the following prologue after the copyright header:
```python
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from builtins import * # noqa
```
- Write `dict(a=1, b=2)` instead of `{'a':1, 'b':2}`. `python-future` patches
`dict()` to return a dictionary like the one from Python 3, but it can't patch
dictionary literals. You could also create a dict with `d = dict()` and then
use `d.update()` on it with a dict literal.
- Read the [_What Else You Need to Know_][what-else] doc from `python-future`.
- Create `bytes` objects from literals like so: `bytes( b'foo' )`. Note that
`bytes` is patched by `python-future` on py2.
- Be careful when passing the `bytes` type from `python-future` to python
libraries (includes the standard library) on py2; while that type should in
theory behave just like `str` on py2, some libraries might have issues. If you
encounter any, pass the value through `future.utils`'s `native()` function
which will convert `bytes` to a real `str` (again, only on py2). Heed this
advice for your own sanity; behind it are 40 hours of debugging and an
instance of tears-down-the-cheek crying at 2 am.
- **Use the `ToBytes()` and `ToUnicode()` helper functions from
`ycmd/utils.py`.** They work around weirdness, complexity and bugs in
`python-future` and behave as you would expect. They're also extensively
covered with tests.
- Use `from future.utils import iteritems`
then `for key, value in iteritems( dict_obj )` to efficiently iterate dicts on
py2 & py3
- Use `from future.utils import itervalues` then `for value in itervalues(
dict_obj )` to efficiently iterate over values in dicts on py2 & py3
- `future.utils` has `PY2` and `PY3` constants that are `True` in the respective
interpreter; be careful about checking for py3 (better to check for py2);
don't write code that will break on py4!
- If you run tests and get failures on importing ycm_core that mention
`initycm_core` or `PyInit_ycm_core`, you've built the C++ parts of ycmd for
py2 and are trying to run tests in py3 (or vice-versa). Rebuild!
[build-bots]: https://travis-ci.org/Valloric/ycmd
[ycmd-users]: https://groups.google.com/forum/?hl=en#!forum/ycmd-users
[ycmd-tests]: https://github.com/Valloric/ycmd/blob/master/TESTS.md
[dev-setup]: https://github.com/Valloric/ycmd/blob/master/DEV_SETUP.md
[python-future]: http://python-future.org/index.html
[what-else]: http://python-future.org/what_else.html
ycmd-0+20160327+gitc3e6904.orig/cpp/ 0000755 0001750 0001750 00000000000 12677434542 015033 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/cpp/CMakeLists.txt 0000644 0001750 0001750 00000020121 12677434535 017571 0 ustar onur onur # Copyright (C) 2011, 2012 Google Inc.
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# YouCompleteMe is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see .
if ( DEFINED ENV{TRAVIS} )
# We lie to Travis CI about the min CMake version we need. For what we use
# Travis for, the old version of CMake that it has is good enough.
cmake_minimum_required( VERSION 2.8 )
else()
if ( APPLE )
# OSX requires CMake >= 2.8.12, see YCM issue #1439
cmake_minimum_required( VERSION 2.8.12 )
else()
# CMake 2.8.11 is the latest available version on RHEL/CentOS 7
cmake_minimum_required( VERSION 2.8.11 )
endif()
endif()
project( YouCompleteMe )
# Get the core version
file( STRINGS "../CORE_VERSION" YCMD_CORE_VERSION )
add_definitions( -DYCMD_CORE_VERSION=${YCMD_CORE_VERSION} )
option( UNIVERSAL "Build universal mac binary" OFF )
if ( CMAKE_GENERATOR STREQUAL Xcode )
set( CMAKE_GENERATOR_IS_XCODE true )
endif()
if ( ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" )
set( SYSTEM_IS_FREEBSD true )
endif()
if ( ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" )
set( SYSTEM_IS_OPENBSD true )
endif()
if ( ${CMAKE_SYSTEM_NAME} MATCHES "SunOS" )
set( SYSTEM_IS_SUNOS true )
endif()
# Check if platform is 64 bit
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
set( 64_BIT_PLATFORM 0 )
else()
set( 64_BIT_PLATFORM 1 )
endif()
#############################################################################
# Turning on this flag tells cmake to emit a compile_commands.json file.
# This file can be used to load compilation flags into YCM. See here for more
# details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
#############################################################################
# This is needed so that on macs, the library is built in both 32 bit and 64 bit
# versions. Without this python might refuse to load the module, depending on
# how python was built.
# On Mac, boost needs to be compiled universal as well, if used instead of the
# included BoostParts lib. For brew, that's
# "brew install boost --universal"
# If the user chose to use the system libclang.dylib (or the libclang.dylib
# binary downloaded from llvm.org) on a mac, then we don't specify universal
# binary building since the system libclang on macs is not universal (and thus
# linking would fail with universal).
if ( UNIVERSAL AND NOT USE_SYSTEM_LIBCLANG )
set( CMAKE_OSX_ARCHITECTURES "i386;x86_64" )
endif()
#############################################################################
# To shut up the warning about CMake policy CMP0042
set( CMAKE_MACOSX_RPATH ON )
#############################################################################
if ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
set( COMPILER_IS_CLANG true )
# Linux machines don't necessarily have libc++ installed alongside clang,
# but HAS_LIBCXX11 doesn't always trigger for machines that DO have libc++. We
# know that at least all the Mac OS versions we support that use Clang have
# libc++, so we're safe there. On FreeBSD 9 libc++ is an optional build
# toggle. On FreeBSD 10 it is the default.
if ( HAS_LIBCXX11 OR APPLE OR SYSTEM_IS_FREEBSD )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" )
endif()
# Ninja will by default prevent Clang from outputting diagnostics in color, so
# we force color output
if ( CMAKE_GENERATOR STREQUAL "Ninja" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics" )
endif()
endif()
#############################################################################
# Force release build by default, speed is of the essence
if ( NOT CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Release )
endif()
#############################################################################
# Determining the presence of C++11 support in the compiler
set( CPP11_AVAILABLE false )
if ( CMAKE_COMPILER_IS_GNUCXX )
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if ( GCC_VERSION VERSION_GREATER 4.6 OR GCC_VERSION VERSION_EQUAL 4.6 )
set( CPP11_AVAILABLE true )
endif()
elseif( COMPILER_IS_CLANG )
set( CPP11_AVAILABLE true )
set( CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11" )
set( CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++" )
endif()
#############################################################################
# For MSVC enable UNICODE and compilation on multiple processors
if ( MSVC )
add_definitions( /DUNICODE /D_UNICODE /Zc:wchar_t- )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP" )
endif()
# Solves the conflict in names of hypot in python sources and boost::python
if ( MINGW )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include cmath")
endif()
# Due to a bug/misconfiguration/stupidity, boost 1.52 and libc++ don't like each
# other much: a compilation error "Constexpr function never produces a constant
# expression" pops up when trying to compile anything that uses
# boost/chrono/duration.hpp (namely boost/thread for us). This is a workaround
# that prevents this from happening. Also present in cpp/BoostParts/CMakeLists.txt.
# See here for more details: https://svn.boost.org/trac/boost/ticket/7671
# TODO: remove this when it's fixed upstream (probably boost 1.53).
add_definitions( -DBOOST_THREAD_DONT_USE_CHRONO )
if( MSVC OR CYGWIN )
# BOOST_ALL_NO_LIB turns off MSVC library autolinking
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
if( WIN32 OR CYGWIN )
# BOOST_PYTHON_SOURCE makes boost use the correct __declspec
add_definitions( -DBOOST_PYTHON_SOURCE -DBOOST_THREAD_USE_LIB )
if ( 64_BIT_PLATFORM )
# Enables python compilation for 64-bit Windows
add_definitions( -DMS_WIN64 )
endif()
endif()
#############################################################################
# When used with Clang, adding the -std=c++0x flag to CMAKE_CXX_FLAGS will cause
# the compiler to output a warning during linking:
# clang: warning: argument unused during compilation: '-std=c++0x'
# This is caused by cmake passing this flag to the linking stage which it
# shouldn't do. It's ignored so it does no harm, but the warning is annoying.
#
# Putting the flag in add_definitions() works around the issue, even though it
# shouldn't in theory go there.
if ( CPP11_AVAILABLE )
message( "Your C++ compiler supports C++11, compiling in that mode." )
# Cygwin needs its hand held a bit; see issue #473
if ( CYGWIN AND CMAKE_COMPILER_IS_GNUCXX )
add_definitions( -std=gnu++0x )
else()
add_definitions( -std=c++0x )
endif()
else()
message(
"Your C++ compiler does NOT support C++11, compiling in C++03 mode." )
endif()
#############################################################################
# Note: build.py always explicitly sets this option, so the default used here
# rarely matters.
option( USE_PYTHON2 "If on, link to Python 2 instead of 3" ON )
if ( USE_PYTHON2 )
set( Python_ADDITIONAL_VERSIONS 2.7 2.6 )
find_package( PythonLibs 2.6 REQUIRED ) # 2.6 is ONLY the mininum
if ( NOT PYTHONLIBS_VERSION_STRING VERSION_LESS "3.0.0" )
message( FATAL_ERROR
"You set USE_PYTHON2 to make CMake find python2 libs only, but CMake "
"found python3 libs instead. Either don't set USE_PYTHON2 or install the "
"necessary python2 headers & libraries." )
endif()
else()
set( Python_ADDITIONAL_VERSIONS 3.6 3.5 3.4 3.3 )
find_package( PythonLibs 3.3 REQUIRED ) # 3.3 is ONLY the mininum
endif()
#############################################################################
option( USE_SYSTEM_BOOST "Set to ON to use the system boost libraries" OFF )
if (NOT USE_SYSTEM_BOOST)
add_subdirectory( BoostParts )
endif()
add_subdirectory( ycm )
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ 0000755 0001750 0001750 00000000000 12677434535 015625 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/LetterNode.h 0000644 0001750 0001750 00000003271 12677434535 020046 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef LETTERNODE_H_EIZ6JVWC
#define LETTERNODE_H_EIZ6JVWC
#include "LetterNodeListMap.h"
#include
#include
#include
#include
#include
namespace YouCompleteMe {
class LetterNode : boost::noncopyable {
public:
LetterNode( char letter, int index );
// this is for root nodes
explicit LetterNode( const std::string &text );
inline bool LetterIsUppercase() const {
return is_uppercase_;
}
inline const std::list< LetterNode * > *NodeListForLetter( char letter ) {
return letters_.ListPointerAt( letter );
}
inline void PrependNodeForLetter( char letter, LetterNode *node ) {
letters_[ letter ].push_front( node );
}
inline int Index() const {
return index_;
}
private:
LetterNodeListMap letters_;
std::vector< boost::shared_ptr< LetterNode > > letternode_per_text_index_;
bool is_uppercase_;
int index_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: LETTERNODE_H_EIZ6JVWC */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/CMakeLists.txt 0000644 0001750 0001750 00000043503 12677434535 020372 0 ustar onur onur # Copyright (C) 2011, 2012 Google Inc.
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# YouCompleteMe is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see .
cmake_minimum_required( VERSION 2.8.7 )
project( ycm_core )
option( USE_DEV_FLAGS "Use compilation flags meant for YCM developers" OFF )
option( USE_CLANG_COMPLETER "Use Clang semantic completer for C/C++/ObjC" OFF )
option( USE_SYSTEM_LIBCLANG "Set to ON to use the system libclang library" OFF )
set( PATH_TO_LLVM_ROOT "" CACHE PATH "Path to the root of a LLVM+Clang binary distribution" )
set( EXTERNAL_LIBCLANG_PATH "" CACHE PATH "Path to the libclang library to use" )
if ( USE_CLANG_COMPLETER AND
NOT USE_SYSTEM_LIBCLANG AND
NOT PATH_TO_LLVM_ROOT AND
NOT EXTERNAL_LIBCLANG_PATH )
set( CLANG_VERSION "3.8.0" )
if ( APPLE )
set( CLANG_DIRNAME "clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin" )
set( CLANG_SHA256
"e5a961e04b0e1738bbb5b824886a34932dc13b0af699d1fe16519d814d7b776f" )
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.xz" )
elseif ( WIN32 )
if( 64_BIT_PLATFORM )
set( CLANG_DIRNAME "LLVM-${CLANG_VERSION}-win64" )
set( CLANG_SHA256
"f9c3147157db32beab025314db9b82c600e182d82994880c1d844c70e29d76ef" )
else()
set( CLANG_DIRNAME "LLVM-${CLANG_VERSION}-win32" )
set( CLANG_SHA256
"ebdb056ebc6efd57c0643733a099920d1d5760a4d570580243e6c63f4b52920f" )
endif()
set( CLANG_FILENAME "${CLANG_DIRNAME}.exe" )
else()
if ( 64_BIT_PLATFORM )
# We MUST support the latest Ubuntu LTS release!
# At the time of writing, that's 14.04. Switch to next LTS ~6 months after
# it comes out.
set( CLANG_DIRNAME "clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04" )
set( CLANG_SHA256
"3120c3055ea78bbbb6848510a2af70c68538b990cb0545bac8dad01df8ff69d7" )
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.xz" )
else()
# Clang 3.3 is the last version with pre-built x86 binaries upstream.
# That's too old now.
message( FATAL_ERROR "No pre-built Clang ${CLANG_VERSION} binaries for 32 bit linux. "
"You'll have to compile Clang ${CLANG_VERSION} from source. "
"See the YCM docs for details on how to use a user-compiled libclang." )
endif()
endif()
# Check if the Clang archive is already downloaded and its checksum is correct.
# If this is not the case, remove it if needed and download it.
set( CLANG_DOWNLOAD ON )
set( CLANG_LOCAL_FILE
"${CMAKE_SOURCE_DIR}/../clang_archives/${CLANG_FILENAME}" )
if( EXISTS "${CLANG_LOCAL_FILE}" )
file( SHA256 "${CLANG_LOCAL_FILE}" CLANG_LOCAL_SHA256 )
if( "${CLANG_LOCAL_SHA256}" STREQUAL "${CLANG_SHA256}" )
set( CLANG_DOWNLOAD OFF )
else()
file( REMOVE "${CLANG_LOCAL_FILE}" )
endif()
endif()
if( CLANG_DOWNLOAD )
message( "Downloading Clang ${CLANG_VERSION}" )
set( CLANG_URL "http://llvm.org/releases/${CLANG_VERSION}" )
file(
DOWNLOAD "${CLANG_URL}/${CLANG_FILENAME}" "${CLANG_LOCAL_FILE}"
SHOW_PROGRESS EXPECTED_HASH SHA256=${CLANG_SHA256}
)
else()
message( "Using Clang archive: ${CLANG_LOCAL_FILE}" )
endif()
# Copy and extract the Clang archive in the building directory.
file( COPY "${CLANG_LOCAL_FILE}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/../" )
if ( CLANG_FILENAME MATCHES ".+bz2" )
execute_process( COMMAND tar -xjf ${CLANG_FILENAME} )
elseif( CLANG_FILENAME MATCHES ".+xz" )
execute_process( COMMAND tar -xJf ${CLANG_FILENAME} )
elseif( CLANG_FILENAME MATCHES ".+exe" )
# Find 7-zip executable in the PATH and using the registry
find_program( 7Z_EXECUTABLE 7z PATHS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\7-Zip;Path] )
if ( NOT 7Z_EXECUTABLE )
message( FATAL_ERROR
"7-zip is needed to extract the files from the Clang installer. "
"Install it and try again." )
endif()
execute_process( COMMAND ${7Z_EXECUTABLE} x ${CLANG_FILENAME} OUTPUT_QUIET )
else()
execute_process( COMMAND tar -xzf ${CLANG_FILENAME} )
endif()
# We need to set PATH_TO_LLVM_ROOT. To do that, we first have to find the
# folder name the archive produced. It isn't the archive base name.
# On Windows, the find command is not available so we directly set the path.
if ( WIN32 )
# Since 7-zip release version 15.12, files are not anymore extracted in
# $_OUTDIR folder but directly to the root. So, we check the existence of
# $_OUTDIR to appropriately set PATH_TO_LLVM_ROOT.
if ( EXISTS ${CMAKE_CURRENT_BINARY_DIR}/../$_OUTDIR )
set( PATH_TO_LLVM_ROOT ${CMAKE_CURRENT_BINARY_DIR}/../$_OUTDIR )
else()
set( PATH_TO_LLVM_ROOT ${CMAKE_CURRENT_BINARY_DIR}/.. )
endif()
else()
execute_process( COMMAND
find ${CMAKE_CURRENT_BINARY_DIR}/.. -maxdepth 1 -type d -name clang*
OUTPUT_VARIABLE PATH_TO_LLVM_ROOT
OUTPUT_STRIP_TRAILING_WHITESPACE )
endif()
endif()
if ( PATH_TO_LLVM_ROOT OR USE_SYSTEM_LIBCLANG OR EXTERNAL_LIBCLANG_PATH )
set( USE_CLANG_COMPLETER TRUE )
endif()
if ( USE_CLANG_COMPLETER AND
NOT PATH_TO_LLVM_ROOT AND
NOT USE_SYSTEM_LIBCLANG AND
NOT EXTERNAL_LIBCLANG_PATH )
message( FATAL_ERROR
"You have not specified which libclang to use. You have several options:\n"
" 1. Set PATH_TO_LLVM_ROOT to a path to the root of a LLVM+Clang binary "
"distribution. You can download such a binary distro from llvm.org. This "
"is the recommended approach.\n"
" 2. Set USE_SYSTEM_LIBCLANG to ON; this makes YCM search for the system "
"version of libclang.\n"
" 3. Set EXTERNAL_LIBCLANG_PATH to a path to whatever "
"libclang.[so|dylib|dll] you wish to use.\n"
"You HAVE to pick one option. See the docs for more information.")
endif()
if ( USE_CLANG_COMPLETER )
message( "Using libclang to provide semantic completion for C/C++/ObjC" )
else()
message( "NOT using libclang, no semantic completion for C/C++/ObjC will be "
"available" )
endif()
if ( PATH_TO_LLVM_ROOT )
set( CLANG_INCLUDES_DIR "${PATH_TO_LLVM_ROOT}/include" )
else()
set( CLANG_INCLUDES_DIR "${CMAKE_SOURCE_DIR}/llvm/include" )
endif()
if ( NOT IS_ABSOLUTE "${CLANG_INCLUDES_DIR}" )
get_filename_component(CLANG_INCLUDES_DIR
"${CMAKE_BINARY_DIR}/${CLANG_INCLUDES_DIR}" ABSOLUTE)
endif()
if ( NOT EXTERNAL_LIBCLANG_PATH AND PATH_TO_LLVM_ROOT )
if ( MINGW )
set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/bin" )
else()
set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/lib" )
endif()
# Need TEMP because find_library does not work with an option variable
find_library( TEMP NAMES clang libclang
PATHS ${LIBCLANG_SEARCH_PATH}
NO_DEFAULT_PATH )
set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
endif()
# This is a workaround for a CMake bug with include_directories(SYSTEM ...)
# on Mac OS X. Bug report: http://public.kitware.com/Bug/view.php?id=10837
if ( APPLE )
set( CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem " )
endif()
if ( USE_SYSTEM_BOOST )
find_package( Boost REQUIRED COMPONENTS python filesystem system regex thread )
else()
set( Boost_INCLUDE_DIR ${BoostParts_SOURCE_DIR} )
set( Boost_LIBRARIES BoostParts )
endif()
file( GLOB_RECURSE SERVER_SOURCES *.h *.cpp )
# The test sources are a part of a different target, so we remove them
# The CMakeFiles cpp file is picked up when the user creates an in-source build,
# and we don't want that. We also remove client-specific code
file( GLOB_RECURSE to_remove tests/*.h tests/*.cpp CMakeFiles/*.cpp *client* )
if( to_remove )
list( REMOVE_ITEM SERVER_SOURCES ${to_remove} )
endif()
if ( USE_CLANG_COMPLETER )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/ClangCompleter" )
add_definitions( -DUSE_CLANG_COMPLETER )
else()
file( GLOB_RECURSE to_remove_clang ClangCompleter/*.h ClangCompleter/*.cpp )
if( to_remove_clang )
list( REMOVE_ITEM SERVER_SOURCES ${to_remove_clang} )
endif()
endif()
# The SYSTEM flag makes sure that -isystem[header path] is passed to the
# compiler instead of the standard -I[header path]. Headers included with
# -isystem do not generate warnings (and they shouldn't; e.g. boost warnings are
# just noise for us since we won't be changing them).
# Since there is no -isystem flag equivalent on Windows, headers from external
# projects may conflict with our headers and override them. We prevent that by
# including these directories after ours.
include_directories(
SYSTEM
${Boost_INCLUDE_DIR}
${PYTHON_INCLUDE_DIRS}
${CLANG_INCLUDES_DIR}
)
#############################################################################
# One can use the system libclang.[so|dylib] like so:
# cmake -DUSE_SYSTEM_LIBCLANG=1 [...]
# One can also explicitely pick the external libclang.[so|dylib] for use like so:
# cmake -DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so [...]
# The final .so we build will then first look in the same dir in which it is
# located for libclang.so. This is provided by the rpath = $ORIGIN feature.
if ( EXTERNAL_LIBCLANG_PATH OR USE_SYSTEM_LIBCLANG )
if ( USE_SYSTEM_LIBCLANG )
if ( APPLE )
set( ENV_LIB_PATHS ENV DYLD_LIBRARY_PATH )
elseif ( UNIX )
set( ENV_LIB_PATHS ENV LD_LIBRARY_PATH )
elseif ( WIN32 )
set( ENV_LIB_PATHS ENV PATH )
else ()
set( ENV_LIB_PATHS "" )
endif()
# On Debian-based systems, llvm installs into /usr/lib/llvm-x.y.
file( GLOB SYS_LLVM_PATHS "/usr/lib/llvm*/lib" )
# Need TEMP because find_library does not work with an option variable
# On Debian-based systems only a symlink to libclang.so.1 is created
find_library( TEMP
NAMES
clang
libclang.so.1
PATHS
${ENV_LIB_PATHS}
/usr/lib
/usr/lib/llvm
${SYS_LLVM_PATHS}
/Library/Developer/CommandLineTools/usr/lib
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib )
set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
else()
# For Macs, we do things differently; look further in this file.
if ( NOT APPLE )
# Setting this to true makes sure that libraries we build will have our rpath
# set even without having to do "make install"
set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE )
set( CMAKE_INSTALL_RPATH "\$ORIGIN" )
endif()
endif()
# In Clang 3.7, the library target is a symlink of the soversion one.
# Since it will be copied in the project folder, we need the symlinked
# library.
get_filename_component( LIBCLANG_TARGET "${EXTERNAL_LIBCLANG_PATH}" REALPATH )
message(
"Using external libclang: ${LIBCLANG_TARGET}" )
else()
set( LIBCLANG_TARGET )
endif()
if ( EXTRA_RPATH )
set( CMAKE_INSTALL_RPATH "${EXTRA_RPATH}:${CMAKE_INSTALL_RPATH}" )
endif()
# Needed on Linux machines, but not on Macs and OpenBSD
if ( UNIX AND NOT ( APPLE OR SYSTEM_IS_OPENBSD ) )
set( EXTRA_LIBS rt )
endif()
#############################################################################
add_library( ${PROJECT_NAME} SHARED
${SERVER_SOURCES}
)
target_link_libraries( ${PROJECT_NAME}
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
${LIBCLANG_TARGET}
${EXTRA_LIBS}
)
if( LIBCLANG_TARGET )
# When building with MSVC, we need to copy libclang.dll instead of libclang.lib
if( MSVC )
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${PATH_TO_LLVM_ROOT}/bin/libclang.dll" "$"
)
else()
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${LIBCLANG_TARGET}" "$"
)
if( APPLE )
# In OS X El Capitan, Apple introduced System Integrity Protection.
# Amongst other things, this introduces features to the dynamic loader
# (dyld) which cause it to "sanitise" (and complain about) embedded
# LC_RPATH entries which contain @executable_path when then are loaded
# into "restricted" binaries. For our purposes, "restricted" here means
# "supplied by Apple" and includes the system versions of python. For
# unknown reasons, the libclang.dylib that comes from llvm.org includes an
# LC_RPATH entry '@executable_path/../lib' which causes the OS X dynamic
# loader to print a cryptic warning to stderr of the form:
#
# dyld: warning, LC_RPATH @executable_path/../lib in
# /path/to/ycmd/libclang.dylib being ignored in restricted program
# because of @executable_path
#
# In order to prevent this harmless and annoying message appearing, we
# simply strip the rpath entry from the dylib. There's no way any
# @executable_path that python might have could be in any way useful to
# libclang.dylib, so this seems perfectly safe.
get_filename_component( LIBCLANG_TAIL ${LIBCLANG_TARGET} NAME )
add_custom_command( TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND install_name_tool
"-delete_rpath"
"@executable_path/../lib"
"$/${LIBCLANG_TAIL}"
)
endif()
endif()
endif()
#############################################################################
# Things are a bit different on Macs when using an external libclang.dylib; here
# we want to make sure we use @loader_path/libclang.dylib instead of
# @rpath/libclang.dylib in the final ycm_core.so. If we use the
# @rpath version, then it may load the system libclang which the user
# explicitely does not want (otherwise the user would specify
# USE_SYSTEM_LIBCLANG). If we hardcode with `@loader_path/libclang.dylib`,
# it guarantees to search `@loader_path` for libclang.dylib first and use it
# only. So with `@loader_path`, we make sure that only the libclang.dylib
# present in the same directory as our ycm_core.so is used.
# And the extra `rpath` is helpful to find libclang.dylib's dependencies
# if it is built with `--enable-shared` flag.
if ( EXTERNAL_LIBCLANG_PATH AND APPLE )
get_filename_component(EXTRA_LIB_PATH ${EXTERNAL_LIBCLANG_PATH} DIRECTORY)
set_target_properties(${PROJECT_NAME}
PROPERTIES LINK_FLAGS "-Wl,-rpath,${EXTRA_LIB_PATH}")
add_custom_command( TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND install_name_tool
"-change"
"@rpath/libclang.dylib"
"@loader_path/libclang.dylib"
"$"
)
endif()
#############################################################################
# We don't want the "lib" prefix, it can screw up python when it tries to search
# for our module
set_target_properties( ${PROJECT_NAME} PROPERTIES PREFIX "")
if ( WIN32 OR CYGWIN )
# DLL platforms put dlls in the RUNTIME_OUTPUT_DIRECTORY
# First for the generic no-config case (e.g. with mingw)
set_target_properties( ${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. )
# Second, for multi-config builds (e.g. msvc)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
set_target_properties( ${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_SOURCE_DIR}/../.. )
endforeach()
if ( WIN32 )
# This is the extension for compiled Python modules on Windows
set_target_properties( ${PROJECT_NAME} PROPERTIES SUFFIX ".pyd")
elseif ( CYGWIN )
# This is the extension for compiled Python modules in Cygwin
set_target_properties( ${PROJECT_NAME} PROPERTIES SUFFIX ".dll")
endif()
else()
# Even on macs, we want a .so extension instead of a .dylib which is what
# cmake would give us by default. Python won't recognize a .dylib as a module,
# but it will recognize a .so
set_target_properties( ${PROJECT_NAME} PROPERTIES SUFFIX ".so")
endif()
set_target_properties( ${PROJECT_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. )
#############################################################################
# For some reason, Xcode is too dumb to understand the -isystem flag and thus
# borks on warnings in Boost.
if ( USE_DEV_FLAGS AND ( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG ) AND
NOT CMAKE_GENERATOR_IS_XCODE )
# We want all warnings, and warnings should be treated as errors
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror" )
endif()
#############################################################################
# We want warnings if we accidentally use C++11 features
# We can't use this warning on FreeBSD because std headers on that OS are dumb.
# See here: https://github.com/Valloric/YouCompleteMe/issues/260
if ( USE_DEV_FLAGS AND COMPILER_IS_CLANG AND NOT CMAKE_GENERATOR_IS_XCODE AND
NOT SYSTEM_IS_FREEBSD )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wc++98-compat" )
endif()
#############################################################################
if( SYSTEM_IS_SUNOS )
# SunOS needs this setting for thread support
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads" )
endif()
if( SYSTEM_IS_OPENBSD OR SYSTEM_IS_FREEBSD )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread" )
endif()
add_subdirectory( tests )
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ 0000755 0001750 0001750 00000000000 12677434535 020524 5 ustar onur onur ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ClangUtils.cpp 0000644 0001750 0001750 00000003075 12677434535 023302 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "ClangUtils.h"
#include "standard.h"
namespace YouCompleteMe {
std::string CXStringToString( CXString text ) {
std::string final_string;
if ( !text.data )
return final_string;
final_string = std::string( clang_getCString( text ) );
clang_disposeString( text );
return final_string;
}
bool CursorIsValid( CXCursor cursor ) {
return !clang_Cursor_isNull( cursor ) &&
!clang_isInvalid( clang_getCursorKind( cursor ) );
}
bool CursorIsReference( CXCursor cursor ) {
return clang_isReference( clang_getCursorKind( cursor ) );
}
bool CursorIsDeclaration( CXCursor cursor ) {
return clang_isDeclaration( clang_getCursorKind( cursor ) );
}
std::string CXFileToFilepath( CXFile file ) {
return CXStringToString( clang_getFileName( file ) );
}
std::string ClangVersion() {
return CXStringToString( clang_getClangVersion() );
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/Diagnostic.h 0000644 0001750 0001750 00000004673 12677434535 022773 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef DIAGNOSTIC_H_BZH3BWIZ
#define DIAGNOSTIC_H_BZH3BWIZ
#include "standard.h"
#include "Range.h"
#include "Location.h"
#include
#include
namespace YouCompleteMe {
enum DiagnosticKind {
INFORMATION = 0,
ERROR,
WARNING
};
/// Information about a replacement that can be made to the source to "fix" a
/// diagnostic.
struct FixItChunk {
/// The replacement string. This string should replace the source range
/// represented by 'range'.
std::string replacement_text;
/// The range within the file to replace with replacement_text.
Range range;
bool operator == ( const FixItChunk &other ) const {
return replacement_text == other.replacement_text &&
range == other.range;
}
};
/// Collection of FixItChunks which, when applied together, fix a particular
/// diagnostic. This structure forms the reply to the "FixIt" subcommand, and
/// represents a lightweight view of a diagnostic. The location is included to
/// aid clients in applying the most appropriate FixIt based on context.
struct FixIt {
std::vector< FixItChunk > chunks;
Location location;
bool operator==( const FixIt &other ) const {
return chunks == other.chunks &&
location == other.location;
}
};
struct Diagnostic {
bool operator== ( const Diagnostic &other ) const {
return
location_ == other.location_ &&
kind_ == other.kind_ &&
text_ == other.text_;
}
Location location_;
Range location_extent_;
std::vector< Range > ranges_;
DiagnosticKind kind_;
std::string text_;
std::string long_formatted_text_;
/// The (cached) changes required to fix this diagnostic
std::vector< FixItChunk > fixits_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: DIAGNOSTIC_H_BZH3BWIZ */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/TranslationUnitStore.cpp 0000644 0001750 0001750 00000010371 12677434535 025405 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "TranslationUnitStore.h"
#include "TranslationUnit.h"
#include "Utils.h"
#include "exceptions.h"
#include
#include
#include
using boost::lock_guard;
using boost::shared_ptr;
using boost::make_shared;
using boost::mutex;
namespace YouCompleteMe {
namespace {
std::size_t HashForFlags( const std::vector< std::string > &flags ) {
return boost::hash< std::vector< std::string > >()( flags );
}
} // unnamed namespace
TranslationUnitStore::TranslationUnitStore( CXIndex clang_index )
: clang_index_( clang_index ) {
}
TranslationUnitStore::~TranslationUnitStore() {
RemoveAll();
}
shared_ptr< TranslationUnit > TranslationUnitStore::GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
bool dont_care;
return GetOrCreate( filename, unsaved_files, flags, dont_care );
}
shared_ptr< TranslationUnit > TranslationUnitStore::GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool &translation_unit_created ) {
translation_unit_created = false;
{
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
shared_ptr< TranslationUnit > current_unit = GetNoLock( filename );
if ( current_unit &&
HashForFlags( flags ) == filename_to_flags_hash_[ filename ] ) {
return current_unit;
}
// We create and store an invalid, sentinel TU so that other threads don't
// try to create a TU for the same file while we are trying to create this
// TU object. When we are done creating the TU, we will overwrite this value
// with the valid object.
filename_to_translation_unit_[ filename ] =
make_shared< TranslationUnit >();
// We need to store the flags for the sentinel TU so that other threads end
// up returning the sentinel TU while the real one is being created.
filename_to_flags_hash_[ filename ] = HashForFlags( flags );
}
boost::shared_ptr< TranslationUnit > unit;
try {
unit = boost::make_shared< TranslationUnit >( filename,
unsaved_files,
flags,
clang_index_ );
} catch ( ClangParseError & ) {
Remove( filename );
return unit;
}
{
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
filename_to_translation_unit_[ filename ] = unit;
// Flags have already been stored.
}
translation_unit_created = true;
return unit;
}
shared_ptr< TranslationUnit > TranslationUnitStore::Get(
const std::string &filename ) {
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
return GetNoLock( filename );
}
bool TranslationUnitStore::Remove( const std::string &filename ) {
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
Erase( filename_to_flags_hash_, filename );
return Erase( filename_to_translation_unit_, filename );
}
void TranslationUnitStore::RemoveAll() {
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
filename_to_translation_unit_.clear();
filename_to_flags_hash_.clear();
}
shared_ptr< TranslationUnit > TranslationUnitStore::GetNoLock(
const std::string &filename ) {
return FindWithDefault( filename_to_translation_unit_,
filename,
shared_ptr< TranslationUnit >() );
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/Documentation.h 0000644 0001750 0001750 00000003527 12677434535 023515 0 ustar onur onur // Copyright (C) 2015 ycmd contributors
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef DOCUMENTATION_H_POYSHVX8
#define DOCUMENTATION_H_POYSHVX8
#include
#include
namespace YouCompleteMe {
/// This class holds information useful for generating a documentation response
/// for a given cursor
struct DocumentationData {
/// Construct an empty object
DocumentationData() {}
/// Construct and extract information from the supplied cursor. The cursor
/// should be pointing to a canonical declaration, such as returned by
/// clang_getCanonicalCursor( clang_getCursorReferenced( cursor ) )
DocumentationData( const CXCursor &cursor );
/// XML data as parsed by libclang. This provides full semantic parsing of
/// doxygen-syntax comments.
std::string comment_xml;
/// The raw text of the comment preceding the declaration
std::string raw_comment;
/// The brief comment (either first paragraph or \brief) as parsed by libclang
std::string brief_comment;
/// The canonical type of the referenced cursor
std::string canonical_type;
/// The display name of the referenced cursor
std::string display_name;
};
} // namespace YouCompleteMe
#endif /* end of include guard: DOCUMENTATION_H_POYSHVX8 */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/CompilationDatabase.h 0000644 0001750 0001750 00000004115 12677434535 024601 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef COMPILATIONDATABASE_H_ZT7MQXPG
#define COMPILATIONDATABASE_H_ZT7MQXPG
#include
#include
#include
#include
#include
#include
#include
namespace YouCompleteMe {
struct CompilationInfoForFile {
std::vector< std::string > compiler_flags_;
std::string compiler_working_dir_;
};
// Access to Clang's internal CompilationDatabase. This class is thread-safe.
class CompilationDatabase : boost::noncopyable {
public:
// |path_to_directory| should be a string-like object.
CompilationDatabase( const boost::python::object &path_to_directory );
~CompilationDatabase();
bool DatabaseSuccessfullyLoaded();
// Returns true when a separate thread is already getting flags; this is
// useful so that the caller doesn't need to block.
bool AlreadyGettingFlags();
// NOTE: Multiple calls to this function from separate threads will be
// serialized since Clang internals are not thread-safe.
// |path_to_file| should be a string-like object.
CompilationInfoForFile GetCompilationInfoForFile(
const boost::python::object &path_to_file );
private:
bool is_loaded_;
CXCompilationDatabase compilation_database_;
boost::mutex compilation_database_mutex_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: COMPILATIONDATABASE_H_ZT7MQXPG */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/CompilationDatabase.cpp 0000644 0001750 0001750 00000006415 12677434535 025141 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "CompilationDatabase.h"
#include "ClangUtils.h"
#include "standard.h"
#include "ReleaseGil.h"
#include "PythonSupport.h"
#include
#include
#include
#include
using boost::lock_guard;
using boost::unique_lock;
using boost::try_to_lock_t;
using boost::remove_pointer;
using boost::shared_ptr;
using boost::mutex;
namespace YouCompleteMe {
typedef shared_ptr <
remove_pointer< CXCompileCommands >::type > CompileCommandsWrap;
CompilationDatabase::CompilationDatabase(
const boost::python::object &path_to_directory )
: is_loaded_( false ) {
CXCompilationDatabase_Error status;
std::string path_to_directory_string = GetUtf8String( path_to_directory );
compilation_database_ = clang_CompilationDatabase_fromDirectory(
path_to_directory_string.c_str(),
&status );
is_loaded_ = status == CXCompilationDatabase_NoError;
}
CompilationDatabase::~CompilationDatabase() {
clang_CompilationDatabase_dispose( compilation_database_ );
}
bool CompilationDatabase::DatabaseSuccessfullyLoaded() {
return is_loaded_;
}
bool CompilationDatabase::AlreadyGettingFlags() {
unique_lock< mutex > lock( compilation_database_mutex_, try_to_lock_t() );
return !lock.owns_lock();
}
CompilationInfoForFile CompilationDatabase::GetCompilationInfoForFile(
const boost::python::object &path_to_file ) {
CompilationInfoForFile info;
if ( !is_loaded_ )
return info;
std::string path_to_file_string = GetUtf8String( path_to_file );
ReleaseGil unlock;
lock_guard< mutex > lock( compilation_database_mutex_ );
CompileCommandsWrap commands(
clang_CompilationDatabase_getCompileCommands(
compilation_database_,
path_to_file_string.c_str() ), clang_CompileCommands_dispose );
uint num_commands = clang_CompileCommands_getSize( commands.get() );
if ( num_commands < 1 ) {
return info;
}
// We always pick the first command offered
CXCompileCommand command = clang_CompileCommands_getCommand(
commands.get(),
0 );
info.compiler_working_dir_ = CXStringToString(
clang_CompileCommand_getDirectory( command ) );
uint num_flags = clang_CompileCommand_getNumArgs( command );
info.compiler_flags_.reserve( num_flags );
for ( uint i = 0; i < num_flags; ++i ) {
info.compiler_flags_.push_back(
CXStringToString( clang_CompileCommand_getArg( command, i ) ) );
}
return info;
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ClangHelpers.h 0000644 0001750 0001750 00000003104 12677434535 023242 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef CLANGHELPERS_H_T3ME71LG
#define CLANGHELPERS_H_T3ME71LG
#include "Diagnostic.h"
#include "CompletionData.h"
#include "UnsavedFile.h"
#include
#include
#include
#include
namespace YouCompleteMe {
typedef boost::shared_ptr <
boost::remove_pointer< CXDiagnostic >::type > DiagnosticWrap;
std::vector< CompletionData > ToCompletionDataVector(
CXCodeCompleteResults *results );
// NOTE: CXUnsavedFiles store pointers to data in UnsavedFiles, so UnsavedFiles
// need to outlive CXUnsavedFiles!
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
const std::vector< UnsavedFile > &unsaved_files );
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
CXTranslationUnit translation_unit );
} // namespace YouCompleteMe
#endif /* end of include guard: CLANGHELPERS_H_T3ME71LG */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ClangCompleter.cpp 0000644 0001750 0001750 00000016631 12677434535 024136 0 ustar onur onur // Copyright (C) 2011-2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "ClangCompleter.h"
#include "exceptions.h"
#include "Result.h"
#include "Candidate.h"
#include "TranslationUnit.h"
#include "standard.h"
#include "CandidateRepository.h"
#include "CompletionData.h"
#include "Utils.h"
#include "ClangUtils.h"
#include "ReleaseGil.h"
#include
#include
using boost::shared_ptr;
using boost::unordered_map;
namespace YouCompleteMe {
ClangCompleter::ClangCompleter()
: clang_index_( clang_createIndex( 0, 0 ) ),
translation_unit_store_( clang_index_ ) {
// The libclang docs don't say what is the default value for crash recovery.
// I'm pretty sure it's turned on by default, but I'm not going to take any
// chances.
clang_toggleCrashRecovery( true );
}
ClangCompleter::~ClangCompleter() {
// We need to destroy all TUs before calling clang_disposeIndex because
// the translation units need to be destroyed before the index is destroyed.
// Technically, a thread could still be holding onto a shared_ptr object
// when we destroy the clang index, but since we're shutting down, we don't
// really care.
// In practice, this situation shouldn't happen because the server threads are
// Python deamon threads and will all be killed before the main thread exits.
translation_unit_store_.RemoveAll();
clang_disposeIndex( clang_index_ );
}
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit = translation_unit_store_.Get( filename );
if ( !unit )
return false;
// Thankfully, an invalid, sentinel TU always returns true for
// IsCurrentlyUpdating, so no caller will try to rely on the TU object, even
// if unit is currently pointing to a sentinel.
return unit->IsCurrentlyUpdating();
}
std::vector< Diagnostic > ClangCompleter::UpdateTranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
ReleaseGil unlock;
bool translation_unit_created;
shared_ptr< TranslationUnit > unit = translation_unit_store_.GetOrCreate(
filename,
unsaved_files,
flags,
translation_unit_created );
if ( !unit )
return std::vector< Diagnostic >();
try {
return unit->Reparse( unsaved_files );
}
catch ( ClangParseError & ) {
// If unit->Reparse fails, then the underlying TranslationUnit object is not
// valid anymore and needs to be destroyed and removed from the filename ->
// TU map.
translation_unit_store_.Remove( filename );
}
return std::vector< Diagnostic >();
}
std::vector< CompletionData >
ClangCompleter::CandidatesForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit )
return std::vector< CompletionData >();
return unit->CandidatesForLocation( line,
column,
unsaved_files );
}
Location ClangCompleter::GetDeclarationLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return Location();
}
return unit->GetDeclarationLocation( line, column, unsaved_files, reparse );
}
Location ClangCompleter::GetDefinitionLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return Location();
}
return unit->GetDefinitionLocation( line, column, unsaved_files, reparse );
}
std::string ClangCompleter::GetTypeAtLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return "no unit";
}
return unit->GetTypeAtLocation( line, column, unsaved_files, reparse );
}
std::string ClangCompleter::GetEnclosingFunctionAtLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return "no unit";
}
return unit->GetEnclosingFunctionAtLocation( line,
column,
unsaved_files,
reparse );
}
std::vector< FixIt >
ClangCompleter::GetFixItsForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return std::vector< FixIt >();
}
return unit->GetFixItsForLocationInFile( line,
column,
unsaved_files,
reparse );
}
DocumentationData ClangCompleter::GetDocsForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return DocumentationData();
}
return unit->GetDocsForLocationInFile( line,
column,
unsaved_files,
reparse );
}
void ClangCompleter::DeleteCachesForFile( const std::string &filename ) {
ReleaseGil unlock;
translation_unit_store_.Remove( filename );
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/Location.h 0000644 0001750 0001750 00000003673 12677434535 022456 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef LOCATION_H_6TLFQH4I
#define LOCATION_H_6TLFQH4I
#include "standard.h"
#include "ClangUtils.h"
#include
#include
namespace YouCompleteMe {
struct Location {
// Creates an invalid location
Location()
: line_number_( 0 ),
column_number_( 0 ),
filename_( "" ) {}
Location( const std::string &filename, uint line, uint column )
: line_number_( line ),
column_number_( column ),
filename_( filename ) {}
Location( const CXSourceLocation &location ) {
CXFile file;
uint unused_offset;
clang_getExpansionLocation( location,
&file,
&line_number_,
&column_number_,
&unused_offset );
filename_ = CXFileToFilepath( file );
}
bool operator== ( const Location &other ) const {
return
line_number_ == other.line_number_ &&
column_number_ == other.column_number_ &&
filename_ == other.filename_;
}
bool IsValid() {
return !filename_.empty();
}
uint line_number_;
uint column_number_;
// The full, absolute path
std::string filename_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: LOCATION_H_6TLFQH4I */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/TranslationUnit.cpp 0000644 0001750 0001750 00000035572 12677434535 024402 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "TranslationUnit.h"
#include "CompletionData.h"
#include "standard.h"
#include "exceptions.h"
#include "ClangUtils.h"
#include "ClangHelpers.h"
#include
#include
using boost::unique_lock;
using boost::mutex;
using boost::try_to_lock_t;
using boost::shared_ptr;
using boost::remove_pointer;
namespace YouCompleteMe {
namespace {
unsigned EditingOptions() {
return CXTranslationUnit_DetailedPreprocessingRecord |
CXTranslationUnit_Incomplete |
CXTranslationUnit_IncludeBriefCommentsInCodeCompletion |
CXTranslationUnit_CreatePreambleOnFirstParse |
clang_defaultEditingTranslationUnitOptions();
}
unsigned ReparseOptions( CXTranslationUnit translationUnit ) {
return clang_defaultReparseOptions( translationUnit );
}
unsigned CompletionOptions() {
return clang_defaultCodeCompleteOptions() |
CXCodeComplete_IncludeBriefComments;
}
void EnsureCompilerNamePresent( std::vector< const char * > &flags ) {
bool no_compiler_name_set = !flags.empty() && flags.front()[ 0 ] == '-';
if ( flags.empty() || no_compiler_name_set )
flags.insert( flags.begin(), "clang" );
}
} // unnamed namespace
typedef shared_ptr <
remove_pointer< CXCodeCompleteResults >::type > CodeCompleteResultsWrap;
TranslationUnit::TranslationUnit()
: filename_( "" ),
clang_translation_unit_( NULL ) {
}
TranslationUnit::TranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
CXIndex clang_index )
: filename_( filename ),
clang_translation_unit_( NULL ) {
std::vector< const char * > pointer_flags;
pointer_flags.reserve( flags.size() );
foreach ( const std::string & flag, flags ) {
pointer_flags.push_back( flag.c_str() );
}
EnsureCompilerNamePresent( pointer_flags );
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
const CXUnsavedFile *unsaved = cxunsaved_files.size() > 0
? &cxunsaved_files[ 0 ] : NULL;
// Actually parse the translation unit.
CXErrorCode result = clang_parseTranslationUnit2FullArgv(
clang_index,
filename.c_str(),
&pointer_flags[ 0 ],
pointer_flags.size(),
const_cast( unsaved ),
cxunsaved_files.size(),
EditingOptions(),
&clang_translation_unit_ );
if ( result != CXError_Success )
boost_throw( ClangParseError() );
}
TranslationUnit::~TranslationUnit() {
Destroy();
}
void TranslationUnit::Destroy() {
unique_lock< mutex > lock( clang_access_mutex_ );
if ( clang_translation_unit_ ) {
clang_disposeTranslationUnit( clang_translation_unit_ );
clang_translation_unit_ = NULL;
}
}
bool TranslationUnit::IsCurrentlyUpdating() const {
// We return true when the TU is invalid; an invalid TU also acts a sentinel,
// preventing other threads from trying to use it.
if ( !clang_translation_unit_ )
return true;
unique_lock< mutex > lock( clang_access_mutex_, try_to_lock_t() );
return !lock.owns_lock();
}
std::vector< Diagnostic > TranslationUnit::Reparse(
const std::vector< UnsavedFile > &unsaved_files ) {
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
Reparse( cxunsaved_files );
unique_lock< mutex > lock( diagnostics_mutex_ );
return latest_diagnostics_;
}
std::vector< CompletionData > TranslationUnit::CandidatesForLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files ) {
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return std::vector< CompletionData >();
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
const CXUnsavedFile *unsaved = cxunsaved_files.size() > 0
? &cxunsaved_files[ 0 ] : NULL;
// codeCompleteAt reparses the TU if the underlying source file has changed on
// disk since the last time the TU was updated and there are no unsaved files.
// If there are unsaved files, then codeCompleteAt will parse the in-memory
// file contents we are giving it. In short, it is NEVER a good idea to call
// clang_reparseTranslationUnit right before a call to clang_codeCompleteAt.
// This only makes clang reparse the whole file TWICE, which has a huge impact
// on latency. At the time of writing, it seems that most users of libclang
// in the open-source world don't realize this (I checked). Some don't even
// call reparse*, but parse* which is even less efficient.
CodeCompleteResultsWrap results(
clang_codeCompleteAt( clang_translation_unit_,
filename_.c_str(),
line,
column,
const_cast( unsaved ),
cxunsaved_files.size(),
CompletionOptions() ),
clang_disposeCodeCompleteResults );
std::vector< CompletionData > candidates = ToCompletionDataVector(
results.get() );
return candidates;
}
Location TranslationUnit::GetDeclarationLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse ) {
if ( reparse )
Reparse( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return Location();
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return Location();
CXCursor referenced_cursor = clang_getCursorReferenced( cursor );
if ( !CursorIsValid( referenced_cursor ) )
return Location();
CXCursor canonical_cursor = clang_getCanonicalCursor( referenced_cursor );
if ( !CursorIsValid( canonical_cursor ) )
return Location( clang_getCursorLocation( referenced_cursor ) );
return Location( clang_getCursorLocation( canonical_cursor ) );
}
Location TranslationUnit::GetDefinitionLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse ) {
if ( reparse )
Reparse( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return Location();
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return Location();
CXCursor definition_cursor = clang_getCursorDefinition( cursor );
if ( !CursorIsValid( definition_cursor ) )
return Location();
return Location( clang_getCursorLocation( definition_cursor ) );
}
std::string TranslationUnit::GetTypeAtLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse ) {
if ( reparse )
Reparse( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return "Internal error: no translation unit";
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return "Internal error: cursor not valid";
CXType type = clang_getCursorType( cursor );
std::string type_description =
CXStringToString( clang_getTypeSpelling( type ) );
if ( type_description.empty() )
return "Unknown type";
// We have a choice here; libClang provides clang_getCanonicalType which will
// return the "underlying" type for the type returned by clang_getCursorType
// e.g. for a typedef
// type = clang_getCanonicalType( type );
//
// Without the above, something like the following would return "MyType"
// rather than int:
// typedef int MyType;
// MyType i = 100; <-- type = MyType, canonical type = int
//
// There is probably more semantic value in calling it MyType. Indeed, if we
// opt for the more specific type, we can get very long or
// confusing STL types even for simple usage. e.g. the following:
// std::string test = "test"; <-- type = std::string;
// canonical type = std::basic_string
//
// So as a compromise, we return both if and only if the types differ, like
// std::string => std::basic_string
CXType canonical_type = clang_getCanonicalType( type );
if ( !clang_equalTypes( type, canonical_type ) ) {
type_description += " => ";
type_description += CXStringToString(
clang_getTypeSpelling( canonical_type ) );
}
return type_description;
}
std::string TranslationUnit::GetEnclosingFunctionAtLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse ) {
if ( reparse )
Reparse( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return "Internal error: no translation unit";
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return "Internal error: cursor not valid";
CXCursor parent = clang_getCursorSemanticParent( cursor );
std::string parent_str =
CXStringToString( clang_getCursorDisplayName( parent ) );
if ( parent_str.empty() )
return "Unknown semantic parent";
return parent_str;
}
// Argument taken as non-const ref because we need to be able to pass a
// non-const pointer to clang. This function (and clang too) will not modify the
// param though.
void TranslationUnit::Reparse(
std::vector< CXUnsavedFile > &unsaved_files ) {
unsigned options = ( clang_translation_unit_
? ReparseOptions( clang_translation_unit_ )
: static_cast( CXReparse_None ) );
Reparse( unsaved_files, options );
}
// Argument taken as non-const ref because we need to be able to pass a
// non-const pointer to clang. This function (and clang too) will not modify the
// param though.
void TranslationUnit::Reparse( std::vector< CXUnsavedFile > &unsaved_files,
uint parse_options ) {
int failure = 0;
{
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return;
CXUnsavedFile *unsaved = unsaved_files.size() > 0
? &unsaved_files[ 0 ] : NULL;
failure = clang_reparseTranslationUnit( clang_translation_unit_,
unsaved_files.size(),
unsaved,
parse_options );
}
if ( failure ) {
Destroy();
boost_throw( ClangParseError() );
}
UpdateLatestDiagnostics();
}
void TranslationUnit::UpdateLatestDiagnostics() {
unique_lock< mutex > lock1( clang_access_mutex_ );
unique_lock< mutex > lock2( diagnostics_mutex_ );
latest_diagnostics_.clear();
uint num_diagnostics = clang_getNumDiagnostics( clang_translation_unit_ );
latest_diagnostics_.reserve( num_diagnostics );
for ( uint i = 0; i < num_diagnostics; ++i ) {
Diagnostic diagnostic =
BuildDiagnostic(
DiagnosticWrap( clang_getDiagnostic( clang_translation_unit_, i ),
clang_disposeDiagnostic ),
clang_translation_unit_ );
if ( diagnostic.kind_ != INFORMATION )
latest_diagnostics_.push_back( diagnostic );
}
}
namespace {
/// Sort a FixIt container by its location's distance from a given column
/// (such as the cursor location).
///
/// PreCondition: All FixIts in the container are on the same line.
struct sort_by_location {
sort_by_location( int column ) : column_( column ) { }
bool operator()( const FixIt &a, const FixIt &b ) {
int a_distance = a.location.column_number_ - column_;
int b_distance = b.location.column_number_ - column_;
return std::abs( a_distance ) < std::abs( b_distance );
}
private:
int column_;
};
}
std::vector< FixIt > TranslationUnit::GetFixItsForLocationInFile(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse ) {
if ( reparse )
Reparse( unsaved_files );
std::vector< FixIt > fixits;
{
unique_lock< mutex > lock( diagnostics_mutex_ );
for ( std::vector< Diagnostic >::const_iterator it
= latest_diagnostics_.begin();
it != latest_diagnostics_.end();
++it ) {
// Find all fixits for the supplied line
if ( it->fixits_.size() > 0 &&
it->location_.line_number_ == static_cast( line ) ) {
FixIt fixit;
fixit.chunks = it->fixits_;
fixit.location = it->location_;
fixits.push_back( fixit );
}
}
}
// Sort them by the distance to the supplied column
std::sort( fixits.begin(),
fixits.end(),
sort_by_location( column ) );
return fixits;
}
DocumentationData TranslationUnit::GetDocsForLocationInFile(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse ) {
if ( reparse )
Reparse( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return DocumentationData();
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return DocumentationData();
// If the original cursor is a reference, then we return the documentation
// for the type/method/etc. that is referenced
CXCursor referenced_cursor = clang_getCursorReferenced( cursor );
if ( CursorIsValid( referenced_cursor ) )
cursor = referenced_cursor;
// We always want the documentation associated with the canonical declaration
CXCursor canonical_cursor = clang_getCanonicalCursor( cursor );
if ( !CursorIsValid( canonical_cursor ) )
return DocumentationData();
return DocumentationData( canonical_cursor );
}
CXCursor TranslationUnit::GetCursor( int line, int column ) {
// ASSUMES A LOCK IS ALREADY HELD ON clang_access_mutex_!
if ( !clang_translation_unit_ )
return clang_getNullCursor();
CXFile file = clang_getFile( clang_translation_unit_, filename_.c_str() );
CXSourceLocation source_location = clang_getLocation(
clang_translation_unit_,
file,
line,
column );
return clang_getCursor( clang_translation_unit_, source_location );
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ClangUtils.h 0000644 0001750 0001750 00000002470 12677434535 022745 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef CLANGUTILS_H_9MVHQLJS
#define CLANGUTILS_H_9MVHQLJS
#include
#include
namespace YouCompleteMe {
/**
* Return a std::string from the supplied CXString.
*
* Takes ownership of, and destroys, the supplied CXString which must not be used
* subsequently.
*/
std::string CXStringToString( CXString text );
bool CursorIsValid( CXCursor cursor );
bool CursorIsReference( CXCursor cursor );
bool CursorIsDeclaration( CXCursor cursor );
std::string CXFileToFilepath( CXFile file );
std::string ClangVersion();
} // namespace YouCompleteMe
#endif /* end of include guard: CLANGUTILS_H_9MVHQLJS */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/Documentation.cpp 0000644 0001750 0001750 00000003167 12677434535 024050 0 ustar onur onur // Copyright (C) 2015 YouCompleteMe Contributors
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "Documentation.h"
#include "ClangHelpers.h"
#include
namespace YouCompleteMe {
namespace {
bool CXCommentValid( const CXComment &comment ) {
return clang_Comment_getKind( comment ) != CXComment_Null;
}
}
DocumentationData::DocumentationData( const CXCursor &cursor )
: raw_comment( CXStringToString( clang_Cursor_getRawCommentText( cursor ) ) )
, brief_comment( CXStringToString(
clang_Cursor_getBriefCommentText( cursor ) ) )
, canonical_type( CXStringToString(
clang_getTypeSpelling( clang_getCursorType( cursor ) ) ) )
, display_name( CXStringToString( clang_getCursorSpelling( cursor ) ) ) {
CXComment parsed_comment = clang_Cursor_getParsedComment( cursor );
if ( CXCommentValid( parsed_comment ) ) {
comment_xml = CXStringToString(
clang_FullComment_getAsXML( parsed_comment ) );
}
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/CompletionData.h 0000644 0001750 0001750 00000010002 12677434535 023571 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef COMPLETIONDATA_H_2JCTF1NU
#define COMPLETIONDATA_H_2JCTF1NU
#include "standard.h"
#include
#include
namespace YouCompleteMe {
enum CompletionKind {
STRUCT = 0,
CLASS,
ENUM,
TYPE,
MEMBER,
FUNCTION,
VARIABLE,
MACRO,
PARAMETER,
NAMESPACE,
UNKNOWN
};
// This class holds pieces of information about a single completion coming from
// clang. These pieces are shown in Vim's UI in different ways.
//
// Normally, the completion menu looks like this (without square brackets):
//
// [main completion text] [kind] [extra menu info]
// [main completion text] [kind] [extra menu info]
// [main completion text] [kind] [extra menu info]
// ... (etc.) ...
//
// The user can also enable a "preview" window that will show extra information
// about a completion at the top of the buffer.
struct CompletionData {
CompletionData() {}
CompletionData( const CXCompletionResult &completion_result );
// What should actually be inserted into the buffer. For a function like
// "int foo(int x)", this is just "foo". Same for a data member like "foo_":
// we insert just "foo_".
std::string TextToInsertInBuffer() const {
return original_string_;
}
// Currently, here we show the full function signature (without the return
// type) if the current completion is a function or just the raw TypedText if
// the completion is, say, a data member. So for a function like "int foo(int
// x)", this would be "foo(int x)". For a data member like "count_", it would
// be just "count_".
std::string MainCompletionText() const {
return everything_except_return_type_;
}
// This is extra info shown in the pop-up completion menu, after the
// completion text and the kind. Currently we put the return type of the
// function here, if any.
std::string ExtraMenuInfo() const {
return return_type_;
}
// This is used to show extra information in vim's preview window. This is the
// window that vim usually shows at the top of the buffer. This should be used
// for extra information about the completion.
std::string DetailedInfoForPreviewWindow() const {
return detailed_info_;
}
std::string DocString() const {
return doc_string_;
}
bool operator== ( const CompletionData &other ) const {
return
kind_ == other.kind_ &&
everything_except_return_type_ == other.everything_except_return_type_ &&
return_type_ == other.return_type_ &&
original_string_ == other.original_string_;
// detailed_info_ doesn't matter
}
std::string detailed_info_;
std::string return_type_;
CompletionKind kind_;
// The original, raw completion string. For a function like "int foo(int x)",
// the original string is "foo". For a member data variable like "foo_", this
// is just "foo_". This corresponds to clang's TypedText chunk of the
// completion string.
std::string original_string_;
std::string everything_except_return_type_;
std::string doc_string_;
private:
void ExtractDataFromChunk( CXCompletionString completion_string,
uint chunk_num,
bool &saw_left_paren,
bool &saw_function_params,
bool &saw_placeholder );
};
} // namespace YouCompleteMe
#endif /* end of include guard: COMPLETIONDATA_H_2JCTF1NU */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/TranslationUnitStore.h 0000644 0001750 0001750 00000005373 12677434535 025060 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef TRANSLATIONUNITSTORE_H_NGN0MCKB
#define TRANSLATIONUNITSTORE_H_NGN0MCKB
#include "TranslationUnit.h"
#include "UnsavedFile.h"
#include
#include
#include
#include
#include
#include
typedef void *CXIndex;
namespace YouCompleteMe {
class TranslationUnitStore : boost::noncopyable {
public:
TranslationUnitStore( CXIndex clang_index );
~TranslationUnitStore();
// You can even call this function for the same filename from multiple
// threads; the TU store will ensure only one TU is created.
boost::shared_ptr< TranslationUnit > GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
boost::shared_ptr< TranslationUnit > GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool &translation_unit_created );
// Careful here! While GetOrCreate makes sure to take into account the flags
// for the file before returning a stored TU (if the flags changed, the TU is
// not really valid anymore and a new one should be built), this function does
// not. You might end up getting a stale TU.
boost::shared_ptr< TranslationUnit > Get( const std::string &filename );
bool Remove( const std::string &filename );
void RemoveAll();
private:
// WARNING: This accesses filename_to_translation_unit_ without a lock!
boost::shared_ptr< TranslationUnit > GetNoLock( const std::string &filename );
typedef boost::unordered_map < std::string,
boost::shared_ptr< TranslationUnit > > TranslationUnitForFilename;
typedef boost::unordered_map < std::string,
std::size_t > FlagsHashForFilename;
CXIndex clang_index_;
TranslationUnitForFilename filename_to_translation_unit_;
FlagsHashForFilename filename_to_flags_hash_;
boost::mutex filename_to_translation_unit_and_flags_mutex_;
};
} // namespace YouCompleteMe
#endif // TRANSLATIONUNITSTORE_H_NGN0MCKB
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/UnsavedFile.h 0000644 0001750 0001750 00000002670 12677434535 023107 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef UNSAVEDFILE_H_0GIYZQL4
#define UNSAVEDFILE_H_0GIYZQL4
#include
struct UnsavedFile {
UnsavedFile() : filename_( "" ), contents_( "" ), length_( 0 ) {}
std::string filename_;
std::string contents_;
unsigned long length_;
// We need this to be able to export this struct to Python via Boost.Python's
// methods. I have no clue why, but it won't compile without it.
// TODO: report this problem on the Boost bug tracker, the default equality
// operator should be more than adequate here
bool operator== ( const UnsavedFile &other ) const {
return
filename_ == other.filename_ &&
contents_ == other.contents_ &&
length_ == other.length_;
}
};
#endif /* end of include guard: UNSAVEDFILE_H_0GIYZQL4 */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ClangCompleter.h 0000644 0001750 0001750 00000006735 12677434535 023607 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef CLANGCOMPLETE_H_WLKDU0ZV
#define CLANGCOMPLETE_H_WLKDU0ZV
#include "../DLLDefines.h"
#include "UnsavedFile.h"
#include "Diagnostic.h"
#include "TranslationUnitStore.h"
#include "Documentation.h"
#include
#include
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
namespace YouCompleteMe {
class TranslationUnit;
struct CompletionData;
struct Location;
typedef std::vector< CompletionData > CompletionDatas;
// All filename parameters must be absolute paths.
class ClangCompleter : boost::noncopyable {
public:
YCM_DLL_EXPORT ClangCompleter();
YCM_DLL_EXPORT ~ClangCompleter();
bool UpdatingTranslationUnit( const std::string &filename );
std::vector< Diagnostic > UpdateTranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
YCM_DLL_EXPORT std::vector< CompletionData > CandidatesForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
Location GetDeclarationLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse = true );
YCM_DLL_EXPORT Location GetDefinitionLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse = true );
std::string GetTypeAtLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse = true );
std::string GetEnclosingFunctionAtLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse = true );
std::vector< FixIt > GetFixItsForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse = true );
DocumentationData GetDocsForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool reparse = true );
void DeleteCachesForFile( const std::string &filename );
private:
/////////////////////////////
// PRIVATE MEMBER VARIABLES
/////////////////////////////
CXIndex clang_index_;
TranslationUnitStore translation_unit_store_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: CLANGCOMPLETE_H_WLKDU0ZV */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/Range.h 0000644 0001750 0001750 00000002406 12677434535 021733 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef RANGE_H_4MFTIGQK
#define RANGE_H_4MFTIGQK
#include "standard.h"
#include "Location.h"
namespace YouCompleteMe {
// Half-open, [start, end>
struct Range {
Range() {}
Range( const Location &start_location, const Location &end_location )
: start_( start_location ), end_( end_location ) {}
Range( const CXSourceRange &range );
bool operator== ( const Range &other ) const {
return
start_ == other.start_ &&
end_ == other.end_;
}
Location start_;
Location end_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: RANGE_H_4MFTIGQK */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/CompletionData.cpp 0000644 0001750 0001750 00000016772 12677434535 024150 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "CompletionData.h"
#include "ClangUtils.h"
#include
#include
#include
namespace YouCompleteMe {
namespace {
CompletionKind CursorKindToCompletionKind( CXCursorKind kind ) {
switch ( kind ) {
case CXCursor_StructDecl:
return STRUCT;
case CXCursor_ClassDecl:
case CXCursor_ClassTemplate:
case CXCursor_ObjCInterfaceDecl:
case CXCursor_ObjCImplementationDecl:
return CLASS;
case CXCursor_EnumDecl:
return ENUM;
case CXCursor_UnexposedDecl:
case CXCursor_UnionDecl:
case CXCursor_TypedefDecl:
return TYPE;
case CXCursor_FieldDecl:
case CXCursor_ObjCIvarDecl:
case CXCursor_ObjCPropertyDecl:
case CXCursor_EnumConstantDecl:
return MEMBER;
case CXCursor_FunctionDecl:
case CXCursor_CXXMethod:
case CXCursor_FunctionTemplate:
case CXCursor_ConversionFunction:
case CXCursor_Constructor:
case CXCursor_Destructor:
case CXCursor_ObjCClassMethodDecl:
case CXCursor_ObjCInstanceMethodDecl:
return FUNCTION;
case CXCursor_VarDecl:
return VARIABLE;
case CXCursor_MacroDefinition:
return MACRO;
case CXCursor_ParmDecl:
return PARAMETER;
case CXCursor_Namespace:
case CXCursor_NamespaceAlias:
return NAMESPACE;
default:
return UNKNOWN;
}
}
bool IsMainCompletionTextInfo( CXCompletionChunkKind kind ) {
return
kind == CXCompletionChunk_Optional ||
kind == CXCompletionChunk_TypedText ||
kind == CXCompletionChunk_Placeholder ||
kind == CXCompletionChunk_LeftParen ||
kind == CXCompletionChunk_RightParen ||
kind == CXCompletionChunk_RightBracket ||
kind == CXCompletionChunk_LeftBracket ||
kind == CXCompletionChunk_LeftBrace ||
kind == CXCompletionChunk_RightBrace ||
kind == CXCompletionChunk_RightAngle ||
kind == CXCompletionChunk_LeftAngle ||
kind == CXCompletionChunk_Comma ||
kind == CXCompletionChunk_Colon ||
kind == CXCompletionChunk_SemiColon ||
kind == CXCompletionChunk_Equal ||
kind == CXCompletionChunk_Informative ||
kind == CXCompletionChunk_HorizontalSpace ||
kind == CXCompletionChunk_Text;
}
std::string ChunkToString( CXCompletionString completion_string,
uint chunk_num ) {
if ( !completion_string )
return std::string();
return YouCompleteMe::CXStringToString(
clang_getCompletionChunkText( completion_string, chunk_num ) );
}
std::string OptionalChunkToString( CXCompletionString completion_string,
uint chunk_num ) {
std::string final_string;
if ( !completion_string )
return final_string;
CXCompletionString optional_completion_string =
clang_getCompletionChunkCompletionString( completion_string, chunk_num );
if ( !optional_completion_string )
return final_string;
uint optional_num_chunks = clang_getNumCompletionChunks(
optional_completion_string );
for ( uint j = 0; j < optional_num_chunks; ++j ) {
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
optional_completion_string, j );
if ( kind == CXCompletionChunk_Optional ) {
final_string.append( OptionalChunkToString( optional_completion_string,
j ) );
}
else {
final_string.append( ChunkToString( optional_completion_string, j ) );
}
}
return final_string;
}
// foo( -> foo
// foo() -> foo
std::string RemoveTrailingParens( std::string text ) {
if ( boost::ends_with( text, "(" ) ) {
boost::erase_tail( text, 1 );
} else if ( boost::ends_with( text, "()" ) ) {
boost::erase_tail( text, 2 );
}
return text;
}
} // unnamed namespace
CompletionData::CompletionData( const CXCompletionResult &completion_result ) {
CXCompletionString completion_string = completion_result.CompletionString;
if ( !completion_string )
return;
uint num_chunks = clang_getNumCompletionChunks( completion_string );
bool saw_left_paren = false;
bool saw_function_params = false;
bool saw_placeholder = false;
for ( uint j = 0; j < num_chunks; ++j ) {
ExtractDataFromChunk( completion_string,
j,
saw_left_paren,
saw_function_params,
saw_placeholder );
}
original_string_ = RemoveTrailingParens( boost::move( original_string_ ) );
kind_ = CursorKindToCompletionKind( completion_result.CursorKind );
detailed_info_.append( return_type_ )
.append( " " )
.append( everything_except_return_type_ )
.append( "\n" );
doc_string_ = YouCompleteMe::CXStringToString(
clang_getCompletionBriefComment( completion_string ) );
}
void CompletionData::ExtractDataFromChunk( CXCompletionString completion_string,
uint chunk_num,
bool &saw_left_paren,
bool &saw_function_params,
bool &saw_placeholder ) {
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
completion_string, chunk_num );
if ( IsMainCompletionTextInfo( kind ) ) {
if ( kind == CXCompletionChunk_LeftParen ) {
saw_left_paren = true;
}
else if ( saw_left_paren &&
!saw_function_params &&
kind != CXCompletionChunk_RightParen &&
kind != CXCompletionChunk_Informative ) {
saw_function_params = true;
everything_except_return_type_.append( " " );
}
else if ( saw_function_params && kind == CXCompletionChunk_RightParen ) {
everything_except_return_type_.append( " " );
}
if ( kind == CXCompletionChunk_Optional ) {
everything_except_return_type_.append(
OptionalChunkToString( completion_string, chunk_num ) );
}
else {
everything_except_return_type_.append(
ChunkToString( completion_string, chunk_num ) );
}
}
switch ( kind ) {
case CXCompletionChunk_ResultType:
return_type_ = ChunkToString( completion_string, chunk_num );
break;
case CXCompletionChunk_Placeholder:
saw_placeholder = true;
break;
case CXCompletionChunk_TypedText:
case CXCompletionChunk_Text:
// need to add paren to insert string
// when implementing inherited methods or declared methods in objc.
case CXCompletionChunk_LeftParen:
case CXCompletionChunk_RightParen:
case CXCompletionChunk_HorizontalSpace:
if ( !saw_placeholder ) {
original_string_ += ChunkToString( completion_string, chunk_num );
}
break;
default:
break;
}
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/TranslationUnit.h 0000644 0001750 0001750 00000006722 12677434535 024042 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef TRANSLATIONUNIT_H_XQ7I6SVA
#define TRANSLATIONUNIT_H_XQ7I6SVA
#include "../DLLDefines.h"
#include "UnsavedFile.h"
#include "Diagnostic.h"
#include "Location.h"
#include "Documentation.h"
#include
#include
#include
#include
#include
namespace YouCompleteMe {
struct CompletionData;
typedef boost::shared_ptr< std::vector< CompletionData > > AsyncCompletions;
class TranslationUnit : boost::noncopyable {
public:
// This constructor creates an invalid, sentinel TU. All of it's methods
// return empty vectors, and IsCurrentlyUpdating always returns true so that
// no callers try to rely on the invalid TU.
TranslationUnit();
YCM_DLL_EXPORT TranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
CXIndex clang_index );
YCM_DLL_EXPORT ~TranslationUnit();
void Destroy();
bool IsCurrentlyUpdating() const;
std::vector< Diagnostic > Reparse(
const std::vector< UnsavedFile > &unsaved_files );
std::vector< CompletionData > CandidatesForLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files );
YCM_DLL_EXPORT Location GetDeclarationLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse = true );
YCM_DLL_EXPORT Location GetDefinitionLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse = true );
std::string GetTypeAtLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse = true );
std::string GetEnclosingFunctionAtLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse = true );
std::vector< FixIt > GetFixItsForLocationInFile(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse = true );
DocumentationData GetDocsForLocationInFile(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
bool reparse = true );
private:
void Reparse( std::vector< CXUnsavedFile > &unsaved_files );
void Reparse( std::vector< CXUnsavedFile > &unsaved_files,
uint parse_options );
void UpdateLatestDiagnostics();
CXCursor GetCursor( int line, int column );
/////////////////////////////
// PRIVATE MEMBER VARIABLES
/////////////////////////////
std::string filename_;
boost::mutex diagnostics_mutex_;
std::vector< Diagnostic > latest_diagnostics_;
mutable boost::mutex clang_access_mutex_;
CXTranslationUnit clang_translation_unit_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: TRANSLATIONUNIT_H_XQ7I6SVA */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/Range.cpp 0000644 0001750 0001750 00000001660 12677434535 022267 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "Range.h"
#include "ClangUtils.h"
namespace YouCompleteMe {
Range::Range( const CXSourceRange &range ) {
start_ = Location( clang_getRangeStart( range ) );
end_ = Location( clang_getRangeEnd( range ) );
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/ClangCompleter/ClangHelpers.cpp 0000644 0001750 0001750 00000017533 12677434535 023610 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "standard.h"
#include "ClangHelpers.h"
#include "ClangUtils.h"
#include "Utils.h"
#include "UnsavedFile.h"
#include "Location.h"
#include "Range.h"
#include
using boost::unordered_map;
namespace YouCompleteMe {
namespace {
// NOTE: The passed in pointer should never be NULL!
std::string FullDiagnosticText( CXDiagnostic cxdiagnostic ) {
std::string full_text = CXStringToString(
clang_formatDiagnostic(
cxdiagnostic,
clang_defaultDiagnosticDisplayOptions() ) );
// Note: clang docs say that a CXDiagnosticSet retrieved with
// clang_getChildDiagnostics do NOT need to be released with
// clang_diposeDiagnosticSet
CXDiagnosticSet diag_set = clang_getChildDiagnostics( cxdiagnostic );
if ( !diag_set )
return full_text;
uint num_child_diagnostics = clang_getNumDiagnosticsInSet( diag_set );
if ( !num_child_diagnostics )
return full_text;
for ( uint i = 0; i < num_child_diagnostics; ++i ) {
CXDiagnostic diagnostic = clang_getDiagnosticInSet( diag_set, i );
if ( !diagnostic )
continue;
full_text.append( "\n" );
full_text.append( FullDiagnosticText( diagnostic ) );
}
return full_text;
}
DiagnosticKind DiagnosticSeverityToType( CXDiagnosticSeverity severity ) {
switch ( severity ) {
case CXDiagnostic_Ignored:
case CXDiagnostic_Note:
return INFORMATION;
case CXDiagnostic_Warning:
return WARNING;
case CXDiagnostic_Error:
case CXDiagnostic_Fatal:
default:
return ERROR;
}
}
// Returns true when the provided completion string is available to the user;
// unavailable completion strings refer to entities that are private/protected,
// deprecated etc.
bool CompletionStringAvailable( CXCompletionString completion_string ) {
if ( !completion_string )
return false;
return clang_getCompletionAvailability( completion_string ) ==
CXAvailability_Available;
}
std::vector< Range > GetRanges( const DiagnosticWrap &diagnostic_wrap ) {
std::vector< Range > ranges;
uint num_ranges = clang_getDiagnosticNumRanges( diagnostic_wrap.get() );
ranges.reserve( num_ranges );
for ( uint i = 0; i < num_ranges; ++i ) {
ranges.push_back(
Range( clang_getDiagnosticRange( diagnostic_wrap.get(), i ) ) );
}
return ranges;
}
Range GetLocationExtent( CXSourceLocation source_location,
CXTranslationUnit translation_unit ) {
// If you think the below code is an idiotic way of getting the source range
// for an identifier at a specific source location, you are not the only one.
// I cannot believe that this is the only way to achieve this with the
// libclang API in a robust way.
// I've tried many simpler ways of doing this and they all fail in various
// situations.
CXSourceRange range = clang_getCursorExtent(
clang_getCursor( translation_unit, source_location ) );
CXToken *tokens;
uint num_tokens;
clang_tokenize( translation_unit, range, &tokens, &num_tokens );
Location location( source_location );
Range final_range;
for ( uint i = 0; i < num_tokens; ++i ) {
Location token_location( clang_getTokenLocation( translation_unit,
tokens[ i ] ) );
if ( token_location == location ) {
std::string name = CXStringToString(
clang_getTokenSpelling( translation_unit, tokens[ i ] ) );
Location end_location = location;
end_location.column_number_ += name.length();
final_range = Range( location, end_location );
break;
}
}
clang_disposeTokens( translation_unit, tokens, num_tokens );
return final_range;
}
} // unnamed namespace
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
const std::vector< UnsavedFile > &unsaved_files ) {
std::vector< CXUnsavedFile > clang_unsaved_files( unsaved_files.size() );
for ( uint i = 0; i < unsaved_files.size(); ++i ) {
clang_unsaved_files[ i ].Filename = unsaved_files[ i ].filename_.c_str();
clang_unsaved_files[ i ].Contents = unsaved_files[ i ].contents_.c_str();
clang_unsaved_files[ i ].Length = unsaved_files[ i ].length_;
}
return clang_unsaved_files;
}
std::vector< CompletionData > ToCompletionDataVector(
CXCodeCompleteResults *results ) {
std::vector< CompletionData > completions;
if ( !results || !results->Results )
return completions;
completions.reserve( results->NumResults );
unordered_map< std::string, uint > seen_data;
for ( uint i = 0; i < results->NumResults; ++i ) {
CXCompletionResult completion_result = results->Results[ i ];
if ( !CompletionStringAvailable( completion_result.CompletionString ) )
continue;
CompletionData data( completion_result );
uint index = GetValueElseInsert( seen_data,
data.original_string_,
completions.size() );
if ( index == completions.size() ) {
completions.push_back( boost::move( data ) );
}
else {
// If we have already seen this completion, then this is an overload of a
// function we have seen. We add the signature of the overload to the
// detailed information.
completions[ index ].detailed_info_
.append( data.return_type_ )
.append( " " )
.append( data.everything_except_return_type_ )
.append( "\n" );
}
}
return completions;
}
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
CXTranslationUnit translation_unit ) {
Diagnostic diagnostic;
if ( !diagnostic_wrap )
return diagnostic;
diagnostic.kind_ = DiagnosticSeverityToType(
clang_getDiagnosticSeverity( diagnostic_wrap.get() ) );
// If this is an "ignored" diagnostic, there's no point in continuing since we
// won't display those to the user
if ( diagnostic.kind_ == INFORMATION )
return diagnostic;
CXSourceLocation source_location =
clang_getDiagnosticLocation( diagnostic_wrap.get() );
diagnostic.location_ = Location( source_location );
diagnostic.location_extent_ = GetLocationExtent( source_location,
translation_unit );
diagnostic.ranges_ = GetRanges( diagnostic_wrap );
diagnostic.text_ = CXStringToString(
clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
diagnostic.long_formatted_text_ = FullDiagnosticText( diagnostic_wrap.get() );
uint num_fixits = clang_getDiagnosticNumFixIts( diagnostic_wrap.get() );
// If there are any fixits supplied by libclang, cache them in the diagnostic
// object.
diagnostic.fixits_.reserve( num_fixits );
for ( uint fixit_idx = 0; fixit_idx < num_fixits; ++fixit_idx ) {
FixItChunk chunk;
CXSourceRange sourceRange;
chunk.replacement_text = CXStringToString(
clang_getDiagnosticFixIt( diagnostic_wrap.get(),
fixit_idx,
&sourceRange ) );
chunk.range = sourceRange;
diagnostic.fixits_.push_back( chunk );
}
return diagnostic;
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/Candidate.h 0000644 0001750 0001750 00000003701 12677434535 017653 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef CANDIDATE_H_R5LZH6AC
#define CANDIDATE_H_R5LZH6AC
#include "DLLDefines.h"
#include "LetterNode.h"
#include
#include
#include
#include
namespace YouCompleteMe {
class Result;
typedef std::bitset< NUM_LETTERS > Bitset;
YCM_DLL_EXPORT Bitset LetterBitsetFromString( const std::string &text );
// Public for tests
YCM_DLL_EXPORT std::string GetWordBoundaryChars( const std::string &text );
class Candidate : boost::noncopyable {
public:
YCM_DLL_EXPORT explicit Candidate( const std::string &text );
inline const std::string &Text() const {
return text_;
}
// Returns true if the candidate contains the bits from the query (it may also
// contain other bits)
inline bool MatchesQueryBitset( const Bitset &query_bitset ) const {
return ( letters_present_ & query_bitset ) == query_bitset;
}
YCM_DLL_EXPORT Result QueryMatchResult( const std::string &query,
bool case_sensitive ) const;
private:
std::string text_;
std::string word_boundary_chars_;
bool text_is_lowercase_;
Bitset letters_present_;
boost::scoped_ptr< LetterNode > root_node_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: CANDIDATE_H_R5LZH6AC */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/LetterNodeListMap.h 0000644 0001750 0001750 00000002766 12677434535 021350 0 ustar onur onur // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef LETTERNODELISTMAP_H_BRK2UMC1
#define LETTERNODELISTMAP_H_BRK2UMC1
#include "DLLDefines.h"
#include
#include
#include
#define NUM_LETTERS 128
namespace YouCompleteMe {
class LetterNode;
YCM_DLL_EXPORT int IndexForChar( char letter );
YCM_DLL_EXPORT bool IsUppercase( char letter );
class LetterNodeListMap : boost::noncopyable {
public:
LetterNodeListMap();
YCM_DLL_EXPORT ~LetterNodeListMap();
bool HasLetter( char letter );
std::list< LetterNode * > &operator[] ( char letter );
std::list< LetterNode * > *ListPointerAt( char letter );
bool HasLetter( char letter ) const;
private:
boost::array< std::list< LetterNode * >*, NUM_LETTERS > letters_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: LETTERNODELISTMAP_H_BRK2UMC1 */
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/IdentifierDatabase.cpp 0000644 0001750 0001750 00000012011 12677434535 022033 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#include "IdentifierDatabase.h"
#include "standard.h"
#include "Candidate.h"
#include "CandidateRepository.h"
#include "IdentifierUtils.h"
#include "Result.h"
#include "Utils.h"
#include
#include
#include
#include
using boost::algorithm::any_of;
using boost::algorithm::is_upper;
namespace YouCompleteMe {
IdentifierDatabase::IdentifierDatabase()
: candidate_repository_( CandidateRepository::Instance() ) {
}
void IdentifierDatabase::AddIdentifiers(
const FiletypeIdentifierMap &filetype_identifier_map ) {
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
foreach ( const FiletypeIdentifierMap::value_type & filetype_and_map,
filetype_identifier_map ) {
foreach( const FilepathToIdentifiers::value_type & filepath_and_identifiers,
filetype_and_map.second ) {
AddIdentifiersNoLock( filepath_and_identifiers.second,
filetype_and_map.first,
filepath_and_identifiers.first );
}
}
}
void IdentifierDatabase::AddIdentifiers(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath ) {
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
AddIdentifiersNoLock( new_candidates, filetype, filepath );
}
void IdentifierDatabase::ClearCandidatesStoredForFile(
const std::string &filetype,
const std::string &filepath ) {
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
GetCandidateSet( filetype, filepath ).clear();
}
void IdentifierDatabase::ResultsForQueryAndType(
const std::string &query,
const std::string &filetype,
std::vector< Result > &results ) const {
FiletypeCandidateMap::const_iterator it;
{
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
it = filetype_candidate_map_.find( filetype );
if ( it == filetype_candidate_map_.end() || query.empty() )
return;
}
Bitset query_bitset = LetterBitsetFromString( query );
bool query_has_uppercase_letters = any_of( query, is_upper() );
boost::unordered_set< const Candidate * > seen_candidates;
seen_candidates.reserve( candidate_repository_.NumStoredCandidates() );
{
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
foreach ( const FilepathToCandidates::value_type & path_and_candidates,
*it->second ) {
foreach ( const Candidate * candidate, *path_and_candidates.second ) {
if ( ContainsKey( seen_candidates, candidate ) )
continue;
else
seen_candidates.insert( candidate );
if ( !candidate->MatchesQueryBitset( query_bitset ) )
continue;
Result result = candidate->QueryMatchResult(
query, query_has_uppercase_letters );
if ( result.IsSubsequence() )
results.push_back( result );
}
}
}
std::sort( results.begin(), results.end() );
}
// WARNING: You need to hold the filetype_candidate_map_mutex_ before calling
// this function and while using the returned set.
std::set< const Candidate * > &IdentifierDatabase::GetCandidateSet(
const std::string &filetype,
const std::string &filepath ) {
boost::shared_ptr< FilepathToCandidates > &path_to_candidates =
filetype_candidate_map_[ filetype ];
if ( !path_to_candidates )
path_to_candidates.reset( new FilepathToCandidates() );
boost::shared_ptr< std::set< const Candidate * > > &candidates =
( *path_to_candidates )[ filepath ];
if ( !candidates )
candidates.reset( new std::set< const Candidate * >() );
return *candidates;
}
// WARNING: You need to hold the filetype_candidate_map_mutex_ before calling
// this function and while using the returned set.
void IdentifierDatabase::AddIdentifiersNoLock(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath ) {
std::set< const Candidate *> &candidates =
GetCandidateSet( filetype, filepath );
std::vector< const Candidate * > repository_candidates =
candidate_repository_.GetCandidatesForStrings( new_candidates );
candidates.insert( repository_candidates.begin(),
repository_candidates.end() );
}
} // namespace YouCompleteMe
ycmd-0+20160327+gitc3e6904.orig/cpp/ycm/IdentifierDatabase.h 0000644 0001750 0001750 00000006315 12677434535 021512 0 ustar onur onur // Copyright (C) 2013 Google Inc.
//
// This file is part of ycmd.
//
// ycmd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ycmd is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ycmd. If not, see .
#ifndef IDENTIFIERDATABASE_H_ZESX3CVR
#define IDENTIFIERDATABASE_H_ZESX3CVR
#include
#include
#include
#include
#include
#include
#include