use of org.python.pydev.shared_core.structure.FastStack in project Pydev by fabioz.
the class SourceModule method findDefinition.
/**
* @param line: starts at 1
* @param col: starts at 1
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Definition[] findDefinition(ICompletionState state, int line, int col, final IPythonNature nature, Set innerFindPaths) throws Exception {
state.checkMaxTimeForCompletion();
if (onFindDefinition != null) {
onFindDefinition.call(state);
}
final String actTok = state.getActivationToken();
Object key = new Tuple3("findDefinition", this.getName(), actTok);
if (!innerFindPaths.add(key)) {
// So, we can't go on this way as it'd recurse!
return new Definition[0];
}
if (actTok.length() == 0) {
// No activation token means the module itself.
return new Definition[] { new Definition(1, 1, "", null, null, this) };
}
// the line passed in starts at 1 and the lines for the visitor start at 0
ArrayList<Definition> toRet = new ArrayList<Definition>();
// first thing is finding its scope
FindScopeVisitor scopeVisitor = getScopeVisitor(line, col);
Object objClassDef = scopeVisitor.scope.getClassDef();
if (objClassDef instanceof ClassDef) {
ClassDef classDef = (ClassDef) objClassDef;
if (actTok.equals("super")) {
if (classDef.bases != null) {
List<Definition> lst = new ArrayList<>(classDef.bases.length);
for (exprType expr : classDef.bases) {
String repr = NodeUtils.getRepresentationString(expr);
if (repr != null) {
state = state.getCopyWithActTok(repr);
Definition[] defs = findDefinition(state, line, col, nature);
if (defs != null && defs.length > 0) {
lst.addAll(Arrays.asList(defs));
}
}
}
if (lst.size() > 0) {
return lst.toArray(new Definition[lst.size()]);
}
}
// Didn't find anything for super
return new Definition[0];
} else if (actTok.startsWith("super()")) {
if (classDef.bases != null) {
List<Definition> lst = new ArrayList<>(classDef.bases.length);
for (exprType expr : classDef.bases) {
String repr = NodeUtils.getRepresentationString(expr);
if (repr != null) {
state = state.getCopyWithActTok(actTok.replace("super()", repr));
Definition[] defs = findDefinition(state, line, col, nature);
if (defs != null && defs.length > 0) {
lst.addAll(Arrays.asList(defs));
}
}
}
if (lst.size() > 0) {
return lst.toArray(new Definition[lst.size()]);
}
}
// Just keep going (may get completions globally).
}
}
// this visitor checks for assigns for the token
FindDefinitionModelVisitor visitor = getFindDefinitionsScopeVisitor(actTok, line, col, nature);
List<Definition> defs = visitor.definitions;
int size = defs.size();
if (size > 0) {
// ok, it is an assign, so, let's get it
for (int i = 0; i < size; i++) {
Object next = defs.get(i);
if (next instanceof AssignDefinition) {
AssignDefinition element = (AssignDefinition) next;
if (element.target.startsWith("self") == false) {
if (element.scope.isOuterOrSameScope(scopeVisitor.scope) || element.foundAsGlobal) {
toRet.add(element);
}
} else {
toRet.add(element);
}
} else {
toRet.add((Definition) next);
}
}
if (toRet.size() > 0) {
return toRet.toArray(new Definition[0]);
}
}
// now, check for locals
TokensList localTokens = scopeVisitor.scope.getAllLocalTokens();
int len = localTokens.size();
for (IterTokenEntry entry : localTokens) {
IToken tok = entry.getToken();
final String tokenRep = tok.getRepresentation();
if (tokenRep.equals(actTok)) {
if (tok instanceof SourceToken && ((SourceToken) tok).getAst() instanceof Assign) {
Assign node = (Assign) ((SourceToken) tok).getAst();
String target = tok.getRepresentation();
return new Definition[] { FindDefinitionModelVisitor.getAssignDefinition(node, target, 0, line, col, scopeVisitor.scope, this, -1) };
}
return new Definition[] { new Definition(tok, scopeVisitor.scope, this, true) };
} else if (actTok.startsWith(tokenRep + ".") && !actTok.startsWith("self.")) {
final int tokenRepLen = tokenRep.length();
// this means we have a declaration in the local scope and we're accessing a part of it
// e.g.:
// class B:
// def met2(self):
// c = C()
// c.met1
state.checkFindLocalDefinedDefinitionMemory(this, tokenRep);
ICompletionState copyWithActTok = state.getCopyWithActTok(tokenRep);
Definition[] definitions = this.findDefinition(copyWithActTok, tok.getLineDefinition(), tok.getColDefinition(), nature, innerFindPaths);
ArrayList<Definition> ret = new ArrayList<Definition>();
for (Definition definition : definitions) {
if (definition.module != null) {
if (definition.value.length() == 0) {
continue;
}
String checkFor = definition.value + actTok.substring(tokenRepLen);
if (this.equals(definition.module)) {
// no point in finding the starting point
if (actTok.equals(definition.value)) {
continue;
}
if (checkFor.equals(actTok)) {
continue;
}
if (checkFor.startsWith(actTok + '.')) {
// a.strip.rjust.strip, in which case we'd recurse.
continue;
}
}
// Note: I couldn't really reproduce this case, so, this fix is just a theoretical
// workaround. Hopefully sometime someone will provide some code to reproduce this.
// see: http://sourceforge.net/tracker/?func=detail&aid=2992629&group_id=85796&atid=577329
int dotsFound = StringUtils.count(checkFor, '.');
if (dotsFound > 15) {
throw new CompletionRecursionException("Trying to go to deep to find definition.\n" + "We probably started entering a recursion.\n" + "Module: " + definition.module.getName() + "\n" + "Token: " + checkFor);
}
Definition[] realDefinitions;
if (definition.module instanceof SourceModule) {
SourceModule sourceModule = (SourceModule) definition.module;
realDefinitions = sourceModule.findDefinition(state.getCopyWithActTok(checkFor), definition.line, definition.col, nature, innerFindPaths);
} else {
realDefinitions = (Definition[]) definition.module.findDefinition(state.getCopyWithActTok(checkFor), definition.line, definition.col, nature);
}
for (Definition realDefinition : realDefinitions) {
ret.add(realDefinition);
}
}
}
if (ret.size() == 0) {
// Well, it seems it's a parameter, so, let's check if we can get the parameter definition to then resolve
// the token.
ILocalScope scope = scopeVisitor.scope;
List<ITypeInfo> possibleClassesForActivationToken = scope.getPossibleClassesForActivationToken(tokenRep);
// Above we have: actTok.startsWith(tokenRep + ".")
// and we just resolved tokenRep, so, let's check the remainder given type hints.
String remainder = actTok.substring(tokenRepLen + 1);
if (possibleClassesForActivationToken.size() > 0) {
for (ITypeInfo possibleClass : possibleClassesForActivationToken) {
AbstractASTManager astManager = (AbstractASTManager) nature.getAstManager();
if (astManager != null) {
TokensList completionsFromTypeRepresentation = astManager.getCompletionsFromTypeRepresentation(state, Arrays.asList(possibleClass), this);
for (IterTokenEntry entry1 : completionsFromTypeRepresentation) {
IToken iToken = entry1.getToken();
if (remainder.equals(iToken.getRepresentation())) {
String parentPackage = iToken.getParentPackage();
IModule module;
if (this.getName().equals(parentPackage)) {
module = this;
} else {
module = astManager.getModule(parentPackage, nature, true, state);
}
if (module != null) {
ret.add(new Definition(iToken, null, module));
}
}
}
}
}
}
}
return ret.toArray(new Definition[ret.size()]);
}
}
// not found... check as local imports
TokensList localImportedModules = scopeVisitor.scope.getLocalImportedModules(line, col, this.name);
ICodeCompletionASTManager astManager = nature.getAstManager();
for (IterTokenEntry entry : localImportedModules) {
IToken tok = entry.getToken();
String importRep = tok.getRepresentation();
if (importRep.equals(actTok) || actTok.startsWith(importRep + ".")) {
Tuple3<IModule, String, IToken> o = astManager.findOnImportedMods(new TokensList(new IToken[] { tok }), state.getCopyWithActTok(actTok), this.getName(), this);
if (o != null && o.o1 instanceof SourceModule) {
ICompletionState copy = state.getCopy();
copy.setActivationToken(o.o2);
findDefinitionsFromModAndTok(nature, toRet, null, (SourceModule) o.o1, copy);
}
if (toRet.size() > 0) {
return toRet.toArray(new Definition[0]);
}
}
}
// local (which has already been covered).
if (actTok.startsWith("self.")) {
// ok, it is some self, now, that is only valid if we are in some class definition
ClassDef classDef = (ClassDef) scopeVisitor.scope.getClassDef();
if (classDef != null) {
// ok, we are in a class, so, let's get the self completions
String classRep = NodeUtils.getRepresentationString(classDef);
if (classRep != null) {
TokensList globalTokens = getGlobalTokens(new CompletionState(line - 1, col - 1, classRep, nature, "", // use the old state as the cache
state), astManager);
String withoutSelf = actTok.substring(5);
for (IterTokenEntry entry : globalTokens) {
IToken token = entry.getToken();
if (token.getRepresentation().equals(withoutSelf)) {
String parentPackage = token.getParentPackage();
IModule module = astManager.getModule(parentPackage, nature, true, state);
if (token instanceof SourceToken && (module != null || this.name == null || this.name.equals(parentPackage))) {
if (module == null) {
module = this;
}
SimpleNode ast2 = ((SourceToken) token).getAst();
Tuple<Integer, Integer> def = getLineColForDefinition(ast2);
FastStack<SimpleNode> stack = new FastStack<SimpleNode>(5);
if (module instanceof SourceModule) {
stack.push(((SourceModule) module).getAst());
}
stack.push(classDef);
ILocalScope scope = new LocalScope(astManager.getNature(), stack);
return new Definition[] { new Definition(def.o1, def.o2, token.getRepresentation(), ast2, scope, module) };
} else {
return new Definition[0];
}
}
}
}
}
}
// ok, it is not an assign, so, let's search the global tokens (and imports)
String tok = actTok;
SourceModule mod = this;
Tuple3<IModule, String, IToken> o = astManager.findOnImportedMods(state.getCopyWithActTok(actTok), this);
if (o != null) {
if (o.o1 instanceof SourceModule) {
mod = (SourceModule) o.o1;
tok = o.o2;
} else if (o.o1 instanceof CompiledModule) {
// ok, we have to check the compiled module
tok = o.o2;
if (tok == null || tok.length() == 0) {
return new Definition[] { new Definition(1, 1, "", null, null, o.o1) };
} else {
state.checkFindDefinitionMemory(o.o1, tok);
return (Definition[]) o.o1.findDefinition(state.getCopyWithActTok(tok), -1, -1, nature);
}
} else if (o.o1 instanceof IAbstractJavaClassModule) {
tok = o.o2;
state.checkFindDefinitionMemory(o.o1, tok);
return (Definition[]) o.o1.findDefinition(state.getCopyWithActTok(tok), -1, -1, nature);
} else {
throw new RuntimeException("Unexpected module found in imports: " + o);
}
}
// mod == this if we are now checking the globals (or maybe not)...heheheh
ICompletionState copy = state.getCopyWithActTok(tok, line - 1, col - 1);
// further on this we will get the first part of the same tok, so token line and column will be the same
try {
state.checkFindDefinitionMemory(mod, tok);
findDefinitionsFromModAndTok(nature, toRet, visitor.moduleImported, mod, copy);
} catch (CompletionRecursionException e) {
// ignore (will return what we've got so far)
// e.printStackTrace();
}
return toRet.toArray(new Definition[0]);
}
use of org.python.pydev.shared_core.structure.FastStack in project Pydev by fabioz.
the class SourceModule method internalFindGlobalTokDef.
/**
* @param tok
* @param nature
* @return
* @throws Exception
*/
private Definition internalFindGlobalTokDef(ICompletionState state, IPythonNature nature) throws Exception {
String tok = state.getActivationToken();
String[] headAndTail = FullRepIterable.headAndTail(tok);
String firstPart = headAndTail[0];
String rep = headAndTail[1];
TokensList tokens = null;
// }
if (tokens == null || tokens.empty()) {
if (nature != null) {
tokens = nature.getAstManager().getCompletionsForModule(this, state.getCopyWithActTok(firstPart, state.getLine(), state.getCol()), true);
} else {
tokens = getGlobalTokens();
}
}
for (IterTokenEntry entry : tokens) {
IToken token = entry.getToken();
boolean sameRep = token.getRepresentation().equals(rep);
if (sameRep) {
if (token instanceof SourceToken) {
SourceToken sourceToken = (SourceToken) token;
if (sourceToken.getType() == IToken.TYPE_OBJECT_FOUND_INTERFACE) {
// that it's actual definition was found
continue;
}
// ok, we found it
SimpleNode a = sourceToken.getAst();
if (a == null) {
continue;
}
Tuple<Integer, Integer> def = getLineColForDefinition(a);
String parentPackage = token.getParentPackage();
IModule module = this;
if (nature != null) {
IModule mod = nature.getAstManager().getModule(parentPackage, nature, true, state);
if (mod != null) {
module = mod;
}
}
if (module instanceof SourceModule) {
// this is just to get its scope...
SourceModule m = (SourceModule) module;
FindScopeVisitor scopeVisitor = m.getScopeVisitor(a.beginLine, a.beginColumn);
Assign foundInAssign = sourceToken.getFoundInAssign();
if (foundInAssign != null) {
Definition ret = findDefinitionsInAssignStatementUncached(nature, rep, m, foundInAssign);
if (ret == null) {
String fullRep = NodeUtils.getFullRepresentationString(sourceToken.getAst());
if (!rep.equals(fullRep)) {
ret = findDefinitionsInAssignStatementUncached(nature, fullRep, m, foundInAssign);
}
}
if (ret != null) {
// Note: we must fix the scope because we visited only the assign in this case (so
// it's not correct).
ret.scope = scopeVisitor.scope;
}
// scopeVisitor.scope, module, nodeValue, unpackPos);
return ret;
} else {
return new Definition(def.o1, def.o2, rep, a, scopeVisitor.scope, module);
}
} else {
// line, col
return new Definition(def.o1, def.o2, rep, a, new LocalScope(nature, new FastStack<SimpleNode>(5)), module);
}
} else if (token instanceof ConcreteToken) {
// a contrete token represents a module
String modName = token.getParentPackage();
if (modName.length() > 0) {
modName += ".";
}
modName += token.getRepresentation();
IModule module = nature.getAstManager().getModule(modName, nature, true, state);
if (module == null) {
return null;
} else {
// it is the module itself
return new Definition(0 + 1, 0 + 1, "", null, null, module);
}
} else if (token instanceof CompiledToken) {
String parentPackage = token.getParentPackage();
FullRepIterable iterable = new FullRepIterable(parentPackage, true);
IModule module = null;
for (String modName : iterable) {
module = nature.getAstManager().getModule(modName, nature, true, state);
if (module != null) {
break;
}
}
if (module == null) {
return null;
}
int length = module.getName().length();
String finalRep = "";
if (parentPackage.length() > length) {
finalRep = parentPackage.substring(length + 1) + '.';
}
finalRep += token.getRepresentation();
try {
IDefinition[] definitions = module.findDefinition(state.getCopyWithActTok(finalRep), -1, -1, nature);
if (definitions.length > 0) {
Definition definition = (Definition) definitions[0];
definition.setGeneratorType(token.getGeneratorType());
return definition;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException("Unexpected token:" + token.getClass());
}
}
}
return null;
}
use of org.python.pydev.shared_core.structure.FastStack in project Pydev by fabioz.
the class PythonModelProvider method convertToPythonElementsAddOrRemove.
/**
* Converts the shape modification to use Python elements.
* @param natureToSourcePathSet
*
* @param modification: the shape modification to convert
* @param isAdd: boolean indicating whether this convertion is happening in an add operation
*/
@SuppressWarnings("unchecked")
private void convertToPythonElementsAddOrRemove(PipelinedShapeModification modification, boolean isAdd, Map<PythonNature, Set<String>> natureToSourcePathSet) {
if (DEBUG) {
debug("Before", modification);
}
Object parent = modification.getParent();
if (parent instanceof IContainer) {
IContainer parentContainer = (IContainer) parent;
Object pythonParent = getResourceInPythonModel(parentContainer, true);
if (pythonParent instanceof IWrappedResource) {
IWrappedResource parentResource = (IWrappedResource) pythonParent;
modification.setParent(parentResource);
wrapChildren(parentResource, parentResource.getSourceFolder(), modification.getChildren(), isAdd, natureToSourcePathSet);
} else if (pythonParent == null) {
Object parentInWrap = parentContainer;
PythonSourceFolder sourceFolderInWrap = null;
// this may happen when a source folder is added or some element that still doesn't have it's parent in the model...
// so, we have to get the parent's parent until we actually 'know' that it is not in the model (or until we run
// out of parents to try)
// the case in which we reproduce this is Test 1 (described in the class)
FastStack<Object> found = new FastStack<Object>(20);
while (true) {
// add the current to the found
if (parentContainer == null) {
break;
}
found.push(parentContainer);
if (parentContainer instanceof IProject) {
// we got to the project without finding any part of a python model already there, so, let's see
// if any of the parts was actually a source folder (that was still not added)
tryCreateModelFromProject((IProject) parentContainer, found, natureToSourcePathSet);
// and now, if it was created, try to convert it to the python model (without any further add)
convertToPythonElementsUpdateOrRefresh(modification.getChildren());
return;
}
Object p = getResourceInPythonModel(parentContainer, true);
if (p instanceof IWrappedResource) {
IWrappedResource wrappedResource = (IWrappedResource) p;
sourceFolderInWrap = wrappedResource.getSourceFolder();
while (found.size() > 0) {
Object f = found.pop();
if (f instanceof IResource) {
// no need to create it if it's already in the model!
Object child = sourceFolderInWrap.getChild((IResource) f);
if (child != null && child instanceof IWrappedResource) {
wrappedResource = (IWrappedResource) child;
continue;
}
}
// creating is enough to add it to the model
if (f instanceof IFile) {
wrappedResource = new PythonFile(wrappedResource, (IFile) f, sourceFolderInWrap);
} else if (f instanceof IFolder) {
wrappedResource = new PythonFolder(wrappedResource, (IFolder) f, sourceFolderInWrap);
}
}
parentInWrap = wrappedResource;
break;
}
parentContainer = parentContainer.getParent();
}
wrapChildren(parentInWrap, sourceFolderInWrap, modification.getChildren(), isAdd, natureToSourcePathSet);
}
} else if (parent == null) {
wrapChildren(null, null, modification.getChildren(), isAdd, natureToSourcePathSet);
}
if (DEBUG) {
debug("After", modification);
}
}
Aggregations