summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/codeimport/pythonimport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'umbrello/umbrello/codeimport/pythonimport.cpp')
-rw-r--r--umbrello/umbrello/codeimport/pythonimport.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/umbrello/umbrello/codeimport/pythonimport.cpp b/umbrello/umbrello/codeimport/pythonimport.cpp
new file mode 100644
index 00000000..af59cf8a
--- /dev/null
+++ b/umbrello/umbrello/codeimport/pythonimport.cpp
@@ -0,0 +1,190 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * copyright (C) 2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "pythonimport.h"
+
+// qt/kde includes
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <kdebug.h>
+// app includes
+#include "import_utils.h"
+#include "../uml.h"
+#include "../umldoc.h"
+#include "../umlpackagelist.h"
+#include "../package.h"
+#include "../classifier.h"
+#include "../enum.h"
+#include "../operation.h"
+#include "../attribute.h"
+
+PythonImport::PythonImport() : NativeImportBase("#") {
+ setMultiLineComment("\"\"\"", "\"\"\"");
+ initVars();
+}
+
+PythonImport::~PythonImport() {
+}
+
+void PythonImport::initVars() {
+ m_srcIndentIndex = 0;
+ m_srcIndent[m_srcIndentIndex] = 0;
+ m_braceWasOpened = false;
+}
+
+bool PythonImport::preprocess(QString& line) {
+ if (NativeImportBase::preprocess(line))
+ return true;
+ // Handle single line comment
+ int pos = line.find(m_singleLineCommentIntro);
+ if (pos != -1) {
+ QString cmnt = line.mid(pos);
+ m_source.append(cmnt);
+ m_srcIndex++;
+ if (pos == 0)
+ return true;
+ line = line.left(pos);
+ line.remove( QRegExp("\\s+$") );
+ }
+ // Transform changes in indentation into braces a la C++/Java/Perl/...
+ pos = line.find( QRegExp("\\S") );
+ if (pos == -1)
+ return true;
+ bool isContinuation = false;
+ int leadingWhite = line.left(pos).contains( QRegExp("\\s") );
+ if (leadingWhite > m_srcIndent[m_srcIndentIndex]) {
+ if (m_srcIndex == 0) {
+ kError() << "PythonImport::preprocess(): internal error 1" << endl;
+ return true;
+ }
+ if (m_braceWasOpened) {
+ m_srcIndent[++m_srcIndentIndex] = leadingWhite;
+ m_braceWasOpened = false;
+ } else {
+ isContinuation = true;
+ }
+ } else {
+ while (m_srcIndentIndex > 0 && leadingWhite < m_srcIndent[m_srcIndentIndex]) {
+ m_srcIndentIndex--;
+ m_source.append("}");
+ m_srcIndex++;
+ }
+ }
+ if (line.endsWith(":")) {
+ line.replace( QRegExp(":$"), "{" );
+ m_braceWasOpened = true;
+ } else {
+ m_braceWasOpened = false;
+ }
+ if (!isContinuation && !m_braceWasOpened)
+ line += ';';
+ return false; // The input was not completely consumed by preprocessing.
+}
+
+void PythonImport::fillSource(const QString& word) {
+ QString lexeme;
+ const uint len = word.length();
+ for (uint i = 0; i < len; i++) {
+ const QChar& c = word[i];
+ if (c.isLetterOrNumber() || c == '_' || c == '.') {
+ lexeme += c;
+ } else {
+ if (!lexeme.isEmpty()) {
+ m_source.append(lexeme);
+ m_srcIndex++;
+ lexeme = QString();
+ }
+ m_source.append(QString(c));
+ m_srcIndex++;
+ }
+ }
+ if (!lexeme.isEmpty()) {
+ m_source.append(lexeme);
+ m_srcIndex++;
+ }
+}
+
+void PythonImport::skipBody() {
+ if (m_source[m_srcIndex] != "{")
+ skipStmt("{");
+ int braceNesting = 0;
+ QString token;
+ while (!(token = advance()).isNull()) {
+ if (token == "}") {
+ if (braceNesting <= 0)
+ break;
+ braceNesting--;
+ } else if (token == "{") {
+ braceNesting++;
+ }
+ }
+}
+
+bool PythonImport::parseStmt() {
+ const uint srcLength = m_source.count();
+ const QString& keyword = m_source[m_srcIndex];
+ if (keyword == "class") {
+ const QString& name = advance();
+ UMLObject *ns = Import_Utils::createUMLObject(Uml::ot_Class,
+ name, m_scope[m_scopeIndex], m_comment);
+ m_scope[++m_scopeIndex] = m_klass = static_cast<UMLClassifier*>(ns);
+ m_comment = QString();
+ if (advance() == "(") {
+ while (m_srcIndex < srcLength - 1 && advance() != ")") {
+ const QString& baseName = m_source[m_srcIndex];
+ Import_Utils::createGeneralization(m_klass, baseName);
+ if (advance() != ",")
+ break;
+ }
+ }
+ if (m_source[m_srcIndex] != "{") {
+ skipStmt("{");
+ }
+ return true;
+ }
+ if (keyword == "def") {
+ if (m_klass == NULL) {
+ // skip functions outside of a class
+ skipBody();
+ return true;
+ }
+ const QString& name = advance();
+ // operation
+ UMLOperation *op = Import_Utils::makeOperation(m_klass, name);
+ if (advance() != "(") {
+ kError() << "importPython def " << name << ": expecting \"(\"" << endl;
+ skipBody();
+ return true;
+ }
+ while (m_srcIndex < srcLength && advance() != ")") {
+ const QString& parName = m_source[m_srcIndex];
+ UMLAttribute *att = Import_Utils::addMethodParameter(op, "string", parName);
+ if (advance() != ",")
+ break;
+ }
+ Import_Utils::insertMethod(m_klass, op, Uml::Visibility::Public, "string",
+ false /*isStatic*/, false /*isAbstract*/, false /*isFriend*/,
+ false /*isConstructor*/, m_comment);
+ skipBody();
+ return true;
+ }
+ if (keyword == "}") {
+ if (m_scopeIndex)
+ m_klass = dynamic_cast<UMLClassifier*>(m_scope[--m_scopeIndex]);
+ else
+ kError() << "importPython: too many }" << endl;
+ return true;
+ }
+ return false; // @todo parsing of attributes
+}
+
+