📄 abstractastmanager.java
字号:
if(tok.length() == 0){
//the activation token corresponds to an imported module. We have to get its global tokens and return them.
ICompletionState copy = state.getCopy();
copy.setActivationToken("");
copy.setBuiltinsGotten(true); //we don't want builtins...
return getCompletionsForModule(mod, copy);
}else if (mod != null){
ICompletionState copy = state.getCopy();
copy.setActivationToken(tok);
copy.setCol(-1);
copy.setLine(-1);
copy.raiseNFindTokensOnImportedModsCalled(mod, tok);
String parentPackage = o.o3.getParentPackage();
if(parentPackage.trim().length() > 0 &&
parentPackage.equals(current.getName()) &&
state.getActivationToken().equals(tok) &&
!parentPackage.endsWith("__init__")){
if(current.isInDirectGlobalTokens(tok)){
return null;
}
}
return getCompletionsForModule(mod, copy);
}
return null;
}
/**
* @param activationToken
* @param importedModules
* @param module
* @return tuple with:
* 0: mod
* 1: tok
* @throws CompletionRecursionException
*/
public Tuple3<IModule, String, IToken> findOnImportedMods( ICompletionState state, IModule current) throws CompletionRecursionException {
IToken[] importedModules = current.getTokenImportedModules();
return findOnImportedMods(importedModules, state, current.getName());
}
/**
* This function tries to find some activation token defined in some imported module.
* @return tuple with: the module and the token that should be used from it.
*
* @param this is the activation token we have. It may be a single token or some dotted name.
*
* If it is a dotted name, such as testcase.TestCase, we need to match against some import
* represented as testcase or testcase.TestCase.
*
* If a testcase.TestCase matches against some import named testcase, the import is returned and
* the TestCase is put as the module
*
* 0: mod
* 1: tok (string)
* 2: actual tok
* @throws CompletionRecursionException
*/
public Tuple3<IModule, String, IToken> findOnImportedMods( IToken[] importedModules, ICompletionState state, String currentModuleName) throws CompletionRecursionException {
FullRepIterable iterable = new FullRepIterable(state.getActivationToken(), true);
for(String tok : iterable){
for (IToken importedModule : importedModules) {
final String modRep = importedModule.getRepresentation(); //this is its 'real' representation (alias) on the file (if it is from xxx import a as yyy, it is yyy)
if(modRep.equals(tok)){
String act = state.getActivationToken();
Tuple<IModule, String> r = findOnImportedMods(importedModule, tok, state, act, currentModuleName);
if(r == null){
return null;
}
return new Tuple3<IModule, String, IToken>(r.o1, r.o2, importedModule);
}
}
}
return null;
}
/**
* Checks if some module can be resolved and returns the module it is resolved to (and to which token).
* @throws CompletionRecursionException
*
*/
protected Tuple<IModule, String> findOnImportedMods(IToken importedModule, String tok, ICompletionState state,
String activationToken, String currentModuleName) throws CompletionRecursionException {
Tuple<IModule, String> modTok = null;
IModule mod = null;
//ok, check if it is a token for the new import
if(importedModule instanceof SourceToken){
SourceToken token = (SourceToken) importedModule;
if(token.isImportFrom()){
ImportFrom importFrom = (ImportFrom) token.getAst();
int level = importFrom.level;
if(level > 0){
//ok, it must be treated as a relative import
//ok, it is the import added on python 2.5 (from .. import xxx)
String parentPackage = token.getParentPackage();
String[] moduleParts = FullRepIterable.dotSplit(parentPackage);
String relative = null;
if(moduleParts.length > level){
relative = FullRepIterable.joinParts(moduleParts, moduleParts.length-level);
}
String modName = ((NameTok)importFrom.module).id;
if(modName.length() > 0){
//ok, we have to add the other part too, as we have more than the leading dots
//from ..bar import
relative += "."+modName;
}
relative += "."+tok;
modTok = findModuleFromPath(relative, state.getNature(), false, null);
mod = modTok.o1;
if(checkValidity(currentModuleName, mod)){
Tuple<IModule, String> ret = fixTok(modTok, tok, activationToken);
return ret;
}
//ok, it is 'forced' as relative import because it has a level, so, it MUST return here
return null;
}
}
}
//check as relative with complete rep
String asRelativeImport = importedModule.getAsRelativeImport(currentModuleName);
modTok = findModuleFromPath(asRelativeImport, state.getNature(), true, currentModuleName);
mod = modTok.o1;
if(checkValidity(currentModuleName, mod)){
Tuple<IModule, String> ret = fixTok(modTok, tok, activationToken);
return ret;
}
//check if the import actually represents some token in an __init__ file
String originalWithoutRep = importedModule.getOriginalWithoutRep();
if(originalWithoutRep.length() > 0){
if(!originalWithoutRep.endsWith("__init__")){
originalWithoutRep = originalWithoutRep + ".__init__";
}
modTok = findModuleFromPath(originalWithoutRep, state.getNature(), true, null);
mod = modTok.o1;
if(modTok.o2.endsWith("__init__") == false && checkValidity(currentModuleName, mod)){
if(mod.isInGlobalTokens(importedModule.getRepresentation(), state.getNature(), false)){
//then this is the token we're looking for (otherwise, it might be a module).
Tuple<IModule, String> ret = fixTok(modTok, tok, activationToken);
if(ret.o2.length() == 0){
ret.o2 = importedModule.getRepresentation();
}else{
ret.o2 = importedModule.getRepresentation()+"."+ret.o2;
}
return ret;
}
}
}
//the most 'simple' case: check as absolute with original rep
modTok = findModuleFromPath(importedModule.getOriginalRep(), state.getNature(), false, null);
mod = modTok.o1;
if(checkValidity(currentModuleName, mod)){
Tuple<IModule, String> ret = fixTok(modTok, tok, activationToken);
return ret;
}
//ok, one last shot, to see a relative looking in folders __init__
modTok = findModuleFromPath(asRelativeImport, state.getNature(), false, null);
mod = modTok.o1;
if(checkValidity(currentModuleName, mod)){
Tuple<IModule, String> ret = fixTok(modTok, tok, activationToken);
//now let's see if what we did when we found it as a relative import is correct:
//if we didn't find it in an __init__ module, all should be ok
if(!mod.getName().endsWith("__init__")){
return ret;
}
//otherwise, we have to be more cautious...
//if the activation token is empty, then it is the module we were looking for
//if it is not the initial token we were looking for, it is correct
//if it is in the global tokens of the found module it is correct
//if none of this situations was found, we probably just found the same token we had when we started (unless I'm mistaken...)
else if(activationToken.length() == 0 || ret.o2.equals(activationToken) == false || mod.isInGlobalTokens(activationToken, state.getNature(), false)){
return ret;
}
}
return null;
}
protected boolean checkValidity(String currentModuleName, IModule mod) {
if(mod == null){
return false;
}
String modName = mod.getName();
if(modName == null){
return true;
}
//still in the same module
if(modName.equals(currentModuleName)){
return false;
}
// if(currentModuleName != null && modName.endsWith(".__init__")){
// //we have to check it without the __init__
// String withoutLastPart = FullRepIterable.getWithoutLastPart(modName);
// if(withoutLastPart.equals(currentModuleName)){
// return false;
// }
// }
return true;
}
/**
* Fixes the token if we found a module that was just a substring from the initial activation token.
*
* This means that if we had testcase.TestCase and found it as TestCase, the token is added with TestCase
*/
protected Tuple<IModule, String> fixTok(Tuple<IModule, String> modTok, String tok, String activationToken) {
if(activationToken.length() > tok.length() && activationToken.startsWith(tok)){
String toAdd = activationToken.substring(tok.length() + 1);
if(modTok.o2.length() == 0){
modTok.o2 = toAdd;
}else{
modTok.o2 += "."+toAdd;
}
}
return modTok;
}
/**
* This function receives a path (rep) and extracts a module from that path.
* First it tries with the full path, and them removes a part of the final of
* that path until it finds the module or the path is empty.
*
* @param currentModuleName this is the module name (used to check validity for relative imports) -- not used if dontSearchInit is false
* if this parameter is not null, it means we're looking for a relative import. When checking for relative imports,
* we should only check the modules that are directly under this project (so, we should not check the whole pythonpath for
* it, just direct modules)
*
* @return tuple with found module and the String removed from the path in
* order to find the module.
*/
protected Tuple<IModule, String> findModuleFromPath(String rep, IPythonNature nature, boolean dontSearchInit, String currentModuleName){
String tok = "";
boolean lookingForRelative = currentModuleName != null;
IModule mod = getModule(rep, nature, dontSearchInit, lookingForRelative);
String mRep = rep;
int index;
while(mod == null && (index = mRep.lastIndexOf('.')) != -1){
tok = mRep.substring(index+1) + "."+tok;
mRep = mRep.substring(0,index);
if(mRep.length() > 0){
mod = getModule(mRep, nature, dontSearchInit, lookingForRelative);
}
}
if (tok.endsWith(".")){
tok = tok.substring(0, tok.length()-1); //remove last point if found.
}
if(dontSearchInit && currentModuleName != null && mod != null){
String parentModule = FullRepIterable.getParentModule(currentModuleName);
//if we are looking for some relative import token, it can only match if the name found is not less than the parent
//of the current module because of the way in that relative imports are meant to be written.
//if it equal, it should not match either, as it was found as the parent module... this can not happen because it must find
//it with __init__ if it was the parent module
if (mod.getName().length() <= parentModule.length()){
return new Tuple<IModule, String>(null, null);
}
}
return new Tuple<IModule, String>((AbstractModule)mod, tok);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -