lib/qx/tool/compiler/Analyser.js
function(className, forceScan, cb) {
      var t = this;
      if (!this.__db) {
        this.__db = {}; 
      }
      var db = this.__db;
      
      if (typeof forceScan == "function") {
        cb = forceScan;
        forceScan = false;
      }

      if (!db.classInfo) {
        db.classInfo = {};
      }

      var library = t.getLibraryFromClassname(className);
      if (!library) {
        let err = new Error("Cannot find class file " + className);
        err.code = "ENOCLASSFILE";
        cb && cb(err);
        return;
      }
      var sourceClassFilename = qx.tool.compiler.ClassFile.getSourcePath(library, className);
      var outputClassFilename = qx.tool.compiler.ClassFile.getOutputPath(this, className);
      
      function scanFile(stat, outputStat) {
        var dbClassInfo = db.classInfo[className];
        if (dbClassInfo && outputStat) {
          var dbMtime = null;
          try {
            dbMtime = dbClassInfo.mtime && new Date(dbClassInfo.mtime);
          } catch (e) {
          }
          if (dbMtime && dbMtime.getTime() == stat.mtime.getTime()) {
            if (outputStat.mtime.getTime() >= stat.mtime.getTime()) {
              cb && cb(null, dbClassInfo);
              return;
            }
          }
        }
        
        // Add database entry
        var oldDbClassInfo = db.classInfo[className] ? Object.assign({}, db.classInfo[className]) : null;
        dbClassInfo = db.classInfo[className] = {
          mtime: stat.mtime,
          libraryName: library.getNamespace()
        };

        // Analyse it and collect unresolved symbols and dependencies
        var classFile = new qx.tool.compiler.ClassFile(t, className, library);
        t.fireDataEvent("compilingClass", { dbClassInfo: dbClassInfo, oldDbClassInfo: oldDbClassInfo, classFile: classFile });
        classFile.load(function(err) {
          if (err) {
            cb && cb(err);
            return;
          }

          // Save it
          classFile.writeDbInfo(dbClassInfo);

          t.fireDataEvent("compiledClass", { dbClassInfo: dbClassInfo, oldDbClassInfo: oldDbClassInfo, classFile: classFile });

          // Next!
          cb && cb(null, dbClassInfo, classFile);
        });
      }
      
      // Detect whether we need to rescan the file
      fs.stat(sourceClassFilename, function(err, stat) {
        if (err) {
          cb && cb(err);
          return;
        }

        fs.exists(outputClassFilename, function(exists) {
          if (!exists || forceScan) {
            scanFile(stat);
            return;
          }
          fs.exists(outputClassFilename + "on", function(exists) {
            if (!exists) {
              scanFile(stat);
              return;
            }
            
            fs.stat(outputClassFilename, function(err, outputStat) {
              if (err) {
                cb && cb(err);
                return;
              }
  
              scanFile(stat, outputStat);
            });
          });
        });
      });
    }
function(className, forceScan, cb) {
      var t = this;
      if (!this.__db) {
        this.__db = {}; 
      }
      var db = this.__db;
      
      if (typeof forceScan == "function") {
        cb = forceScan;
        forceScan = false;
      }

      if (!db.classInfo) {
        db.classInfo = {};
      }

      var library = t.getLibraryFromClassname(className);
      if (!library) {
        let err = new Error("Cannot find class file " + className);
        err.code = "ENOCLASSFILE";
        cb && cb(err);
        return;
      }
      var sourceClassFilename = qx.tool.compiler.ClassFile.getSourcePath(library, className);
      var outputClassFilename = qx.tool.compiler.ClassFile.getOutputPath(this, className);
      
      function scanFile(stat, outputStat) {
        var dbClassInfo = db.classInfo[className];
        if (dbClassInfo && outputStat) {
          var dbMtime = null;
          try {
            dbMtime = dbClassInfo.mtime && new Date(dbClassInfo.mtime);
          } catch (e) {
          }
          if (dbMtime && dbMtime.getTime() == stat.mtime.getTime()) {
            if (outputStat.mtime.getTime() >= stat.mtime.getTime()) {
              cb && cb(null, dbClassInfo);
              return;
            }
          }
        }
        
        // Add database entry
        var oldDbClassInfo = db.classInfo[className] ? Object.assign({}, db.classInfo[className]) : null;
        dbClassInfo = db.classInfo[className] = {
          mtime: stat.mtime,
          libraryName: library.getNamespace()
        };

        // Analyse it and collect unresolved symbols and dependencies
        var classFile = new qx.tool.compiler.ClassFile(t, className, library);
        t.fireDataEvent("compilingClass", { dbClassInfo: dbClassInfo, oldDbClassInfo: oldDbClassInfo, classFile: classFile });
        classFile.load(function(err) {
          if (err) {
            cb && cb(err);
            return;
          }

          // Save it
          classFile.writeDbInfo(dbClassInfo);

          t.fireDataEvent("compiledClass", { dbClassInfo: dbClassInfo, oldDbClassInfo: oldDbClassInfo, classFile: classFile });

          // Next!
          cb && cb(null, dbClassInfo, classFile);
        });
      }
      
      // Detect whether we need to rescan the file
      fs.stat(sourceClassFilename, function(err, stat) {
        if (err) {
          cb && cb(err);
          return;
        }

        fs.exists(outputClassFilename, function(exists) {
          if (!exists || forceScan) {
            scanFile(stat);
            return;
          }
          fs.exists(outputClassFilename + "on", function(exists) {
            if (!exists) {
              scanFile(stat);
              return;
            }
            
            fs.stat(outputClassFilename, function(err, outputStat) {
              if (err) {
                cb && cb(err);
                return;
              }
  
              scanFile(stat, outputStat);
            });
          });
        });
      });
    }
Loads a class
@param className {String} the name of the class
@param forceScan {Boolean?} true if the class is to be compiled whether it needs it or not (default false)
@param cb(err, DbClassInfo)