* Files only get here if we were unable to parse them.
*/
private transient Map<File, Long> predefinedFilesNotParsedToTimestamp;
public AbstractModule getBuiltinModule(String name, boolean dontSearchInit) {
AbstractModule n = null;
//check for supported builtins these don't have files associated.
//they are the first to be passed because the user can force a module to be builtin, because there
//is some information that is only useful when you have builtins, such as os and wxPython (those can
//be source modules, but they have so much runtime info that it is almost impossible to get useful information
//from statically analyzing them).
String[] builtins = getBuiltins();
if (builtins == null || this.info == null) {
//still on startup
return null;
}
//for temporary access (so that we don't generate many instances of it)
ModulesKey keyForCacheAccess = new ModulesKey(null, null);
//A different choice for users that want more complete information on the libraries they're dealing
//with is using predefined modules. Those will
File predefinedModule = this.info.getPredefinedModule(name);
if (predefinedModule != null && predefinedModule.exists()) {
keyForCacheAccess.name = name;
keyForCacheAccess.file = predefinedModule;
n = cache.getObj(keyForCacheAccess, this);
if ((n instanceof PredefinedSourceModule)) {
PredefinedSourceModule predefinedSourceModule = (PredefinedSourceModule) n;
if (predefinedSourceModule.isSynched()) {
return n;
}
//otherwise (not PredefinedSourceModule or not synched), just keep going to create
//it as a predefined source module
}
boolean tryToParse = true;
Long lastModified = null;
if (predefinedFilesNotParsedToTimestamp == null) {
predefinedFilesNotParsedToTimestamp = new HashMap<File, Long>();
} else {
Long lastTimeChanged = predefinedFilesNotParsedToTimestamp.get(predefinedModule);
if (lastTimeChanged != null) {
lastModified = predefinedModule.lastModified();
if (lastTimeChanged.equals(lastModified)) {
tryToParse = false;
} else {
predefinedFilesNotParsedToTimestamp.remove(predefinedModule);
}
}
}
if (tryToParse) {
IDocument doc;
try {
doc = FileUtilsFileBuffer.getDocFromFile(predefinedModule);
IGrammarVersionProvider provider = new IGrammarVersionProvider() {
public int getGrammarVersion() throws MisconfigurationException {
return IGrammarVersionProvider.GRAMMAR_PYTHON_VERSION_3_0; // Always Python 3.0 here
}
};
Tuple<SimpleNode, Throwable> obj = PyParser.reparseDocument(new PyParser.ParserInfo(doc, provider,
name, predefinedModule));
if (obj.o2 != null) {
if (lastModified == null) {
lastModified = predefinedModule.lastModified();
}
predefinedFilesNotParsedToTimestamp.put(predefinedModule, lastModified);
Log.log("Unable to parse: " + predefinedModule, obj.o2);
} else if (obj.o1 != null) {
n = new PredefinedSourceModule(name, predefinedModule, obj.o1, obj.o2);
doAddSingleModule(keyForCacheAccess, n);
return n;
}
//keep on going
} catch (Throwable e) {
Log.log(e);
}
}
}
boolean foundStartingWithBuiltin = false;
FastStringBuffer buffer = null;
for (int i = 0; i < builtins.length; i++) {
String forcedBuiltin = builtins[i];
if (name.startsWith(forcedBuiltin)) {
if (name.length() > forcedBuiltin.length() && name.charAt(forcedBuiltin.length()) == '.') {
foundStartingWithBuiltin = true;
keyForCacheAccess.name = name;
n = cache.getObj(keyForCacheAccess, this);
if (n == null && dontSearchInit == false) {
if (buffer == null) {
buffer = new FastStringBuffer();
} else {
buffer.clear();
}
keyForCacheAccess.name = buffer.append(name).append(".__init__").toString();
n = cache.getObj(keyForCacheAccess, this);
}
if (n instanceof EmptyModule || n instanceof SourceModule) {
//it is actually found as a source module, so, we have to 'coerce' it to a compiled module
n = new CompiledModule(name, this);
doAddSingleModule(new ModulesKey(n.getName(), null), n);
return n;
}
}
if (name.equals(forcedBuiltin)) {
keyForCacheAccess.name = name;
n = cache.getObj(keyForCacheAccess, this);
if (n == null || n instanceof EmptyModule || n instanceof SourceModule) {
//still not created or not defined as compiled module (as it should be)
n = new CompiledModule(name, this);
doAddSingleModule(new ModulesKey(n.getName(), null), n);
return n;
}
}
if (n instanceof CompiledModule) {
return n;
}
}
}
if (foundStartingWithBuiltin) {
if (builtinsNotConsidered.getObj(name) != null) {
return null;
}
//ok, just add it if it is some module that actually exists
n = new CompiledModule(name, this);
IToken[] globalTokens = n.getGlobalTokens();
//if it does not contain the __file__, this means that it's not actually a module
//(but may be a token from a compiled module, so, clients wanting it must get the module
//first and only then go on to this token).
//done: a cache with those tokens should be kept, so that we don't actually have to create
//the module to see its return values (because that's slow)