File indexing completed on 2024-04-14 04:31:15
0001 /* This file is part of KDevelop 0002 * 0003 * Copyright (C) 2011-2015 Miquel Sabaté Solà <mikisabate@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 #include <parser/parser.h> 0020 0021 #include <language/editor/documentrange.h> 0022 0023 using namespace KDevelop; 0024 0025 namespace ruby 0026 { 0027 0028 Parser::Parser() 0029 { 0030 m_contents = nullptr; 0031 m_version = ruby21; 0032 ast = nullptr; 0033 } 0034 0035 Parser::Parser(const IndexedString &fileName, const QByteArray &contents) 0036 { 0037 currentDocument = fileName; 0038 m_contents = contents; 0039 m_version = ruby21; 0040 ast = nullptr; 0041 } 0042 0043 Parser::~Parser() 0044 { 0045 if (ast) { 0046 free_ast(ast->tree); 0047 delete ast; 0048 ast = nullptr; 0049 } 0050 } 0051 0052 void Parser::setContents(const QByteArray &contents) 0053 { 0054 m_contents = contents; 0055 } 0056 0057 void Parser::setRubyVersion(enum ruby_version version) 0058 { 0059 m_version = version; 0060 } 0061 0062 Ast * Parser::parse() 0063 { 0064 struct options_t opts; 0065 struct error_t *aux; 0066 opts.path = currentDocument.str().toUtf8(); 0067 opts.contents = m_contents.data(); 0068 opts.version = m_version; 0069 0070 // Let's call the parser ;) 0071 struct ast_t *res = rb_compile_file(&opts); 0072 ast = new Ast(res->tree); 0073 if (res->unrecoverable) { 0074 for (aux = res->errors; aux; aux = aux->next) { 0075 appendProblem(aux); 0076 } 0077 delete ast; 0078 ast = nullptr; 0079 rb_free(res); 0080 return nullptr; 0081 } else { 0082 problems.clear(); 0083 for (aux = res->errors; aux; aux = aux->next) { 0084 appendProblem(aux); 0085 } 0086 free_errors(res); 0087 free(res); 0088 } 0089 return ast; 0090 } 0091 0092 void Parser::mapAstUse(Ast *node, const SimpleUse &use) 0093 { 0094 Q_UNUSED(node); 0095 Q_UNUSED(use); 0096 } 0097 0098 const QString Parser::symbol(const Node *node) const 0099 { 0100 int len = node->pos.end_col - node->pos.start_col; 0101 return m_contents.mid(node->pos.offset - len, len); 0102 } 0103 0104 void Parser::appendProblem(const struct error_t *error) 0105 { 0106 int col = (error->column > 0) ? error->column - 1 : 0; 0107 ProblemPointer problem(new KDevelop::Problem); 0108 0109 KTextEditor::Cursor cursor(error->line - 1, col); 0110 KTextEditor::Range range(cursor, cursor); 0111 DocumentRange location(currentDocument, range); 0112 problem->setFinalLocation(location); 0113 problem->setDescription(QString(error->msg)); 0114 problem->setSource(IProblem::Parser); 0115 if (error->warning) { 0116 problem->setSeverity(IProblem::Error); 0117 } else { 0118 problem->setSeverity(IProblem::Warning); 0119 } 0120 problems << problem; 0121 } 0122 0123 } 0124