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 classDict; // list of generalizations to add to model // after adding all classes private List> generalizations; public Py2UMLCreator() { this.classDict = new Hashtable(); this.generalizations = new Vector>(); } 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 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(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(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 paramNameList = new BasicEList(); EList paramTypeList = new BasicEList(); // 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 a; B b; public Tuple(A a, B b) { this.a=a; this.b=b; } public String toString() { return "(<"+this.a+">,<"+this.b+">)"; } } }