167 lines
4.7 KiB
Java
Executable File
167 lines
4.7 KiB
Java
Executable File
package pyUML.pythonTree;
|
|
|
|
import java.io.File;
|
|
import java.util.List;
|
|
import java.util.Vector;
|
|
|
|
import org.eclipse.core.runtime.IPath;
|
|
import org.python.pydev.parser.jython.SimpleNode;
|
|
import org.python.pydev.parser.jython.ast.ClassDef;
|
|
import org.python.pydev.parser.jython.ast.Module;
|
|
import org.python.pydev.parser.jython.ast.stmtType;
|
|
import org.python.pydev.refactoring.ast.visitors.VisitorFactory;
|
|
|
|
import pyUML.backend.EclipseHelperMethods;
|
|
import pyUML.backend.ParseHelpers;
|
|
import pyUML.exceptions.PyUMLCancelledException;
|
|
import pyUML.exceptions.PyUMLParseException;
|
|
|
|
|
|
|
|
/**
|
|
* This class represents a Python file in the Python
|
|
* Package structure.
|
|
* It must have a parent package and contains a
|
|
* pydev Abstract Syntax Tree (AST)
|
|
*
|
|
*/
|
|
public class PythonTreeFile extends PythonTreeNode{
|
|
private IPath filePath;
|
|
private PythonTreePackage parent;
|
|
private SimpleNode ast;
|
|
private List<PythonTreeClass> classesInFile;
|
|
private String fileContent;
|
|
private String[] splittedFileContent = null;
|
|
|
|
|
|
public PythonTreeFile(IPath filePath, PythonTreePackage parent) throws PyUMLParseException, PyUMLCancelledException{
|
|
super(parent);
|
|
this.filePath = filePath;
|
|
this.parent = parent;
|
|
this.name = filePath.lastSegment();
|
|
|
|
this.classesInFile = new Vector<PythonTreeClass>();
|
|
this.initAst();
|
|
this.initClassesWithAST();
|
|
}
|
|
|
|
/**
|
|
* Parses the given Python file and saves the ast
|
|
*/
|
|
private void initAst() throws PyUMLParseException{
|
|
// init AST so that it will never be null
|
|
this.ast=new SimpleNode();
|
|
// try to get content of python file
|
|
this.fileContent = ParseHelpers.fileToString(
|
|
new File(filePath.toOSString()), this.getProject());
|
|
if (this.fileContent==null) {
|
|
return;
|
|
}
|
|
|
|
// get AST of file
|
|
try{
|
|
this.ast = VisitorFactory.getRootNodeFromString(this.fileContent);
|
|
} catch (Throwable t) {
|
|
String message = t.getClass().getName()+ " while parsing file "
|
|
+ this.filePath.toOSString() +"\n\n" +t.getMessage();
|
|
throw new PyUMLParseException(message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* extracts all the top level clases (no inner classes)
|
|
* out of the AST
|
|
*/
|
|
private void initClassesWithAST() throws PyUMLParseException, PyUMLCancelledException{
|
|
if (this.ast instanceof Module) {
|
|
Module pyModule = (Module) this.ast;
|
|
stmtType[] statements = pyModule.body;
|
|
for (int i = 0; i < statements.length; i++) {
|
|
if (statements[i] instanceof ClassDef) {
|
|
// get end line of class -> look for following statement
|
|
int followingLine = 0;
|
|
if (i +1 < statements.length) {
|
|
stmtType followingStmt = statements[i+1];
|
|
followingLine = followingStmt.beginLine;
|
|
}
|
|
ClassDef pyClass = (ClassDef) statements[i];
|
|
PythonTreeClass cl = new PythonTreeClass(this.parent, this, pyClass, followingLine-1);
|
|
this.classesInFile.add(cl);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void updateFileInEclipse() {
|
|
EclipseHelperMethods.updateFile(this.getFilePath().toOSString(), this.getProject());
|
|
}
|
|
|
|
/**
|
|
* re-inits a file -> re-parses the content
|
|
* and adds new classes, if needed.
|
|
* @throws PyUMLParseException
|
|
*/
|
|
public void reInitFile() throws PyUMLParseException, PyUMLCancelledException {
|
|
for (PythonTreeClass cl : this.getClassesInFile()) {
|
|
this.getRoot().getClassDict().remove(cl.getPackageStructure()+cl.getName());
|
|
this.getRoot().getClassNameDict().remove(cl.getPackageStructure()+cl.getName());
|
|
this.getParent().getChildClasses().remove(cl);
|
|
}
|
|
|
|
this.splittedFileContent=null;
|
|
this.classesInFile = new Vector<PythonTreeClass>();
|
|
this.initAst();
|
|
this.initClassesWithAST();
|
|
this.getParent().getChildClasses().addAll(this.getClassesInFile());
|
|
this.getRoot().getChildClasses().addAll(this.getParent().getChildClasses());
|
|
|
|
}
|
|
|
|
/**
|
|
* Splits the file content by "\n", which results in an array of lines.
|
|
* The result is cached for performance reasons.
|
|
* @return an Array containing the lines of the file content
|
|
*/
|
|
public String[] getSplittedFileContent() {
|
|
if (splittedFileContent == null)
|
|
splittedFileContent = fileContent.split("\n");
|
|
return splittedFileContent;
|
|
}
|
|
|
|
public IPath getFilePath() {
|
|
return filePath;
|
|
}
|
|
public SimpleNode getAst() {
|
|
return ast;
|
|
}
|
|
public PythonTreePackage getParent() {
|
|
return parent;
|
|
}
|
|
|
|
public List<PythonTreeClass> getClassesInFile() {
|
|
return classesInFile;
|
|
}
|
|
|
|
/**
|
|
* @return the content of the whole file as a String
|
|
*/
|
|
public String getFileContent() {
|
|
return fileContent;
|
|
}
|
|
|
|
/**
|
|
* Set this objects "file content" string. This does *not*
|
|
* update any real file!
|
|
* @param fileContent the file content as a String
|
|
*/
|
|
public void setFileContent(String fileContent) {
|
|
this.fileContent = fileContent;
|
|
this.splittedFileContent=null;
|
|
}
|
|
|
|
public void setFilePath(IPath filePath) {
|
|
this.filePath = filePath;
|
|
}
|
|
}
|
|
|