diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +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 this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/cmake/FindASTRedux.cmake b/cmake/FindASTRedux.cmake index ffd4873..2335724 100644 --- a/cmake/FindASTRedux.cmake +++ b/cmake/FindASTRedux.cmake @@ -1,10 +1,37 @@ +#============================================================================= +# 2017 Emma Gospodinova +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + include(FindPackageHandleStandardArgs) find_library(ASTRedux_LIBRARY NAMES ast_redux) find_package_handle_standard_args(ASTRedux DEFAULT_MSG ASTRedux_LIBRARY) # Set package properties if FeatureSummary was included if (COMMAND set_package_properties) set_package_properties(ASTRedux PROPERTIES DESCRIPTION "ast-redux - a Rust library") endif() diff --git a/cmake/FindRust.cmake b/cmake/FindRust.cmake index 374422d..c2d58c1 100644 --- a/cmake/FindRust.cmake +++ b/cmake/FindRust.cmake @@ -1,36 +1,63 @@ +#============================================================================= +# 2017 Emma Gospodinova +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + include(FindPackageHandleStandardArgs) find_program(RUSTC_EXECUTABLE rustc) find_package_handle_standard_args(Rust DEFAULT_MSG RUSTC_EXECUTABLE) mark_as_advanced(RUSTC_EXECUTABLE) execute_process(COMMAND ${RUSTC_EXECUTABLE} -Vv OUTPUT_VARIABLE RUSTC_VERSION_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE) string(REGEX MATCH "host:[ \t]([A-Za-z0-9_-]*)\n" RUSTC_TARGET_TRIPLE "${RUSTC_VERSION_OUTPUT}") string(REGEX REPLACE "host:[ \t]([A-Za-z0-9_-]*)\n" "\\1" RUSTC_TARGET_TRIPLE "${RUSTC_TARGET_TRIPLE}") string(REGEX MATCH "release:[ \t]([A-Za-z0-9\\._-]*)\n" RUSTC_RELEASE "${RUSTC_VERSION_OUTPUT}") string(REGEX REPLACE "release:[ \t]([A-Za-z0-9\\._-]*)\n" "\\1" RUSTC_RELEASE "${RUSTC_RELEASE}") mark_as_advanced(RUSTC_TARGET_TRIPLE) mark_as_advanced(RUSTC_RELEASE) if(NOT ${RUSTC_RELEASE} MATCHES "nightly") message(FATAL_ERROR "A nightly Rust compiler is required to build kdev-rust. Please read: https://doc.rust-lang.org/1.5.0/book/nightly-rust.html Or just run: curl -s https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly") endif() execute_process(COMMAND ${RUSTC_EXECUTABLE} --print sysroot OUTPUT_VARIABLE RUST_SYSROOT OUTPUT_STRIP_TRAILING_WHITESPACE) set(RUST_LIBRARY_DIR "${RUST_SYSROOT}/lib/rustlib/${RUSTC_TARGET_TRIPLE}/lib") unset(RUSTC_VERSION_OUTPUT) diff --git a/codecompletion/completioncontext.cpp b/codecompletion/completioncontext.cpp index e84e62a..594906b 100644 --- a/codecompletion/completioncontext.cpp +++ b/codecompletion/completioncontext.cpp @@ -1,45 +1,62 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "completioncontext.h" #include #include #include #include #include "rustdebug.h" namespace Rust { using namespace KDevelop; CompletionContext::CompletionContext(DUContextPointer context, const QString &contextText, const QString &followingText, const CursorInRevision &position, int depth) : KDevelop::CodeCompletionContext(context, contextText, position, depth), m_followingText(followingText) { } QList CompletionContext::completionItems(bool &abort, bool fullCompletion) { QList items; DUChainReadLocker lock; auto declarations = m_duContext->allDeclarations(CursorInRevision::invalid(), m_duContext->topContext()); for(const QPair &decl : declarations) { if(decl.first->topContext() != m_duContext->topContext()) continue; if(decl.first->identifier() == globalImportIdentifier() || decl.first->identifier() == globalAliasIdentifier() || decl.first->identifier() == Identifier()) continue; items << CompletionTreeItemPointer(new NormalDeclarationCompletionItem(DeclarationPointer(decl.first))); } return items; } } diff --git a/codecompletion/completioncontext.h b/codecompletion/completioncontext.h index b6769a1..2ffddc2 100644 --- a/codecompletion/completioncontext.h +++ b/codecompletion/completioncontext.h @@ -1,30 +1,47 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef COMPLETIONCONTEXT_H #define COMPLETIONCONTEXT_H #include #include #include namespace Rust { class KDEVRUSTCOMPLETION_EXPORT CompletionContext : public KDevelop::CodeCompletionContext { public: CompletionContext(KDevelop::DUContextPointer context, const QString &contextText, const QString &followingText, const KDevelop::CursorInRevision &position, int depth); QList completionItems(bool &abort, bool fullCompletion) override; private: QString m_followingText; }; } #endif // COMPLETIONCONTEXT_H diff --git a/codecompletion/completionmodel.cpp b/codecompletion/completionmodel.cpp index e15e0a5..dc3482a 100644 --- a/codecompletion/completionmodel.cpp +++ b/codecompletion/completionmodel.cpp @@ -1,18 +1,35 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "completionmodel.h" #include "completionworker.h" namespace Rust { CompletionModel::CompletionModel(QObject *parent) : KDevelop::CodeCompletionModel(parent) { } KDevelop::CodeCompletionWorker *CompletionModel::createCompletionWorker() { return new CompletionWorker(this); } } diff --git a/codecompletion/completionmodel.h b/codecompletion/completionmodel.h index e39a402..60277c2 100644 --- a/codecompletion/completionmodel.h +++ b/codecompletion/completionmodel.h @@ -1,23 +1,40 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef COMPLETIONMODEL_H #define COMPLETIONMODEL_H #include #include "kdevrustcompletion_export.h" namespace Rust { class KDEVRUSTCOMPLETION_EXPORT CompletionModel : public KDevelop::CodeCompletionModel { Q_OBJECT public: CompletionModel(QObject *parent); protected: KDevelop::CodeCompletionWorker *createCompletionWorker() override; }; } #endif // COMPLETIONMODEL_H diff --git a/codecompletion/completionworker.cpp b/codecompletion/completionworker.cpp index 47a04a6..d8ee52b 100644 --- a/codecompletion/completionworker.cpp +++ b/codecompletion/completionworker.cpp @@ -1,25 +1,42 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "completionworker.h" #include "completionmodel.h" #include "completioncontext.h" namespace Rust { CompletionWorker::CompletionWorker(CompletionModel *parent) : KDevelop::CodeCompletionWorker(parent) { } KDevelop::CodeCompletionContext *CompletionWorker::createCompletionContext(KDevelop::DUContextPointer context, const QString &contextText, const QString &followingText, const KDevelop::CursorInRevision &position) const { if (!context) { return nullptr; } return new CompletionContext(context, contextText, followingText, position, 0); } } diff --git a/codecompletion/completionworker.h b/codecompletion/completionworker.h index f83cfc7..a0306c7 100644 --- a/codecompletion/completionworker.h +++ b/codecompletion/completionworker.h @@ -1,26 +1,43 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef COMPLETIONWORKER_H #define COMPLETIONWORKER_H #include namespace Rust { class CompletionModel; class CompletionWorker : public KDevelop::CodeCompletionWorker { Q_OBJECT public: CompletionWorker(CompletionModel *parent); protected: KDevelop::CodeCompletionContext *createCompletionContext(KDevelop::DUContextPointer context, const QString &contextText, const QString &followingText, const KDevelop::CursorInRevision &position) const override; }; } #endif // COMPLETIONWORKER_H diff --git a/duchain/astredux.h b/duchain/astredux.h index 43e84f8..de58ef6 100644 --- a/duchain/astredux.h +++ b/duchain/astredux.h @@ -1,92 +1,109 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef ASTREDUX_H #define ASTREDUX_H extern "C" { enum RSNodeKind { Crate, Module, StructDecl, EnumDecl, TraitDecl, ImplDecl, TypeAliasDecl, FieldDecl, EnumVariantDecl, FunctionDecl, ParmDecl, VarDecl, Path, PathSegment, Block, Arm, Unexposed }; enum RSDiagnosticLevel { Info, Note, Warning, Error, Fatal }; enum RSVisitResult { Break, Continue, Recurse }; struct RSLocation { int line; int column; }; struct RSRange { RSLocation start; RSLocation end; }; struct RSCrate; struct RSNode; struct RSDiagnostic; struct RSDiagnosticIterator; typedef RSVisitResult (*CallbackFn)(RSNode *node, RSNode *parent, void *data); RSCrate *parse_crate(const char *name, const char *source); void destroy_crate(RSCrate *crate); RSNode *node_from_crate(RSCrate *crate); void destroy_node(RSNode *node); unsigned int node_get_id(RSNode *node); RSCrate *node_get_crate(RSNode *node); RSNodeKind node_get_kind(RSNode *node); const char *node_get_spelling_name(RSNode *node); RSRange node_get_spelling_range(RSNode *node); RSRange node_get_extent(RSNode *node); void destroy_string(const char *str); RSDiagnosticIterator *crate_get_diagnostics(RSCrate *crate); void destroy_diagnostic_iterator(RSDiagnosticIterator *iterator); RSDiagnostic *diagnostics_next(RSDiagnosticIterator *iterator); void destroy_diagnostic(RSDiagnostic *diagnostic); RSDiagnosticLevel diagnostic_get_level(RSDiagnostic *diagnostic); const char *diagnostic_get_message(RSDiagnostic *diagnostic); RSRange diagnostic_get_primary_range(RSDiagnostic *diagnostic); void visit_children(RSNode *node, CallbackFn callback, void *data); } #endif // ASTREDUX_H diff --git a/duchain/contextbuilder.cpp b/duchain/contextbuilder.cpp index 6aa5577..740fb41 100644 --- a/duchain/contextbuilder.cpp +++ b/duchain/contextbuilder.cpp @@ -1,139 +1,156 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "contextbuilder.h" #include #include #include #include "rustducontext.h" #include "nodetraits.h" namespace Rust { RSVisitResult visitCallback(RSNode *node, RSNode *parent, void *data); void ContextBuilder::setParseSession(ParseSession *session) { this->session = session; } RangeInRevision ContextBuilder::editorFindSpellingRange(RustNode *node, const QString &identifier) { RSRange range = node_get_spelling_range(node->data()); KTextEditor::Range incorrectRange = KTextEditor::Range(range.start.line - 1, range.start.column, INT_MAX, INT_MAX); IDocument *document = ICore::self()->documentController() ->documentForUrl(topContext()->url().toUrl()); QVector ranges; if (document) { ranges = document->textDocument()->searchText(incorrectRange, identifier); } else { ranges = { KTextEditor::Range::invalid() }; } return RangeInRevision::castFromSimpleRange(ranges.first()); } RSVisitResult ContextBuilder::visitNode(RustNode *node, RustNode *parent) { RSNodeKind kind = node_get_kind(node->data()); #define BUILD_CONTEXT_FOR(K) case K: return buildContext(node, parent); switch (kind) { BUILD_CONTEXT_FOR(Crate); BUILD_CONTEXT_FOR(Module); BUILD_CONTEXT_FOR(StructDecl); BUILD_CONTEXT_FOR(EnumDecl); BUILD_CONTEXT_FOR(TraitDecl); BUILD_CONTEXT_FOR(ImplDecl); BUILD_CONTEXT_FOR(TypeAliasDecl); BUILD_CONTEXT_FOR(FieldDecl); BUILD_CONTEXT_FOR(EnumVariantDecl); BUILD_CONTEXT_FOR(FunctionDecl); BUILD_CONTEXT_FOR(ParmDecl); BUILD_CONTEXT_FOR(VarDecl); BUILD_CONTEXT_FOR(Path); BUILD_CONTEXT_FOR(PathSegment); BUILD_CONTEXT_FOR(Block); BUILD_CONTEXT_FOR(Arm); BUILD_CONTEXT_FOR(Unexposed); } #undef BUILD_CONTEXT_FOR return Recurse; } template RSVisitResult ContextBuilder::buildContext(RustNode *node, RustNode *parent) { Q_UNUSED(parent); constexpr bool hasContext = NodeTraits::hasContext(Kind); RustPath name(node); if (hasContext) { openContext(node, NodeTraits::contextType(Kind), &name); visitChildren(node); closeContext(); return Continue; } return Recurse; } void ContextBuilder::visitChildren(RustNode *node) { visit_children(node->data(), visitCallback, this); } void ContextBuilder::startVisiting(RustNode *node) { visitChildren(node); } void ContextBuilder::setContextOnNode(RustNode *node, KDevelop::DUContext *context) { session->setContextOnNode(node, context); } KDevelop::DUContext *ContextBuilder::contextFromNode(RustNode *node) { return session->contextFromNode(node); } KDevelop::RangeInRevision ContextBuilder::editorFindRange(RustNode *fromNode, RustNode *toNode) { RSRange fromRange = node_get_extent(fromNode->data()); RSRange toRange = node_get_extent(toNode->data()); return RangeInRevision(fromRange.start.line - 1, fromRange.start.column, toRange.end.line - 1, toRange.end.column); } KDevelop::QualifiedIdentifier ContextBuilder::identifierForNode(RustPath *node) { return QualifiedIdentifier(node->value); } KDevelop::DUContext *ContextBuilder::newContext(const KDevelop::RangeInRevision &range) { return new RustNormalDUContext(range, currentContext()); } KDevelop::TopDUContext *ContextBuilder::newTopContext(const KDevelop::RangeInRevision &range, KDevelop::ParsingEnvironmentFile *file) { if (!file) { file = new ParsingEnvironmentFile(document()); file->setLanguage(IndexedString("Rust")); } return new RustTopDUContext(document(), range, file); } RSVisitResult visitCallback(RSNode *node, RSNode *parent, void *data) { ContextBuilder *builder = static_cast(data); RustNode currentNode(node); RustNode parentNode(parent); return builder->visitNode(¤tNode, &parentNode); } } diff --git a/duchain/contextbuilder.h b/duchain/contextbuilder.h index 4ac4db6..3dd09ab 100644 --- a/duchain/contextbuilder.h +++ b/duchain/contextbuilder.h @@ -1,52 +1,69 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef CONTEXTBUILDER_H #define CONTEXTBUILDER_H #include #include "rustnode.h" #include "parsesession.h" #include "kdevrustduchain_export.h" namespace Rust { using ContextBuilderBase = KDevelop::AbstractContextBuilder; class KDEVRUSTDUCHAIN_EXPORT ContextBuilder : public ContextBuilderBase { public: ContextBuilder() = default; ~ContextBuilder() override = default; void setParseSession(ParseSession *session); protected: KDevelop::RangeInRevision editorFindSpellingRange(RustNode *node, const QString &identifier); template RSVisitResult buildContext(RustNode *node, RustNode *parent); template KDevelop::DUContext *createContext(RSNode *node, const KDevelop::QualifiedIdentifier& scopeId); virtual RSVisitResult visitNode(RustNode *node, RustNode *parent); void visitChildren(RustNode *node); void startVisiting(RustNode *node) override; void setContextOnNode(RustNode *node, KDevelop::DUContext *context) override; KDevelop::DUContext *contextFromNode(RustNode *node) override; KDevelop::RangeInRevision editorFindRange(RustNode *fromNode, RustNode *toNode) override; KDevelop::QualifiedIdentifier identifierForNode(RustPath *node) override; KDevelop::DUContext *newContext(const KDevelop::RangeInRevision &range) override; KDevelop::TopDUContext *newTopContext(const KDevelop::RangeInRevision &range, KDevelop::ParsingEnvironmentFile *file) override; private: friend RSVisitResult visitCallback(RSNode *node, RSNode *parent, void *data); ParseSession *session; }; } #endif // CONTEXTBUILDER_H diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp index 5df418c..012d258 100644 --- a/duchain/declarationbuilder.cpp +++ b/duchain/declarationbuilder.cpp @@ -1,156 +1,173 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "declarationbuilder.h" #include #include #include "types/declarationtypes.h" #include "nodetraits.h" #include "rustdebug.h" namespace Rust { using namespace KDevelop; RSVisitResult DeclarationBuilder::visitNode(RustNode *node, RustNode *parent) { RSNodeKind kind = node_get_kind(node->data()); switch (kind) { case Module: return buildDeclaration(node, parent); case StructDecl: return buildDeclaration(node, parent); case EnumDecl: return buildDeclaration(node, parent); case FunctionDecl: return buildDeclaration(node, parent); case TraitDecl: return buildDeclaration(node, parent); case TypeAliasDecl: return buildDeclaration(node, parent); case EnumVariantDecl: return buildDeclaration(node, parent); case FieldDecl: return buildDeclaration(node, parent); case VarDecl: return buildDeclaration(node, parent); default: return ContextBuilder::visitNode(node, parent); } } template RSVisitResult DeclarationBuilder::buildDeclaration(RustNode *node, RustNode *parent) { Q_UNUSED(parent); constexpr bool hasContext = NodeTraits::hasContext(Kind); RustPath name(node); createDeclaration(node, &name, hasContext); RSVisitResult ret = buildContext(node, parent); if (hasContext) eventuallyAssignInternalContext(); closeDeclaration(); return ret; } template Declaration *DeclarationBuilder::createDeclaration(RustNode *node, RustPath *name, bool hasContext) { auto range = editorFindSpellingRange(node, name->value); typename DeclType::Type *decl = openDeclaration::Type>(Identifier(name->value), range, hasContext ? DeclarationIsDefinition : NoFlags); if (NodeTraits::isTypeDeclaration(Kind)) { decl->setKind(Declaration::Type); } auto type = createType(node); openType(type); setDeclData(decl); setType(decl, type.data()); closeType(); return decl; } template > typename IdType::Type::Ptr DeclarationBuilder::createType(RustNode *node) { Q_UNUSED(node); return typename IdType::Type::Ptr(new typename IdType::Type); } template > FunctionType::Ptr DeclarationBuilder::createType(RustNode *node) { Q_UNUSED(node); return FunctionType::Ptr(new FunctionType); } template > AbstractType::Ptr DeclarationBuilder::createType(RustNode *node) { Q_UNUSED(node); return AbstractType::Ptr(new IntegralType(IntegralType::TypeMixed)); } template void DeclarationBuilder::setType(Declaration *decl, typename IdType::Type *type) { setType(decl, static_cast(type)); setType(decl, static_cast(type)); } template void DeclarationBuilder::setType(Declaration *decl, IdentifiedType *type) { type->setDeclaration(decl); } template void DeclarationBuilder::setType(Declaration *decl, AbstractType *type) { decl->setAbstractType(AbstractType::Ptr(type)); } template> void DeclarationBuilder::setDeclData(ClassDeclaration *decl) { if (Kind == StructDecl || Kind == ImplDecl) { decl->setClassType(ClassDeclarationData::Struct); } else if (Kind == TraitDecl) { decl->setClassType(ClassDeclarationData::Trait); } } template> void DeclarationBuilder::setDeclData(Declaration *decl) { decl->setKind(Declaration::Namespace); } template> void DeclarationBuilder::setDeclData(Declaration *decl) { decl->setKind(Declaration::Instance); } template> void DeclarationBuilder::setDeclData(AliasDeclaration *decl) { decl->setIsTypeAlias(true); decl->setKind(Declaration::Type); } template> void DeclarationBuilder::setDeclData(Declaration *decl) { Q_UNUSED(decl); } } diff --git a/duchain/declarationbuilder.h b/duchain/declarationbuilder.h index 0ae335f..1e2e17f 100644 --- a/duchain/declarationbuilder.h +++ b/duchain/declarationbuilder.h @@ -1,81 +1,98 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef DECLARATIONBUILDER_H #define DECLARATIONBUILDER_H #include #include #include #include #include "types/declarationtypes.h" #include "contextbuilder.h" #include "nodetraits.h" #include "rustnode.h" #include "astredux.h" #include "kdevrustduchain_export.h" namespace Rust { using TypeBuilderBase = KDevelop::AbstractTypeBuilder; using DeclarationBuilderBase = KDevelop::AbstractDeclarationBuilder; namespace detail { enum class enabler {}; } constexpr detail::enabler dummy = {}; template using EnableIf = typename std::enable_if::type; class KDEVRUSTDUCHAIN_EXPORT DeclarationBuilder : public DeclarationBuilderBase { public: DeclarationBuilder() = default; ~DeclarationBuilder() override = default; protected: RSVisitResult visitNode(RustNode *node, RustNode *parent) override; private: template RSVisitResult buildDeclaration(RustNode *node, RustNode *parent); template KDevelop::Declaration *createDeclaration(RustNode *node, RustPath *name, bool hasContext); template = dummy> typename IdType::Type::Ptr createType(RustNode *node); template = dummy> KDevelop::FunctionType::Ptr createType(RustNode *node); template = dummy> KDevelop::AbstractType::Ptr createType(RustNode *node); template = dummy> void setDeclData(KDevelop::Declaration *decl); template = dummy> void setDeclData(KDevelop::Declaration *decl); template = dummy> void setDeclData(KDevelop::Declaration *decl); template = dummy> void setDeclData(KDevelop::AliasDeclaration *decl); template = dummy> void setDeclData(KDevelop::ClassDeclaration *decl); template void setType(KDevelop::Declaration *decl, typename IdType::Type *type); template void setType(KDevelop::Declaration *decl, KDevelop::IdentifiedType *type); template void setType(KDevelop::Declaration *decl, KDevelop::AbstractType *type); }; } #endif // DECLARATIONBUILDER_H diff --git a/duchain/navigation/navigationwidget.cpp b/duchain/navigation/navigationwidget.cpp index bb7fa46..5a5448a 100644 --- a/duchain/navigation/navigationwidget.cpp +++ b/duchain/navigation/navigationwidget.cpp @@ -1,25 +1,42 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "navigationwidget.h" namespace Rust { //NavigationWidget::NavigationWidget(KDevelop::DeclarationPointer declaration, KDevelop::TopDUContextPointer topContext, // const QString& /* htmlPrefix */, const QString& /* htmlSuffix */, KDevelop::AbstractNavigationWidget::DisplayHints hints) // : KDevelop::AbstractNavigationWidget() //{ // setDisplayHints(hints); // initBrowser(400); // auto realDeclaration = DeclarationPointer(Helper::resolveAliasDeclaration(declaration.data())); // auto context = new DeclarationNavigationContext(realDeclaration, topContext); // setContext(NavigationContextPointer(context)); //} //NavigationWidget::NavigationWidget(const IncludeItem &/*includeItem*/, TopDUContextPointer /*topContext*/, // const QString &/*htmlPrefix*/, const QString &/*htmlSuffix*/, KDevelop::AbstractNavigationWidget::DisplayHints hints) // : KDevelop::AbstractNavigationWidget() //{ // setDisplayHints(hints); // // not supported //} } diff --git a/duchain/navigation/navigationwidget.h b/duchain/navigation/navigationwidget.h index 9c336a2..d963420 100644 --- a/duchain/navigation/navigationwidget.h +++ b/duchain/navigation/navigationwidget.h @@ -1,11 +1,28 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef NAVIGATIONWIDGET_H #define NAVIGATIONWIDGET_H class NavigationWidget { public: NavigationWidget(); }; #endif // NAVIGATIONWIDGET_H diff --git a/duchain/nodetraits.h b/duchain/nodetraits.h index e77019a..857147d 100644 --- a/duchain/nodetraits.h +++ b/duchain/nodetraits.h @@ -1,52 +1,69 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef NODETRAITS_H #define NODETRAITS_H #include #include "astredux.h" namespace Rust { namespace NodeTraits { constexpr bool hasContext(RSNodeKind kind) { return kind == Crate || kind == Module || kind == StructDecl || kind == EnumDecl || kind == TraitDecl || kind == ImplDecl || kind == FunctionDecl || kind == Block || kind == Arm; } constexpr KDevelop::DUContext::ContextType contextType(RSNodeKind kind) { using namespace KDevelop; return kind == Crate ? DUContext::Global : kind == Module ? DUContext::Namespace : kind == StructDecl ? DUContext::Class : kind == EnumDecl ? DUContext::Enum : kind == TraitDecl ? DUContext::Class : kind == ImplDecl ? DUContext::Class : kind == FunctionDecl ? DUContext::Function : kind == Block ? DUContext::Other : kind == Arm ? DUContext::Other : static_cast(-1); } constexpr bool isKDevDeclaration(RSNodeKind kind) { return kind == EnumDecl || kind == EnumVariantDecl || kind == ParmDecl || kind == VarDecl || kind == Module; } constexpr bool isTypeDeclaration(RSNodeKind kind) { return kind == EnumDecl || kind == EnumVariantDecl || kind == StructDecl || kind == ImplDecl || kind == TraitDecl; } } } #endif // NODETRAITS_H diff --git a/duchain/parsesession.cpp b/duchain/parsesession.cpp index 3ef5013..76a0b1e 100644 --- a/duchain/parsesession.cpp +++ b/duchain/parsesession.cpp @@ -1,70 +1,87 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "parsesession.h" namespace Rust { ParseSessionData::ParseSessionData(const KDevelop::IndexedString &document, const QByteArray &contents) : m_document(document), m_contents(contents), m_crate(nullptr) { } ParseSessionData::~ParseSessionData() { if (m_crate != nullptr) { destroy_crate(m_crate); } } void ParseSessionData::parse() { m_crate = parse_crate(m_document.c_str(), m_contents); } ParseSession::ParseSession(const ParseSessionData::Ptr &data) : d(data) { } ParseSession::~ParseSession() { } void ParseSession::parse() { d->parse(); } ParseSessionData::Ptr ParseSession::data() const { return d; } void ParseSession::setData(const ParseSessionData::Ptr data) { this->d = data; } KDevelop::IndexedString ParseSession::document() const { return d->m_document; } RSCrate *ParseSession::crate() const { return d->m_crate; } void ParseSession::setContextOnNode(RustNode *node, KDevelop::DUContext *context) { d->m_nodeContextMap.insert(node_get_id(node->data()), context); } KDevelop::DUContext *ParseSession::contextFromNode(RustNode *node) { return d->m_nodeContextMap.value(node_get_id(node->data())); } } diff --git a/duchain/parsesession.h b/duchain/parsesession.h index 76f9e2d..a27b3a3 100644 --- a/duchain/parsesession.h +++ b/duchain/parsesession.h @@ -1,64 +1,81 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef PARSESESSION_H #define PARSESESSION_H #include #include #include #include #include "astredux.h" #include "rustnode.h" #include "kdevrustduchain_export.h" namespace Rust { class KDEVRUSTDUCHAIN_EXPORT ParseSessionData : public KDevelop::IAstContainer { public: typedef QExplicitlySharedDataPointer Ptr; ParseSessionData(const KDevelop::IndexedString &document, const QByteArray &contents); ~ParseSessionData() override; private: friend class ParseSession; void parse(); KDevelop::IndexedString m_document; QByteArray m_contents; RSCrate *m_crate; QMap m_nodeContextMap; }; class KDEVRUSTDUCHAIN_EXPORT ParseSession { public: explicit ParseSession(const ParseSessionData::Ptr &data); ~ParseSession(); void parse(); ParseSessionData::Ptr data() const; void setData(const ParseSessionData::Ptr data); KDevelop::IndexedString document() const; RSCrate *crate() const; void setContextOnNode(RustNode *node, KDevelop::DUContext *context); KDevelop::DUContext *contextFromNode(RustNode *node); private: Q_DISABLE_COPY(ParseSession) ParseSessionData::Ptr d; }; } #endif // PARSESESSION_H diff --git a/duchain/rustducontext.cpp b/duchain/rustducontext.cpp index 33f0db1..59b1b0d 100644 --- a/duchain/rustducontext.cpp +++ b/duchain/rustducontext.cpp @@ -1,11 +1,28 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "rustducontext.h" #include namespace Rust { REGISTER_DUCHAIN_ITEM_WITH_DATA(RustTopDUContext, TopDUContextData); REGISTER_DUCHAIN_ITEM_WITH_DATA(RustNormalDUContext, DUContextData); } diff --git a/duchain/rustducontext.h b/duchain/rustducontext.h index dc8eb53..50d50ea 100644 --- a/duchain/rustducontext.h +++ b/duchain/rustducontext.h @@ -1,39 +1,56 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef RUSTDUCONTEXT_H #define RUSTDUCONTEXT_H #include #include #include #include "kdevrustduchain_export.h" namespace Rust { using namespace KDevelop; template class KDEVRUSTDUCHAIN_EXPORT RustDUContext : public BaseContext { public: template explicit RustDUContext(Data& data) : BaseContext(data) { } ///Parameters will be reached to the base-class template explicit RustDUContext(Params... params) : BaseContext(params...) { static_cast(this)->d_func_dynamic()->setClassId(this); } enum { Identity = IdentityT }; }; using RustTopDUContext = RustDUContext; using RustNormalDUContext = RustDUContext; } #endif // RUSTDUCONTEXT_H diff --git a/duchain/rustnode.cpp b/duchain/rustnode.cpp index a85fcc6..e7baa87 100644 --- a/duchain/rustnode.cpp +++ b/duchain/rustnode.cpp @@ -1,56 +1,73 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "rustnode.h" namespace Rust { RustPath::RustPath(RustNode *node) { RustString name = RustString(node_get_spelling_name(node->data())); if (*name == nullptr) { value = QString(); } else { value = QString::fromUtf8(*name); } } RustNode::RustNode(RSNode *node) : RustAllocatedObject(node) { } RustNode::RustNode(RustOwnedNode &node) : RustAllocatedObject(node.data()) { } RustNode::~RustNode() { } template RustAllocatedObject::RustAllocatedObject(RustObjectType *object) : object(object) { } template RustAllocatedObject::~RustAllocatedObject() { RustDestructor(object); object = nullptr; } template RustObjectType *RustAllocatedObject::data() { return object; } template RustObjectType *RustAllocatedObject::operator *() { return object; } } diff --git a/duchain/rustnode.h b/duchain/rustnode.h index c2bd6be..b528cc4 100644 --- a/duchain/rustnode.h +++ b/duchain/rustnode.h @@ -1,60 +1,77 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef RUSTNODE_H #define RUSTNODE_H #include #include "astredux.h" #include "kdevrustduchain_export.h" namespace Rust { template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject { public: RustAllocatedObject(RustObjectType *object); ~RustAllocatedObject(); RustObjectType *data(); RustObjectType *operator *(); private: RustObjectType *object; }; template void noop_destructor(T *) {} using RustCrate = RustAllocatedObject; using RustOwnedNode = RustAllocatedObject; using RustString = RustAllocatedObject; using RustDiagnostic = RustAllocatedObject; using RustDiagnosticIterator = RustAllocatedObject; class KDEVRUSTDUCHAIN_EXPORT RustNode : public RustAllocatedObject { public: RustNode(RSNode *node); RustNode(RustOwnedNode &node); ~RustNode(); }; class KDEVRUSTDUCHAIN_EXPORT RustPath { public: explicit RustPath(RustNode *node); QString value; }; template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject; template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject; template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject; template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject; template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject; template class KDEVRUSTDUCHAIN_EXPORT RustAllocatedObject; } #endif // RUSTNODE_H diff --git a/duchain/tests/duchaintest.cpp b/duchain/tests/duchaintest.cpp index 28be28a..a885d3a 100644 --- a/duchain/tests/duchaintest.cpp +++ b/duchain/tests/duchaintest.cpp @@ -1,133 +1,150 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "duchaintest.h" #include #include #include #include #include #include #include "parsesession.h" #include "declarationbuilder.h" #include "usebuilder.h" using namespace KDevelop; QTEST_MAIN(DUChainTest) ReferencedTopDUContext parseCode(QString code) { using namespace Rust; IndexedString document("temp"); ParseSessionData *sessionData = new ParseSessionData(document, code.toUtf8()); ParseSession session(ParseSessionData::Ptr(nullptr)); session.setData(ParseSessionData::Ptr(sessionData)); session.parse(); RustOwnedNode crateNode = RustOwnedNode(node_from_crate(session.crate())); RustNode node = RustNode(crateNode); DeclarationBuilder declarationBuilder; UseBuilder useBuilder(document); declarationBuilder.setParseSession(&session); useBuilder.setParseSession(&session); ReferencedTopDUContext context = declarationBuilder.build(document, &node); useBuilder.buildUses(&node); return context; } QString inMain(QString code) { return QString("fn main() { %1 }").arg(code); } DUContext *getMainContext(ReferencedTopDUContext topContext) { if (!topContext) { return nullptr; } DUChainReadLocker lock; QList mainDeclaration = topContext->findDeclarations(QualifiedIdentifier("main")); if (mainDeclaration.size() != 1 || !mainDeclaration.first()) { return nullptr; } DUContext *mainContext = mainDeclaration.first()->internalContext(); if (mainContext->childContexts().size() != 1 || !mainContext->childContexts().first()) { return nullptr; } return mainContext->childContexts().first(); } void DUChainTest::initTestCase() { AutoTestShell::init(); TestCore::initialize(Core::NoUi); } void DUChainTest::sanityCheck() { QString code("fn main() {}"); ReferencedTopDUContext context = parseCode(code); QVERIFY(context.data()); DUChainReadLocker lock; auto decls = context->localDeclarations(); QCOMPARE(decls.size(), 1); Declaration *funcDeclaration = decls.first(); QVERIFY(funcDeclaration); QCOMPARE(funcDeclaration->identifier().toString(), QString("main")); } void DUChainTest::cleanupTestCase() { TestCore::shutdown(); } void DUChainTest::testPatternBindings() { QFETCH(QString, pattern); QFETCH(QStringList, bindings); QString code = inMain(QString("let %1 = unreachable!();").arg(pattern)); ReferencedTopDUContext context = parseCode(code); DUContext *mainContext = getMainContext(context); QCOMPARE(mainContext->localDeclarations().size(), bindings.size()); for (const QString &binding : bindings) { QCOMPARE(mainContext->findLocalDeclarations(Identifier(binding)).size(), 1); } } void DUChainTest::testPatternBindings_data() { QTest::addColumn("pattern"); QTest::addColumn("bindings"); QTest::newRow("unit") << "()" << QStringList(); QTest::newRow("wildcard") << "_" << QStringList(); QTest::newRow("simple ident") << "x" << QStringList { "x" }; QTest::newRow("simple ident underscore") << "_x" << QStringList { "_x" }; QTest::newRow("mut ident") << "mut x" << QStringList { "x" }; QTest::newRow("ref ident") << "ref x" << QStringList { "x" }; QTest::newRow("ref mut ident") << "ref mut x" << QStringList { "x" }; QTest::newRow("struct single field") << "Foo { x }" << QStringList { "x" }; QTest::newRow("struct single field renamed") << "Foo { x: a }" << QStringList { "a" }; QTest::newRow("struct multiple fields") << "Foo { x, y }" << QStringList { "x", "y" }; QTest::newRow("struct multiple fields renamed") << "Foo { x: a, y: b }" << QStringList { "a", "b" }; QTest::newRow("struct multiple fields single renamed") << "Foo { x: a, y }" << QStringList { "a", "y" }; QTest::newRow("struct multiple fields with remaining") << "Foo { x, y, .. }" << QStringList { "x", "y" }; QTest::newRow("tuple") << "(x, y)" << QStringList { "x", "y" }; QTest::newRow("tuple with remaining") << "(x, y, .., z)" << QStringList { "x", "y", "z" }; QTest::newRow("full with destructure tuple") << "t@(x, y)" << QStringList { "t", "x", "y" }; QTest::newRow("full with destructure struct") << "t@Foo { x, y }" << QStringList { "t", "x", "y" }; } diff --git a/duchain/tests/duchaintest.h b/duchain/tests/duchaintest.h index fe45949..b0443c2 100644 --- a/duchain/tests/duchaintest.h +++ b/duchain/tests/duchaintest.h @@ -1,18 +1,35 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef DUCHAINTEST_H #define DUCHAINTEST_H #include class DUChainTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void sanityCheck(); void cleanupTestCase(); void testPatternBindings(); void testPatternBindings_data(); }; #endif // DUCHAINTEST_H diff --git a/duchain/types/declarationtypes.h b/duchain/types/declarationtypes.h index 00c0fcc..b592935 100644 --- a/duchain/types/declarationtypes.h +++ b/duchain/types/declarationtypes.h @@ -1,88 +1,105 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef DECLARATIONTYPES_H #define DECLARATIONTYPES_H #include #include #include #include #include #include #include #include "astredux.h" #include "nodetraits.h" namespace Rust { template struct IdType; template struct IdType::type> { typedef KDevelop::StructureType Type; }; template struct IdType::type> { typedef KDevelop::TypeAliasType Type; }; template struct IdType::type> { typedef KDevelop::EnumerationType Type; }; template struct IdType::type> { typedef KDevelop::EnumeratorType Type; }; template struct DeclType; template struct DeclType::type> { typedef KDevelop::Declaration Type; }; template struct DeclType::type> { typedef KDevelop::ClassDeclaration Type; }; template struct DeclType::type> { typedef KDevelop::AliasDeclaration Type; }; // FIXME: specialize //template //struct DeclType::type> //{ // typedef KDevelop::ClassFunctionDeclaration Type; //}; template struct DeclType::type> { typedef KDevelop::FunctionDeclaration Type; }; template struct DeclType::type> { typedef KDevelop::ClassMemberDeclaration Type; }; } #endif // DECLARATIONTYPES_H diff --git a/duchain/usebuilder.cpp b/duchain/usebuilder.cpp index b1e39ac..a2c2f6d 100644 --- a/duchain/usebuilder.cpp +++ b/duchain/usebuilder.cpp @@ -1,90 +1,107 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "usebuilder.h" #include #include #include #include #include "rustdebug.h" namespace Rust { using namespace KDevelop; UseBuilder::UseBuilder(const KDevelop::IndexedString &document) : document(document) { } RSVisitResult UseBuilder::visitNode(RustNode *node, RustNode *parent) { RSNodeKind kind = node_get_kind(node->data()); RSNodeKind parentKind = node_get_kind(parent->data()); if (kind == Path) { visitPath(node, parent); } else if (parentKind == Path && kind == PathSegment) { visitPathSegment(node, parent); } return ContextBuilder::visitNode(node, parent); } void UseBuilder::visitPath(RustNode *node, RustNode *parent) { RustPath path(node); fullPath = identifierForNode(&path); currentPath.clear(); } void UseBuilder::visitPathSegment(RustNode *node, RustNode *parent) { RustPath segment(node); IndexedIdentifier pathSegment = IndexedIdentifier(Identifier(segment.value)); currentPath.push(pathSegment); DUContext::SearchFlags flags = DUContext::NoSearchFlags; if (fullPath.isQualified()) { flags = DUContext::NoFiltering; } RangeInRevision useRange = editorFindRange(node, node); DUContext *context = topContext()->findContextAt(useRange.start); QList declarations = context->findDeclarations(currentPath, CursorInRevision::invalid(), AbstractType::Ptr(), nullptr, flags); if (declarations.isEmpty() || !declarations.first()) { ProblemPointer p = ProblemPointer(new Problem()); p->setFinalLocation(DocumentRange(document, useRange.castToSimpleRange())); p->setSource(IProblem::SemanticAnalysis); p->setSeverity(IProblem::Hint); p->setDescription(i18n("Undefined %1", fullPath.toString())); DUChainWriteLocker lock(DUChain::lock()); topContext()->addProblem(p); } else { for (Declaration *declaration : declarations) { if (fullPath.isQualified() && currentPath != fullPath) { // We are dealing with a container-like path, ignore functions and variables if (!declaration->internalContext() || declaration->internalContext()->type() == DUContext::Other || declaration->internalContext()->type() == DUContext::Function) { continue; } } if (declaration->range() != useRange) { UseBuilderBase::newUse(node, useRange, DeclarationPointer(declaration)); break; } } } } } diff --git a/duchain/usebuilder.h b/duchain/usebuilder.h index 3f0a87c..63ebf56 100644 --- a/duchain/usebuilder.h +++ b/duchain/usebuilder.h @@ -1,37 +1,54 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef USEBUILDER_H #define USEBUILDER_H #include #include #include "contextbuilder.h" #include "rustnode.h" #include "kdevrustduchain_export.h" namespace Rust { using UseBuilderBase = KDevelop::AbstractUseBuilder; class KDEVRUSTDUCHAIN_EXPORT UseBuilder : public UseBuilderBase { public: UseBuilder(const KDevelop::IndexedString &document); ~UseBuilder() override = default; RSVisitResult visitNode(RustNode *node, RustNode *parent) override; private: void visitPath(RustNode *node, RustNode *parent); void visitPathSegment(RustNode *node, RustNode *parent); KDevelop::QualifiedIdentifier fullPath; KDevelop::QualifiedIdentifier currentPath; KDevelop::IndexedString document; }; } #endif // USEBUILDER_H diff --git a/rusthighlighting.cpp b/rusthighlighting.cpp index ca5718c..02037a0 100644 --- a/rusthighlighting.cpp +++ b/rusthighlighting.cpp @@ -1,42 +1,59 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "rusthighlighting.h" #include using namespace KDevelop; namespace Rust { class HighlightingInstance : public CodeHighlightingInstance { public: HighlightingInstance(const Highlighting *highlighting); ~HighlightingInstance() override; bool useRainbowColor(Declaration *dec) const override; }; HighlightingInstance::HighlightingInstance(const Highlighting *highlighting) : CodeHighlightingInstance(highlighting) { } HighlightingInstance::~HighlightingInstance() { } bool HighlightingInstance::useRainbowColor(Declaration *dec) const { return dec->context()->type() == DUContext::Function || dec->context()->type() == DUContext::Other; } Highlighting::Highlighting(QObject *parent) : CodeHighlighting(parent) { } CodeHighlightingInstance *Highlighting::createInstance() const { return new HighlightingInstance(this); } } diff --git a/rusthighlighting.h b/rusthighlighting.h index f4e4141..3327807 100644 --- a/rusthighlighting.h +++ b/rusthighlighting.h @@ -1,19 +1,36 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef RUSTHIGHLIGHTING_H #define RUSTHIGHLIGHTING_H #include namespace Rust { class Highlighting : public KDevelop::CodeHighlighting { Q_OBJECT public: Highlighting(QObject *parent); KDevelop::CodeHighlightingInstance *createInstance() const override; }; } #endif // RUSTHIGHLIGHTING_H diff --git a/rustlanguagesupport.cpp b/rustlanguagesupport.cpp index 020ade8..7ef6edb 100644 --- a/rustlanguagesupport.cpp +++ b/rustlanguagesupport.cpp @@ -1,83 +1,100 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "rustlanguagesupport.h" #include #include #include #include #include #include #include #include #include #include #include #include "rustparsejob.h" #include "codecompletion/completionmodel.h" K_PLUGIN_FACTORY_WITH_JSON(KDevRustSupportFactory, "kdevrustsupport.json", registerPlugin(); ) using namespace KDevelop; namespace Rust { LanguageSupport::LanguageSupport(QObject *parent, const QVariantList &args) : KDevelop::IPlugin(QStringLiteral("kdevrustsupport"), parent), KDevelop::ILanguageSupport(), m_highlighting(new Highlighting(this)) { Q_UNUSED(args); new CodeCompletion(this, new CompletionModel(this), name()); } LanguageSupport::~LanguageSupport() { parseLock()->lockForWrite(); parseLock()->unlock(); delete m_highlighting; } QString LanguageSupport::name() const { return "Rust"; } KDevelop::ParseJob *LanguageSupport::createParseJob(const KDevelop::IndexedString &url) { return new ParseJob(url, this); } ICodeHighlighting *LanguageSupport::codeHighlighting() const { return m_highlighting; } SourceFormatterItemList LanguageSupport::sourceFormatterItems() const { SourceFormatterStyle rustFormatter("rustfmt"); rustFormatter.setCaption("rustfmt"); rustFormatter.setDescription(i18n("Format source with rustfmt.")); rustFormatter.setMimeTypes(SourceFormatterStyle::MimeList { SourceFormatterStyle::MimeHighlightPair { "text/rust", "Rust" }, SourceFormatterStyle::MimeHighlightPair { "text/x-rust", "Rust" } }); QString rustfmtPath = QStandardPaths::findExecutable("rustfmt"); if (rustfmtPath.isEmpty()) { qCDebug(KDEV_RUST) << "Could not find the rustfmt executable"; rustfmtPath = "/usr/bin/rustfmt"; } rustFormatter.setContent(rustfmtPath + " --skip-children $TMPFILE"); return SourceFormatterItemList { SourceFormatterStyleItem { "customscript", rustFormatter } }; } } #include "rustlanguagesupport.moc" diff --git a/rustlanguagesupport.h b/rustlanguagesupport.h index 9228a6a..5f665c1 100644 --- a/rustlanguagesupport.h +++ b/rustlanguagesupport.h @@ -1,42 +1,59 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef KDEVRUSTLANGUAGESUPPORT_H #define KDEVRUSTLANGUAGESUPPORT_H #include #include #include #include #include #include #include "rusthighlighting.h" #include "duchain/astredux.h" namespace Rust { class LanguageSupport : public KDevelop::IPlugin , public KDevelop::ILanguageSupport { Q_OBJECT Q_INTERFACES( KDevelop::ILanguageSupport ) public: LanguageSupport(QObject *parent, const QVariantList &args = QVariantList()); ~LanguageSupport() override; QString name() const override; KDevelop::ParseJob *createParseJob(const KDevelop::IndexedString &url) override; KDevelop::ICodeHighlighting *codeHighlighting() const override; KDevelop::SourceFormatterItemList sourceFormatterItems() const override; private: Highlighting *m_highlighting; }; } #endif // KDEVRUSTLANGUAGESUPPORT_H diff --git a/rustparsejob.cpp b/rustparsejob.cpp index 70a1d5e..4153d54 100644 --- a/rustparsejob.cpp +++ b/rustparsejob.cpp @@ -1,210 +1,227 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #include "rustparsejob.h" #include #include #include #include #include #include #include #include #include #include #include #include "duchain/parsesession.h" #include "duchain/astredux.h" #include "duchain/declarationbuilder.h" #include "duchain/usebuilder.h" #include "rustlanguagesupport.h" #include "rustdebug.h" using namespace KDevelop; namespace Rust { ParseJob::ParseJob(const IndexedString &url, ILanguageSupport *languageSupport) : KDevelop::ParseJob(url, languageSupport) { } LanguageSupport *ParseJob::rust() const { return static_cast(languageSupport()); } ParseSessionData::Ptr ParseJob::findParseSessionData(const IndexedString &url) { DUChainReadLocker lock; auto context = KDevelop::DUChainUtils::standardContextForUrl(url.toUrl()); if (context) { return ParseSessionData::Ptr(dynamic_cast(context->ast().data())); } return {}; } void ParseJob::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) { if (abortRequested() || ICore::self()->shuttingDown()) { return abortJob(); } qCDebug(KDEV_RUST) << "Parse job starting for: " << document().toUrl(); QReadLocker parseLock(languageSupport()->parseLock()); { UrlParseLock urlLock(document()); readContents(); } if (abortRequested()) { return; } if (!(minimumFeatures() & TopDUContext::ForceUpdate || minimumFeatures() & Rescheduled)) { DUChainReadLocker lock; static const IndexedString langString(rust()->name()); for (const ParsingEnvironmentFilePointer &file : DUChain::self()->allEnvironmentFiles(document())) { if (file->language() != langString) { continue; } if (!file->needsUpdate() && file->featuresSatisfied(minimumFeatures()) && file->topContext()) { qCDebug(KDEV_RUST) << "Already up to date, skipping:" << document().str(); setDuChain(file->topContext()); if (ICore::self()->languageController()->backgroundParser()->trackerForUrl(document())) { lock.unlock(); highlightDUChain(); } return; } break; } } if (abortRequested()) { return; } ParseSession session(findParseSessionData(document())); if (!session.data()) { session.setData(ParseSessionData::Ptr(new ParseSessionData(document(), contents().contents))); } if (abortRequested()) { return; } ReferencedTopDUContext toUpdate = nullptr; { DUChainReadLocker lock; toUpdate = DUChainUtils::standardContextForUrl(document().toUrl()); } if (toUpdate) { translateDUChainToRevision(toUpdate); toUpdate->setRange(RangeInRevision(0, 0, INT_MAX, INT_MAX)); toUpdate->clearProblems(); } session.parse(); RustOwnedNode crateNode = RustOwnedNode(node_from_crate(session.crate())); if (abortRequested()) { return; } ReferencedTopDUContext context; if (crateNode.data() != nullptr) { RustNode node(crateNode); qCDebug(KDEV_RUST) << "Parsing succeeded for: " << document().toUrl(); DeclarationBuilder builder; builder.setParseSession(&session); context = builder.build(document(), &node, toUpdate); setDuChain(context); if (abortRequested()) { return; } UseBuilder uses(document()); uses.setParseSession(&session); uses.buildUses(&node); } else { qCDebug(KDEV_RUST) << "Parsing failed for: " << document().toUrl(); DUChainWriteLocker lock; context = toUpdate.data(); if (context) { ParsingEnvironmentFilePointer parsingEnvironmentFile = context->parsingEnvironmentFile(); parsingEnvironmentFile->setModificationRevision(contents().modification); context->clearProblems(); } else { ParsingEnvironmentFile *file = new ParsingEnvironmentFile(document()); file->setLanguage(IndexedString("Rust")); context = new TopDUContext(document(), RangeInRevision(0, 0, INT_MAX, INT_MAX), file); DUChain::self()->addDocumentChain(context); } setDuChain(context); } if (abortRequested()) { return; } RustDiagnosticIterator diagnostics(crate_get_diagnostics(session.crate())); RSDiagnostic *d = nullptr; while ((d = diagnostics_next(diagnostics.data())) != nullptr) { RustDiagnostic diagnostic(d); RSDiagnosticLevel level = diagnostic_get_level(diagnostic.data()); RustString message = diagnostic_get_message(diagnostic.data()); RSRange range = diagnostic_get_primary_range(diagnostic.data()); IProblem::Severity severity = (level == Fatal || level == Error) ? IProblem::Error : (level == Info || level == Note) ? IProblem::Hint : IProblem::Warning; ProblemPointer p = ProblemPointer(new Problem()); p->setFinalLocation(DocumentRange(document(), KTextEditor::Range(range.start.line - 1, range.start.column, range.end.line - 1, range.end.column))); p->setSource(IProblem::Parser); p->setSeverity(severity); p->setDescription(QString::fromUtf8(message.data())); DUChainWriteLocker lock(DUChain::lock()); context->addProblem(p); } if (minimumFeatures() & TopDUContext::AST) { DUChainWriteLocker lock; context->setAst(IAstContainer::Ptr(session.data())); } { DUChainWriteLocker lock; context->setFeatures(minimumFeatures()); ParsingEnvironmentFilePointer file = context->parsingEnvironmentFile(); Q_ASSERT(file); file->setModificationRevision(contents().modification); DUChain::self()->updateContextEnvironment(context->topContext(), file.data()); } highlightDUChain(); DUChain::self()->emitUpdateReady(document(), duChain()); qCDebug(KDEV_RUST) << "Parse job finished for: " << document().toUrl(); } } diff --git a/rustparsejob.h b/rustparsejob.h index 2af01d3..85b5a2a 100644 --- a/rustparsejob.h +++ b/rustparsejob.h @@ -1,37 +1,54 @@ +/* + * Copyright 2017 Emma Gospodinova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + #ifndef RUSTPARSEJOB_H #define RUSTPARSEJOB_H #include #include #include #include #include #include "duchain/parsesession.h" namespace Rust { class LanguageSupport; class ParseJob : public KDevelop::ParseJob { Q_OBJECT public: enum { Rescheduled = (KDevelop::TopDUContext::LastFeature << 1), }; ParseJob(const KDevelop::IndexedString &url, KDevelop::ILanguageSupport *languageSupport); protected: void run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) override; private: LanguageSupport *rust() const; ParseSessionData::Ptr findParseSessionData(const KDevelop::IndexedString &url); }; } #endif // RUSTPARSEJOB_H