/*
* Copyright (C) 2006, 2007 Dennis Hunziker, Ueli Kistler
* Copyright (C) 2007 Reto Schuettel, Robin Stocker
*
* IFS Institute for Software, HSR Rapperswil, Switzerland
*
*/
package org.python.pydev.refactoring.ast.visitors;
import java.io.File;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.python.pydev.core.IGrammarVersionProvider;
import org.python.pydev.core.IModule;
import org.python.pydev.core.IModulesManager;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.ISourceModule;
import org.python.pydev.core.MisconfigurationException;
import org.python.pydev.editor.codecompletion.revisited.modules.SourceModule;
import org.python.pydev.parser.PyParser;
import org.python.pydev.parser.jython.ParseException;
import org.python.pydev.parser.jython.SimpleNode;
import org.python.pydev.parser.jython.TokenMgrError;
import org.python.pydev.parser.jython.ast.Module;
import org.python.pydev.parser.jython.ast.VisitorIF;
import org.python.pydev.parser.jython.ast.exprType;
import org.python.pydev.refactoring.ast.PythonModuleManager;
import org.python.pydev.refactoring.ast.adapters.AbstractNodeAdapter;
import org.python.pydev.refactoring.ast.adapters.AbstractScopeNode;
import org.python.pydev.refactoring.ast.adapters.ModuleAdapter;
import org.python.pydev.refactoring.ast.visitors.context.AbstractContextVisitor;
import org.python.pydev.refactoring.ast.visitors.selection.SelectionException;
import org.python.pydev.refactoring.ast.visitors.selection.SelectionExtenderVisitor;
import org.python.pydev.refactoring.ast.visitors.selection.SelectionValidationVisitor;
import org.python.pydev.ui.filetypes.FileTypesPreferencesPage;
import com.aptana.shared_core.io.FileUtils;
import com.aptana.shared_core.structure.Tuple;
public final class VisitorFactory {
private VisitorFactory() {
}
public static ITextSelection createSelectionExtension(AbstractScopeNode<?> scope, ITextSelection selection) {
SelectionExtenderVisitor visitor = null;
try {
visitor = new SelectionExtenderVisitor(scope.getModule(), selection);
scope.getASTNode().accept(visitor);
} catch (Exception e) {
throw new RuntimeException(e);
}
return visitor.getSelection();
}
public static void validateSelection(ModuleAdapter scope) throws SelectionException {
SelectionValidationVisitor visitor = null;
try {
visitor = new SelectionValidationVisitor();
scope.getASTNode().accept(visitor);
} catch (SelectionException e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static <T extends VisitorIF> T createVisitor(Class<T> visitorClass, String source,
IGrammarVersionProvider versionProvider) throws Throwable {
return createVisitor(visitorClass, getRootNodeFromString(source, versionProvider));
}
public static <T extends VisitorIF> T createVisitor(Class<T> visitorClass, SimpleNode root) {
T visitor = null;
try {
visitor = visitorClass.newInstance();
root.accept(visitor);
} catch (Throwable e) {
throw new RuntimeException(e);
}
return visitor;
}
/**
* Unchecked (because if doing Class.cast, it does not work in java 1.4)
*/
@SuppressWarnings("unchecked")
public static <T extends AbstractContextVisitor> T createContextVisitor(Class<T> visitorClass, SimpleNode root,
ModuleAdapter module, AbstractNodeAdapter parent) {
try {
T visitor = (T) visitorClass.getConstructors()[0].newInstance(new Object[] { module, parent });
root.accept(visitor);
return visitor;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ModuleAdapter createModuleAdapter(PythonModuleManager pythonModuleManager, File file, IDocument doc,
IPythonNature nature, IGrammarVersionProvider versionProvider) throws Throwable {
if (file != null && file.exists()) {
if (FileTypesPreferencesPage.isCythonFile(file.getName())) {
versionProvider = new IGrammarVersionProvider() {
public int getGrammarVersion() throws MisconfigurationException {
return IPythonNature.GRAMMAR_PYTHON_VERSION_CYTHON;
}
};
}
if (pythonModuleManager != null) {
IModulesManager modulesManager = pythonModuleManager.getIModuleManager();
if (modulesManager != null) {
String modName = modulesManager.resolveModule(FileUtils.getFileAbsolutePath(file));
if (modName != null) {
IModule module = modulesManager.getModule(modName, nature, true);
if (module instanceof ISourceModule) {
SourceModule iSourceModule = (SourceModule) module;
if (iSourceModule.parseError != null) {
throw iSourceModule.parseError;
}
return new ModuleAdapter(pythonModuleManager, ((ISourceModule) module), nature, doc);
}
}
}
}
}
return new ModuleAdapter(pythonModuleManager, file, doc, getRootNode(doc, versionProvider), nature);
}
public static SimpleNode getRootNodeFromString(String source, IGrammarVersionProvider versionProvider)
throws ParseException, MisconfigurationException {
return getRootNode(getDocumentFromString(source), versionProvider);
}
private static IDocument getDocumentFromString(String source) {
return new Document(source);
}
public static Module getRootNode(IDocument doc, IGrammarVersionProvider versionProvider) throws ParseException,
MisconfigurationException {
Tuple<SimpleNode, Throwable> objects = PyParser.reparseDocument(new PyParser.ParserInfo(doc, versionProvider
.getGrammarVersion()));
Throwable exception = objects.o2;
if (exception != null) {
/* We try to get rid of the 'Throwable' exception, if possible */
if (exception instanceof ParseException) {
throw (ParseException) exception;
} else if (exception instanceof TokenMgrError) {
/* Error from Lexer */
throw new ParseException(exception.toString());
} else {
throw new RuntimeException(exception);
}
}
if (objects.o2 != null)
throw new RuntimeException(objects.o2);
return (Module) objects.o1;
}
/**
* Provides a way to find duplicates of a given expression.
*/
public static FindDuplicatesVisitor createDuplicatesVisitor(ITextSelection selection, SimpleNode nodeToVisit,
exprType expression, AbstractScopeNode node, IDocument doc) {
FindDuplicatesVisitor visitor = new FindDuplicatesVisitor(selection, expression, doc);
try {
nodeToVisit.accept(visitor);
visitor.finish();
} catch (Throwable e) {
throw new RuntimeException(e);
}
return visitor;
}
}