use of org.python.pydev.ast.codecompletion.revisited.modules.SourceModule in project Pydev by fabioz.
the class AnalysisBuilderRunnable method doAnalysis.
@Override
protected void doAnalysis() {
if (!nature.startRequests()) {
return;
}
try {
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "doAnalysis() - " + moduleName + " " + this.getAnalysisCauseStr());
}
// if the resource is not open, there's not much we can do...
final IResource r = resource;
if (r == null) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Finished analysis -- resource null -- " + moduleName);
return;
}
if (!r.getProject().isOpen()) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Finished analysis -- project closed -- " + moduleName);
return;
}
AnalysisRunner runner = new AnalysisRunner();
checkStop();
IAnalysisPreferences analysisPreferences = new AnalysisPreferences(r);
boolean makeAnalysis = // just get problems in resources that are in the pythonpath
runner.canDoAnalysis(document) && PyDevBuilderVisitor.isInPythonPath(r) && analysisPreferences.makeCodeAnalysis();
boolean anotherVisitorRequiresAnalysis = false;
for (IExternalCodeAnalysisVisitor visitor : allVisitors) {
anotherVisitorRequiresAnalysis |= visitor.getRequiresAnalysis();
}
if (!makeAnalysis) {
// let's see if we should do code analysis
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Skipping: !makeAnalysis -- " + moduleName);
}
if (!anotherVisitorRequiresAnalysis) {
AnalysisRunner.deleteMarkers(r);
return;
} else {
// Only delete pydev markers (others will be deleted by the respective visitors later on).
boolean onlyPydevAnalysisMarkers = true;
AnalysisRunner.deleteMarkers(r, onlyPydevAnalysisMarkers);
}
}
if (makeAnalysis && onlyRecreateCtxInsensitiveInfo) {
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Skipping: !forceAnalysis && analysisCause == ANALYSIS_CAUSE_BUILDER && " + "PyDevBuilderPrefPage.getAnalyzeOnlyActiveEditor() -- " + moduleName);
}
return;
}
if (nature == null) {
Log.log("Finished analysis: null nature -- " + moduleName);
return;
}
AbstractAdditionalTokensInfo info = AdditionalProjectInterpreterInfo.getAdditionalInfoForProject(nature);
if (info == null) {
Log.log("Unable to get additional info for: " + r + " -- " + moduleName);
return;
}
if (makeAnalysis && DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "makeAnalysis:" + makeAnalysis + " " + "analysisCause: " + getAnalysisCauseStr() + " -- " + moduleName);
}
checkStop();
if (isHierarchicallyDerived(r)) {
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Resource marked as derived not analyzed: " + r + " -- " + moduleName);
}
// might be already there)
if (r != null) {
AnalysisRunner.deleteMarkers(r);
}
return;
}
// Maybe we can improve that when https://github.com/PyCQA/pylint/pull/1189 is done.
if (!DocumentChanged.hasDocumentChanged(resource, document)) {
for (IExternalCodeAnalysisVisitor visitor : allVisitors) {
visitor.startVisit();
}
} else {
for (IExternalCodeAnalysisVisitor visitor : allVisitors) {
visitor.deleteMarkers();
}
if (!makeAnalysis) {
return;
}
}
List<MarkerInfo> markersFromCodeAnalysis = null;
if (makeAnalysis) {
OccurrencesAnalyzer analyzer = new OccurrencesAnalyzer();
checkStop();
SourceModule module = (SourceModule) this.module.call(moduleRequest);
IMessage[] messages = analyzer.analyzeDocument(nature, module, analysisPreferences, document, this.internalCancelMonitor, DefaultIndentPrefs.get(this.resource));
checkStop();
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Adding markers for module: " + moduleName);
// for (IMessage message : messages) {
// Log.toLogFile(this, message.toString());
// }
}
// last chance to stop...
checkStop();
// don't stop after setting to add / remove the markers
if (r != null) {
boolean analyzeOnlyActiveEditor = PyDevBuilderPreferences.getAnalyzeOnlyActiveEditor();
if (forceAnalysis || !analyzeOnlyActiveEditor || (analyzeOnlyActiveEditor && (!PyDevBuilderPreferences.getRemoveErrorsWhenEditorIsClosed() || OpenEditors.isEditorOpenForResource(r)))) {
markersFromCodeAnalysis = runner.setMarkers(r, document, messages, this.internalCancelMonitor);
} else {
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "Skipped adding markers for module: " + moduleName + " (editor not opened).");
}
}
}
}
// if there are callbacks registered, call them if we still didn't return (mostly for tests)
for (ICallback<Object, IResource> callback : analysisBuilderListeners) {
try {
callback.call(r);
} catch (Exception e) {
Log.log(e);
}
}
checkStop();
for (IExternalCodeAnalysisVisitor visitor : allVisitors) {
visitor.join();
}
checkStop();
if (r != null) {
for (IExternalCodeAnalysisVisitor visitor : allVisitors) {
String problemMarker = visitor.getProblemMarkerId();
String messageId = visitor.getMessageId();
List<MarkerInfo> markersFromVisitor = visitor.getMarkers(resource);
if (markersFromVisitor != null && markersFromVisitor.size() > 0) {
Map<Integer, List<MarkerInfo>> lineToMarkerInfo = new HashMap<>();
if (markersFromCodeAnalysis != null) {
for (MarkerInfo codeAnalysisMarkerInfo : markersFromCodeAnalysis) {
List<MarkerInfo> list = lineToMarkerInfo.get(codeAnalysisMarkerInfo.lineStart);
if (list == null) {
list = new ArrayList<>(2);
lineToMarkerInfo.put(codeAnalysisMarkerInfo.lineStart, list);
}
list.add(codeAnalysisMarkerInfo);
}
}
if (visitor == pyLintVisitor) {
// (there's no real point in putting an error twice).
for (Iterator<MarkerInfo> visitorMarkerInfoIterator = markersFromVisitor.iterator(); visitorMarkerInfoIterator.hasNext(); ) {
MarkerInfo visitorMarkerInfo = visitorMarkerInfoIterator.next();
List<MarkerInfo> codeAnalysisMarkers = lineToMarkerInfo.get(visitorMarkerInfo.lineStart);
if (codeAnalysisMarkers != null && codeAnalysisMarkers.size() > 0) {
for (MarkerInfo codeAnalysisMarker : codeAnalysisMarkers) {
if (codeAnalysisMarker.severity < IMarker.SEVERITY_INFO) {
// Don't consider if it shouldn't be shown.
continue;
}
Map<String, Object> additionalInfo = codeAnalysisMarker.additionalInfo;
if (additionalInfo != null) {
Object analysisType = additionalInfo.get(AnalysisRunner.PYDEV_ANALYSIS_TYPE);
if (analysisType != null && analysisType instanceof Integer) {
String pyLintMessageId = CheckAnalysisErrors.getPyLintMessageIdForPyDevAnalysisType((int) analysisType);
if (pyLintMessageId != null && pyLintMessageId.equals(visitorMarkerInfo.additionalInfo.get(messageId))) {
visitorMarkerInfoIterator.remove();
// Stop the for (we've already removed it).
break;
}
}
}
}
}
}
}
PyMarkerUtils.replaceMarkers(markersFromVisitor, resource, problemMarker, true, this.internalCancelMonitor);
} else {
visitor.deleteMarkers();
}
}
}
} catch (OperationCanceledException e) {
// ok, ignore it
logOperationCancelled();
} catch (Exception e) {
Log.log(e);
} finally {
try {
nature.endRequests();
} catch (Throwable e) {
Log.log("Error when analyzing: " + moduleName, e);
}
try {
AnalysisBuilderRunnableFactory.removeFromThreads(key, this);
} catch (Throwable e) {
Log.log(e);
}
dispose();
}
}
use of org.python.pydev.ast.codecompletion.revisited.modules.SourceModule in project Pydev by fabioz.
the class AnalysisBuilderVisitor method visitChangedResource.
public void visitChangedResource(final IResource resource, final ICallback0<IDocument> document, final IProgressMonitor monitor, boolean forceAnalysis) {
// we may need to 'force' the analysis when a module is renamed, because the first message we receive is
// a 'delete' and after that an 'add' -- which is later mapped to this method, so, if we don't have info
// on the module we should analyze it because it is 'probably' a rename.
final PythonNature nature = getPythonNature(resource);
if (nature == null) {
return;
}
// Put things from the memo to final variables as we might need them later on and we cannot get them from
// the memo later.
final String moduleName;
final SourceModule[] module = new SourceModule[] { null };
final IDocument doc;
doc = document.call();
if (doc == null) {
return;
}
try {
moduleName = getModuleName(resource, nature);
} catch (MisconfigurationException e) {
Log.log(e);
return;
}
// depending on the level of analysis we have to do, we'll decide whether we want
// to make the full parse (slower) or the definitions parse (faster but only with info
// related to the definitions)
ICallback<IModule, Integer> moduleCallback = new ICallback<IModule, Integer>() {
@Override
public IModule call(Integer arg) {
if (arg == IAnalysisBuilderRunnable.FULL_MODULE) {
if (module[0] != null) {
return module[0];
} else {
try {
module[0] = getSourceModule(resource, doc, nature);
} catch (MisconfigurationException e1) {
throw new RuntimeException(e1);
}
if (module[0] != null) {
return module[0];
}
try {
module[0] = createSoureModule(resource, doc, moduleName);
} catch (MisconfigurationException e) {
throw new RuntimeException(e);
}
return module[0];
}
} else if (arg == IAnalysisBuilderRunnable.DEFINITIONS_MODULE) {
if (DebugSettings.DEBUG_ANALYSIS_REQUESTS) {
org.python.pydev.shared_core.log.ToLogFile.toLogFile(this, "PyDevBuilderPrefPage.getAnalyzeOnlyActiveEditor()");
}
IFile f = (IFile) resource;
IPath location = f.getLocation();
if (location != null) {
String file = location.toOSString();
File f2 = new File(file);
return new SourceModule(moduleName, f2, FastDefinitionsParser.parse(doc.get(), moduleName, f2), null, nature);
}
return null;
} else {
throw new RuntimeException("Unexpected parameter: " + arg);
}
}
};
long documentTime = this.getDocumentTime();
if (documentTime == -1) {
Log.log("Warning: The document time in the visitor is -1. Changing for current time.");
documentTime = System.currentTimeMillis();
}
doVisitChangedResource(nature, resource, doc, moduleCallback, null, monitor, forceAnalysis, AnalysisBuilderRunnable.ANALYSIS_CAUSE_BUILDER, documentTime, false);
}
use of org.python.pydev.ast.codecompletion.revisited.modules.SourceModule in project Pydev by fabioz.
the class TddQuickFixParticipant method addProps.
@Override
public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPreferences analysisPreferences, String line, PySelection ps, int offset, IPythonNature nature, PyEdit edit, List<ICompletionProposalHandle> props) throws BadLocationException, CoreException {
if (nature == null) {
return;
}
ICodeCompletionASTManager astManager = nature.getAstManager();
if (astManager == null) {
return;
}
if (markerAnnotation.position == null) {
return;
}
IMarker marker = markerAnnotation.markerAnnotation.getMarker();
Integer id = (Integer) marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE);
int start = markerAnnotation.position.offset;
int end = start + markerAnnotation.position.length;
ps.setSelection(start, end);
String markerContents;
try {
markerContents = ps.getSelectedText();
} catch (Exception e1) {
// Selection may be wrong.
return;
}
IDocument doc = ps.getDoc();
List<String> parametersAfterCall = ps.getParametersAfterCall(end);
switch(id) {
case IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE:
addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall);
addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall);
break;
case IAnalysisPreferences.TYPE_UNDEFINED_IMPORT_VARIABLE:
// Say we had something as:
// import sys
// sys.Bar
// in which case 'Bar' is undefined
// in this situation, the activationTokenAndQual would be "sys." and "Bar"
// and we want to get the definition for "sys"
String[] activationTokenAndQual = ps.getActivationTokenAndQualifier(true);
if (activationTokenAndQual[0].endsWith(".")) {
ArrayList<IDefinition> selected = findDefinitions(nature, edit, start - 2, doc);
for (IDefinition iDefinition : selected) {
IModule module = iDefinition.getModule();
if (module.getFile() != null) {
Definition definition = (Definition) iDefinition;
File file = module.getFile();
if (definition.ast == null) {
// if we have no ast in the definition, it means the module itself was found (global scope)
// Add option to create class at the given module!
addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall, file);
addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall, file);
} else if (definition.ast instanceof ClassDef) {
ClassDef classDef = (ClassDef) definition.ast;
// Ok, we should create a field or method in this case (accessing a classmethod or staticmethod)
PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField();
String className = NodeUtils.getNameFromNameTok(classDef.name);
pyCreateMethod.setCreateInClass(className);
pyCreateMethod.setCreateAs(PyCreateMethodOrField.CLASSMETHOD);
addCreateClassmethodOption(ps, edit, props, markerContents, parametersAfterCall, pyCreateMethod, file, className);
}
}
}
}
break;
case IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT:
// This case is the following: from other_module4 import Foo
// with 'Foo' being undefined.
// So, we have to suggest creating a Foo class/method in other_module4
PyImportsHandling importsHandling = new PyImportsHandling(ps.getDoc(), false);
int offsetLine = ps.getLineOfOffset(start);
String selectedText = ps.getSelectedText();
Tuple<IModule, String> found = null;
String foundFromImportStr = null;
boolean isImportFrom = false;
OUT: for (ImportHandle handle : importsHandling) {
if (handle.startFoundLine == offsetLine || handle.endFoundLine == offsetLine || (handle.startFoundLine < offsetLine && handle.endFoundLine > offsetLine)) {
List<ImportHandleInfo> importInfo = handle.getImportInfo();
for (ImportHandleInfo importHandleInfo : importInfo) {
String fromImportStr = importHandleInfo.getFromImportStr();
List<String> importedStr = importHandleInfo.getImportedStr();
for (String imported : importedStr) {
if (selectedText.equals(imported)) {
if (fromImportStr != null) {
foundFromImportStr = fromImportStr + "." + imported;
isImportFrom = true;
} else {
// if fromImportStr == null, it's not a from xxx import yyy (i.e.: simple import)
foundFromImportStr = imported;
}
try {
String currentModule = nature.resolveModule(edit.getEditorFile());
ICompletionState state = CompletionStateFactory.getEmptyCompletionState(nature, new CompletionCache());
found = nature.getAstManager().findModule(foundFromImportStr, currentModule, state, new SourceModule(currentModule, edit.getEditorFile(), edit.getAST(), null, nature));
} catch (Exception e) {
Log.log(e);
}
break OUT;
}
}
}
break OUT;
}
}
boolean addOptionToCreateClassOrMethod = isImportFrom;
if (found != null && found.o1 != null) {
// or just create a class or method at the end.
if (found.o1 instanceof SourceModule) {
// if all was found, there's nothing left to create.
if (found.o2 != null && found.o2.length() > 0) {
SourceModule sourceModule = (SourceModule) found.o1;
File file = sourceModule.getFile();
if (found.o2.indexOf('.') != -1) {
// We have to create some intermediary structure.
if (!addOptionToCreateClassOrMethod) {
// Cannot create class or method from the info (only the module structure).
if (sourceModule.getName().endsWith(".__init__")) {
File f = getFileStructure(file.getParentFile(), found.o2);
addCreateModuleOption(ps, edit, props, markerContents, f);
}
} else {
// Ok, the leaf may be a class or method.
if (sourceModule.getName().endsWith(".__init__")) {
String moduleName = FullRepIterable.getWithoutLastPart(sourceModule.getName());
String withoutLastPart = FullRepIterable.getWithoutLastPart(found.o2);
moduleName += "." + withoutLastPart;
String classOrMethodName = FullRepIterable.getLastPart(found.o2);
File f = getFileStructure(file.getParentFile(), withoutLastPart);
addCreateClassInNewModuleOption(ps, edit, props, classOrMethodName, moduleName, parametersAfterCall, f);
addCreateMethodInNewModuleOption(ps, edit, props, classOrMethodName, moduleName, parametersAfterCall, f);
}
}
} else {
// Ok, it's all there, we just have to create the leaf.
if (!addOptionToCreateClassOrMethod || sourceModule.getName().endsWith(".__init__")) {
// Cannot create class or method from the info (only the module structure).
if (sourceModule.getName().endsWith(".__init__")) {
File f = new File(file.getParent(), found.o2 + FileTypesPreferences.getDefaultDottedPythonExtension());
addCreateModuleOption(ps, edit, props, markerContents, f);
}
} else {
// Ok, the leaf may be a class or method.
addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall, file);
addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall, file);
}
}
}
}
} else if (foundFromImportStr != null) {
// We couldn't find anything there, so, we have to create the modules structure as needed and
// maybe create a class or module at the end (but only if it's an import from).
// Ok, it's all there, we just have to create the leaf.
// Discover the source folder where we should create the structure.
File editorFile = edit.getEditorFile();
String onlyProjectPythonPathStr = nature.getPythonPathNature().getOnlyProjectPythonPathStr(false);
List<String> split = StringUtils.splitAndRemoveEmptyTrimmed(onlyProjectPythonPathStr, '|');
for (int i = 0; i < split.size(); i++) {
String fullPath = FileUtils.getFileAbsolutePath(split.get(i));
fullPath = PythonPathHelper.getDefaultPathStr(fullPath);
split.set(i, fullPath);
}
HashSet<String> projectSourcePath = new HashSet<String>(split);
if (projectSourcePath.size() == 0) {
// No source folder for editor... this shouldn't happen (code analysis wouldn't even run on it).
return;
}
String fullPath = FileUtils.getFileAbsolutePath(editorFile);
fullPath = PythonPathHelper.getDefaultPathStr(fullPath);
String foundSourceFolderFullPath = null;
if (projectSourcePath.size() == 1) {
foundSourceFolderFullPath = projectSourcePath.iterator().next();
} else {
for (String string : projectSourcePath) {
if (fullPath.startsWith(string)) {
// Use this as the source folder
foundSourceFolderFullPath = string;
break;
}
}
}
if (foundSourceFolderFullPath != null) {
if (!addOptionToCreateClassOrMethod) {
// Cannot create class or method from the info (only the module structure).
File f = getFileStructure(new File(foundSourceFolderFullPath), foundFromImportStr);
addCreateModuleOption(ps, edit, props, foundFromImportStr, f);
} else {
// Ok, the leaf may be a class or method.
String moduleName = FullRepIterable.getWithoutLastPart(foundFromImportStr);
File file = getFileStructure(new File(foundSourceFolderFullPath), moduleName);
String lastPart = FullRepIterable.getLastPart(foundFromImportStr);
addCreateClassInNewModuleOption(ps, edit, props, lastPart, moduleName, parametersAfterCall, file);
addCreateMethodInNewModuleOption(ps, edit, props, lastPart, moduleName, parametersAfterCall, file);
}
}
}
break;
}
}
use of org.python.pydev.ast.codecompletion.revisited.modules.SourceModule in project Pydev by fabioz.
the class MatchImportsVisitorTest method testMatchImports2.
public void testMatchImports2() throws Exception {
Document doc = new Document("" + // rename a.b.c
"import a.b.c.d\n" + // rename a.b.c
"import a.b.c\n" + "import a.b\n" + "");
IPythonNature nature = new PythonNatureStub();
ParseOutput obj = PyParser.reparseDocument(new PyParser.ParserInfo(doc, nature));
SourceModule module = (SourceModule) AbstractModule.createModule((SimpleNode) obj.ast, null, "z", null);
MatchImportsVisitor visitor = new MatchImportsVisitor(nature, "a.b.c", module, null);
module.getAst().accept(visitor);
assertEquals(visitor.importsMatchingOnAliasPart.size(), 2);
assertEquals(visitor.occurrences.size(), 2);
}
use of org.python.pydev.ast.codecompletion.revisited.modules.SourceModule in project Pydev by fabioz.
the class RefactoringRenameTestBase method setUp.
/**
* In the setUp, it initializes the files in the refactoring project
* @see com.python.pydev.analysis.refactoring.refactorer.refactorings.renamelocal.RefactoringLocalTestBase#setUp()
*/
@Override
public void setUp() throws Exception {
super.setUp();
if (filesInRefactoringProject == null) {
filesInRefactoringProject = PyFileListing.getPyFilesBelow(new File(TestDependent.TEST_COM_REFACTORING_PYSRC_LOC), new NullProgressMonitor(), true).getFoundPyFileInfos();
ArrayList<Tuple<List<ModulesKey>, IPythonNature>> iFiles = new ArrayList<Tuple<List<ModulesKey>, IPythonNature>>();
List<ModulesKey> modules = new ArrayList<ModulesKey>();
iFiles.add(new Tuple<List<ModulesKey>, IPythonNature>(modules, natureRefactoring));
FastStringBuffer tempBuf = new FastStringBuffer();
for (PyFileInfo info : filesInRefactoringProject) {
File f = info.getFile();
String modName = info.getModuleName(tempBuf);
ModulesKey modulesKey = new ModulesKey(modName, f);
modules.add(modulesKey);
SourceModule mod = (SourceModule) AbstractModule.createModule(modName, f, natureRefactoring, true);
// also create the additional info so that it can be used for finds
AbstractAdditionalTokensInfo additionalInfo = AdditionalProjectInterpreterInfo.getAdditionalInfoForProject(natureRefactoring);
additionalInfo.addAstInfo(mod.getAst(), modulesKey, false);
}
// RefactorerFindReferences.FORCED_RETURN = iFiles;
}
setUpConfigWorkspaceFiles();
}
Aggregations