// src-input.cc: Input of classes and packages by reading in the source #include #include #include #include #include #include #include #include #include #include "AST.h" #include "ClassDecl.h" #include "NamedPath.h" #include "compiler.h" #include "code-util.h" #include "decls.h" #include "errors.h" #include "string-utils.h" #include "utils.h" extern int DEBUG; static SearchPath &pickLib(Decl *container) { static NamedPath NamedLib; return (SearchPath &) NamedLib; } void PackageDecl::readIn() { bool empty = true; if (_container == NULL) _environ = new Environ (NULL); else _environ = new Environ (_container->environ()); isStub = false; const SearchPath &paths = pickLib(this); string subdir = fullName('/'); if (!subdir.empty()) subdir += '/'; for (SearchPath::const_iterator path = paths.begin(); path != paths.end(); ++path) { const string dirName = *path + subdir; DIR *dir = opendir (dirName.c_str()); if (dir) { for (dirent *entry = readdir (dir); entry; entry = readdir (dir)) { const string name = entry->d_name; const string::size_type length = name.size(); string className; if (name == "." || name == "..") continue; else if (hasSuffix(name, ".ti")) className = name.substr(0, length - 3); else if (hasSuffix(name, ".java")) className = name.substr(0, length - 5); if (!className.empty()) { _environ->add(new ClassDecl(intern(className), this)); empty = false; if (DEBUG) cerr << errorName() << " : found source in " << dirName << name << endl; } else if (this != unnamedPackage) { /* The anonymous package does NOT have subpackages */ string fullname = dirName + name; struct stat fs; /* ignore java and ti directorys in the CWD, because it leads to * stupid conflicts on the standard library which are poorly diagnosed * and that's almost never what we want (PR255) */ if (DEBUG) cerr << "considering subpath:"<< fullname<<"..." << endl; if (!(!strcmp(fullname.c_str(),"./java") || !strcmp(fullname.c_str(),"./ti")) && stat(fullname.c_str(), &fs) == 0 && S_ISDIR(fs.st_mode)) { _environ->add(new PackageDecl(intern(name), this)); empty = false; if (DEBUG) cerr << errorName() << " : found subpackage in " << fullname << endl; } } } closedir (dir); } else if (errno != ENOENT) Warning () << "could not read directory " << dirName << ": " << strerror(errno) << endl; } if (empty && this != unnamedPackage) Warning () << "unable to find any sources or subpackages for " << errorName() << endl; } // debugging globals to make sure that loads, environment builds happen // at the "right" time bool allshouldbeloaded; bool canbuildenv; static bool inExceptions(const string &name) { return (name == "java.lang.UNIXProcess" || name == "java.lang.Throwable" || name == "java.lang.Object" || name == "java.lang.Error" || name == "java.lang.Boolean" || name == "java.lang.Byte" || name == "java.lang.Double" || name == "java.lang.Float" || name == "java.lang.Integer" || name == "java.lang.Long" || name == "java.lang.Math" || name == "java.lang.Number" || name == "java.lang.Short" || name == "java.lang.StrictMath" || name == "java.io.RandomAccessFile" || name == "java.util.Random" || name == "java.util.Vector"); } static bool isInJavaLibrary(Decl *d) { const string name = d->fullName(); return (!inExceptions(name) && (hasPrefix(name, "java.") || // Java 1.4 libraries. hasPrefix(name, "com.") || hasPrefix(name, "javax.") || hasPrefix(name, "org.") || hasPrefix(name, "sun.") || hasPrefix(name, "sunw."))); } void ClassDecl::drequire() { if (!source()) if (templateBasis) { instantiateSource(); assert( source() != NULL ); } else { source(TreeNode::omitted); assert(!allshouldbeloaded); string fileName = fullName('/'); FILE * const file = pickLib(container()).openSource(fileName); if (DEBUG) cerr << ">Reading in " << errorName() << " from " << fileName << endl; //load(fileName, file, isTitanium(fileName) || hasPrefix(fullName(), "ti.")); load(fileName, file, !isInJavaLibrary(this), isInLibrary(this)); if (file) ti_fclose(file); if (source()->absent()) Error() << "file " << fileName << " doesn't contain class or interface " << fullName() << endl; if (DEBUG) cerr << ">Done reading " << errorName() << endl; } } void ClassDecl::buildEnviron() { if (DEBUG) cerr << ">Building env for " << errorName() << endl; assert(!allshouldbeloaded); assert(canbuildenv); assert(!instantiations); drequire(); // builds environments for all recently loaded classes, including this one buildEnvironments(); // If class didn't load, give it a dummy environment, etc if (!_environ) { environ(new Environ(PackageDecl::System->environ())); superClass(ObjectDecl); visits = 2; } }