212 lines
6.8 KiB
Java
Executable File
212 lines
6.8 KiB
Java
Executable File
package synchronize;
|
|
|
|
import java.util.Dictionary;
|
|
import java.util.Hashtable;
|
|
import java.util.List;
|
|
import java.util.Vector;
|
|
|
|
import org.eclipse.emf.common.util.BasicEList;
|
|
import org.eclipse.emf.common.util.EList;
|
|
import org.eclipse.jface.dialogs.MessageDialog;
|
|
import org.eclipse.uml2.uml.Class;
|
|
import org.eclipse.uml2.uml.Generalization;
|
|
import org.eclipse.uml2.uml.Operation;
|
|
import org.eclipse.uml2.uml.Package;
|
|
import org.eclipse.uml2.uml.Property;
|
|
import org.eclipse.uml2.uml.Type;
|
|
import org.python.pydev.parser.jython.SimpleNode;
|
|
import org.python.pydev.parser.jython.ast.Assign;
|
|
import org.python.pydev.parser.jython.ast.Attribute;
|
|
import org.python.pydev.parser.jython.ast.Call;
|
|
import org.python.pydev.parser.jython.ast.ClassDef;
|
|
import org.python.pydev.parser.jython.ast.FunctionDef;
|
|
import org.python.pydev.parser.jython.ast.Import;
|
|
import org.python.pydev.parser.jython.ast.ImportFrom;
|
|
import org.python.pydev.parser.jython.ast.Module;
|
|
import org.python.pydev.parser.jython.ast.Name;
|
|
import org.python.pydev.parser.jython.ast.NameTok;
|
|
import org.python.pydev.parser.jython.ast.Num;
|
|
import org.python.pydev.parser.jython.ast.Str;
|
|
import org.python.pydev.parser.jython.ast.exprType;
|
|
import org.python.pydev.parser.jython.ast.stmtType;
|
|
|
|
import parser.ParseHelpers;
|
|
|
|
public class Py2UMLCreator {
|
|
|
|
// dictionary of all created classes for later access
|
|
private Dictionary<String, Class> classDict;
|
|
|
|
// list of generalizations to add to model
|
|
// after adding all classes
|
|
private List<Tuple<Class, String>> generalizations;
|
|
|
|
|
|
public Py2UMLCreator() {
|
|
this.classDict = new Hashtable<String, Class>();
|
|
this.generalizations = new Vector<Tuple<Class, String>>();
|
|
}
|
|
|
|
public void createModelFromAST(SimpleNode root, Package rootPack) {
|
|
parsePackage(root, rootPack);
|
|
}
|
|
|
|
private void parsePackage(SimpleNode node, Package pack) {
|
|
if (node instanceof Module) {
|
|
Module pyModule = (Module) node;
|
|
stmtType[] statements = pyModule.body;
|
|
for (int i = 0; i < statements.length; i++) {
|
|
parsePackage(statements[i], pack);
|
|
if (statements[i] instanceof ClassDef) {
|
|
ClassDef pyClass = (ClassDef) statements[i];
|
|
parseClass(pyClass, pack);
|
|
}
|
|
if (statements[i] instanceof ImportFrom) {
|
|
ImportFrom importFrom = (ImportFrom) statements[i];
|
|
//System.out.println("---import---");
|
|
//System.out.println(((NameTok)importFrom.names[0].name).id);
|
|
}
|
|
if (statements[i] instanceof Import) {
|
|
Import importFrom = (Import) statements[i];
|
|
//System.out.println("---import---");
|
|
//System.out.println(((NameTok)importFrom.names[0].name).id);
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add generalizations to model
|
|
*/
|
|
public void createGeneralizations() {
|
|
System.out.println("creating Gens");
|
|
System.out.println(this.generalizations);
|
|
for (Tuple<Class, String> tup : this.generalizations) {
|
|
Class subClass = tup.a;
|
|
String superClassStr = tup.b;
|
|
System.out.println("create gen for " + subClass.getName());
|
|
System.out.println(superClassStr);
|
|
if ((classDict.get(superClassStr)) == null) {
|
|
System.out.println("...failed");
|
|
continue;
|
|
}
|
|
Class superclass = classDict.get(superClassStr);
|
|
Generalization gen = subClass.createGeneralization(superclass);
|
|
}
|
|
}
|
|
|
|
// get basic class information
|
|
|
|
private void parseClass(ClassDef pyClass, Package pack) {
|
|
String className=((NameTok) pyClass.name).id;
|
|
Class cl = pack.createOwnedClass(className, false);
|
|
if (classDict.get(className) != null)
|
|
MessageDialog.openError(null, "Duplicate Class detected",
|
|
"The class '"+className+ "' exists more than 1 time!");
|
|
this.classDict.put(className, cl);
|
|
|
|
System.out.println("class "+className);
|
|
exprType[] baseClasses=pyClass.bases;
|
|
for (exprType baseClass : baseClasses) {
|
|
if (baseClass instanceof Name) {
|
|
String baseName = ((Name)baseClass).id;
|
|
System.out.println("found base class " + baseName);
|
|
// add generalization
|
|
generalizations.add(new Tuple<Class,String>(cl, baseName));
|
|
}else if (baseClass instanceof Attribute){
|
|
Attribute att = (Attribute) baseClass;
|
|
String baseName=att.attr.toString();
|
|
System.out.println("found base class " + baseName);
|
|
// add generalization
|
|
generalizations.add(new Tuple<Class,String>(cl, baseName));
|
|
}
|
|
}
|
|
|
|
// parse class body
|
|
|
|
stmtType[] statements = pyClass.body;
|
|
parseBody: for (int i = 0; i < statements.length; i++) {
|
|
System.out.println("stmt at line " + statements[i].beginLine);
|
|
System.out.println(statements[i].getClass().getName());
|
|
|
|
// look for static attributes (=assertions inside class body)
|
|
if (statements[i] instanceof Assign) {
|
|
Assign assign = (Assign) statements[i];
|
|
exprType left = assign.targets[0];
|
|
exprType right = assign.value;
|
|
|
|
String assignTo = ((Name)left).id;
|
|
String assignVal = "";
|
|
|
|
assignVal = ParseHelpers.getStringOfExpr(right);
|
|
System.out.println("attrs:");
|
|
System.out.println(right.getClass().getName());
|
|
System.out.println(assignVal);
|
|
if (right instanceof Call) {
|
|
Call call = (Call) right;
|
|
String callName =(((Name)call.func).id);
|
|
if (callName.equals("staticmethod"))
|
|
continue parseBody;
|
|
}
|
|
Property classAttr = cl.createOwnedAttribute(assignTo, null);
|
|
classAttr.setIsStatic(true);
|
|
classAttr.setDefault(assignVal);
|
|
}
|
|
// get method definitions
|
|
if (statements[i] instanceof FunctionDef) {
|
|
FunctionDef func = (FunctionDef) statements[i];
|
|
String funcName=((NameTok)func.name).id;
|
|
exprType[] argList = func.args.args;
|
|
EList<String> paramNameList = new BasicEList<String>();
|
|
EList<Type> paramTypeList = new BasicEList<Type>();
|
|
|
|
// get arguments
|
|
for (exprType arg : argList) {
|
|
Name n = (Name) arg;
|
|
paramNameList.add(n.id);
|
|
paramTypeList.add(null);
|
|
System.out.println(n.id);
|
|
}
|
|
// create model element
|
|
Operation op = cl.createOwnedOperation(funcName, paramNameList, null);
|
|
// set static method (if so)
|
|
if (argList.length == 0 || (! ((Name) argList[0]).id.equals("self")))
|
|
op.setIsStatic(true);
|
|
|
|
// get object variables, if this is the __init__ method
|
|
if (funcName.equals("__init__")){
|
|
stmtType[] initStmts = func.body;
|
|
for (stmtType initStmt: initStmts) {
|
|
if (initStmt instanceof Assign) {
|
|
Assign assign = (Assign) initStmt;
|
|
exprType left = assign.targets[0];
|
|
exprType right = assign.value;
|
|
if (left instanceof Attribute) {
|
|
Attribute attrLeft = (Attribute) left;
|
|
String attrName = ((NameTok)attrLeft.attr).id;
|
|
String attrVal = ParseHelpers.getStringOfExpr(right);
|
|
Property att = cl.createOwnedAttribute(attrName, null);
|
|
att.setDefault(attrVal);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class Tuple<A,B>{
|
|
A a;
|
|
B b;
|
|
public Tuple(A a, B b) {
|
|
this.a=a;
|
|
this.b=b;
|
|
}
|
|
public String toString() {
|
|
return "(<"+this.a+">,<"+this.b+">)";
|
|
}
|
|
}
|
|
}
|