rootdocimpl.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 1,314 行 · 第 1/3 页

JAVA
1,314
字号
      classDocMap.put(cd.qualifiedName(), cd);   }   public void addClassDocRecursive(ClassDoc cd) {      classDocMap.put(cd.qualifiedName(), cd);      ClassDoc[] innerClasses = cd.innerClasses(false);      for (int i=0; i<innerClasses.length; ++i) {         addClassDocRecursive(innerClasses[i]);      }   }   public void addPackageDoc(PackageDoc pd) {      packageDocMap.put(pd.name(), pd);   }   public PackageDocImpl getPackageDoc(String name) {      return (PackageDocImpl)packageDocMap.get(name);   }   public ClassDocImpl getClassDoc(String qualifiedName) {      return (ClassDocImpl)classDocMap.get(qualifiedName);   }   class ScheduledClass {      ClassDoc contextClass;      String qualifiedName;      ScheduledClass(ClassDoc contextClass, String qualifiedName) {	 this.contextClass=contextClass;	 this.qualifiedName=qualifiedName;      }            public String toString() { return "ScheduledClass{"+qualifiedName+"}"; }   }   public void scheduleClass(ClassDoc context, String qualifiedName) throws ParseException, IOException {      if (classDocMap.get(qualifiedName)==null) {	 //Debug.log(9,"Scheduling "+qualifiedName+", context "+context+".");         //System.err.println("Scheduling " + qualifiedName + ", context " + context);	 scheduledClasses.add(new ScheduledClass(context, qualifiedName));      }   }   /**    *  Load all classes that were implictly referenced by the classes    *  (already loaded) that the user explicitly specified on the    *  command line.    *    *  For example, if the user generates Documentation for his simple    *  'class Test {}', which of course 'extends java.lang.Object',    *  then 'java.lang.Object' is implicitly referenced because it is    *  the base class of Test.    *    *  Gjdoc needs a ClassDocImpl representation of all classes    *  implicitly referenced through derivation (base class),    *  or implementation (interface), or field type, method argument    *  type, or method return type.    *    *  The task of this method is to ensure that Gjdoc has all this    *  information at hand when it exits.    *    *     */   public void loadScheduledClasses(Parser parser) throws ParseException, IOException {      // Because the referenced classes could in turn reference other      // classes, this method runs as long as there are still unloaded      // classes.      while (!scheduledClasses.isEmpty()) {	 // Make a copy of scheduledClasses and empty it. This 	 // prevents any Concurrent Modification issues.	 // As the copy won't need to grow (as it won't change)	 // we make it an Array for performance reasons.	 ScheduledClass[] scheduledClassesArr = (ScheduledClass[])scheduledClasses.toArray(new ScheduledClass[0]);	 scheduledClasses.clear();	 // Load each class specified in our array copy	 	 for (int i=0; i<scheduledClassesArr.length; ++i) {	    // The name of the class we are looking for. This name	    // needs not be fully qualified.	    	    String scheduledClassName=scheduledClassesArr[i].qualifiedName;	    // The ClassDoc in whose context the scheduled class was looked for.	    // This is necessary in order to resolve non-fully qualified 	    // class names.	    ClassDoc scheduledClassContext=scheduledClassesArr[i].contextClass;	    // If there already is a class doc with this name, skip. There's	    // nothing to do for us.	    if (classDocMap.get(scheduledClassName)!=null) {	       continue;	    }	    try {	       // Try to load the class               //printNotice("Trying to load " + scheduledClassName);	       loadScheduledClass(parser, scheduledClassName, scheduledClassContext);	    }	    catch (ParseException e) {	       /**********************************************************               // Check whether the following is necessary at all.	       if (scheduledClassName.indexOf('.')>0) {	       // Maybe the dotted notation doesn't mean a package	       // name but instead an inner class, as in 'Outer.Inner'.	       // so let's assume this and try to load the outer class.		  String outerClass="";		  for (StringTokenizer st=new StringTokenizer(scheduledClassName,"."); st.hasMoreTokens(); ) {		     if (outerClass.length()>0) outerClass+=".";		     outerClass+=st.nextToken();		     if (!st.hasMoreTokens()) break;		     try {			loadClass(outerClass);			//FIXME: shouldn't this be loadScheduledClass(outerClass, scheduledClassContext); ???			continue;		     }		     catch (Exception ee) {		     // Ignore: try next level		     }		  }	       }	       **********************************************************/	       // If we arrive here, the class could not be found	       printWarning("Couldn't load class "+scheduledClassName+" referenced by "+scheduledClassContext);	       //FIXME: shouldn't this be throw new Error("cannot load: "+scheduledClassName);	    }	 }      }   }   private void loadScheduledClass(Parser parser, String scheduledClassName, ClassDoc scheduledClassContext) throws ParseException, IOException {      ClassDoc loadedClass=(ClassDoc)scheduledClassContext.findClass(scheduledClassName);      if (loadedClass==null || loadedClass instanceof ClassDocProxy) {	 ClassDoc classDoc = findScheduledClassFile(scheduledClassName, scheduledClassContext);         if (null != classDoc) {            if (classDoc instanceof ClassDocReflectedImpl) {               Main.getRootDoc().addClassDocRecursive(classDoc);            }            if (Main.DESCEND_SUPERCLASS                && null != classDoc.superclass()                 && (classDoc.superclass() instanceof ClassDocProxy)) {               scheduleClass(classDoc, classDoc.superclass().qualifiedName());            }         }         else {	    // It might be an inner class of one of the outer/super classes.	    // But we can only check that when they are all fully loaded.	    boolean retryLater = false;	    int numberOfProcessedFilesBefore = parser.getNumberOfProcessedFiles();	    ClassDoc cc = scheduledClassContext.containingClass();	    while (cc != null && !retryLater) {	       ClassDoc sc = cc.superclass();	       while (sc != null && !retryLater) {		  if (sc instanceof ClassDocProxy) {		     ((ClassDocImpl)cc).resolve();		     retryLater = true;		  }		  sc = sc.superclass();	       }	       cc = cc.containingClass();	    }	    // Now that outer/super references have been resolved, try again	    // to find the class.	    loadedClass = (ClassDoc)scheduledClassContext.findClass(scheduledClassName);	    int numberOfProcessedFilesAfter = parser.getNumberOfProcessedFiles();	    boolean filesWereProcessed = numberOfProcessedFilesAfter > numberOfProcessedFilesBefore;	    // Only re-schedule class if additional files have been processed	    // If there haven't, there's no point in re-scheduling.	    // Will avoid infinite loops of re-scheduling	    if (null == loadedClass && retryLater && filesWereProcessed)	       scheduleClass(scheduledClassContext, scheduledClassName);	    /* A warning needn't be emitted - this is normal, can happen	       if the scheduled class is in a package which is not	       included on the command line.	       else if (null == loadedClass)	       printWarning("Can't find scheduled class '"	       + scheduledClassName	       + "' in context '"	       + scheduledClassContext.qualifiedName()	       + "'");	    */	 }      }   }   private static interface ResolvedImport   {      public String match(String name);      public boolean mismatch(String name);      public ClassDoc tryFetch(String name);   }   private class ResolvedImportNotFound      implements ResolvedImport   {      private String importSpecifier;      private String name;      ResolvedImportNotFound(String importSpecifier)      {         this.importSpecifier = importSpecifier;         int ndx = importSpecifier.lastIndexOf('.');         if (ndx >= 0) {            this.name = importSpecifier.substring(ndx + 1);         }         else {            this.name = importSpecifier;         }      }      public String toString()      {         return "ResolvedImportNotFound{" + importSpecifier + "}";      }      public String match(String name)      {	 if (name.equals(this.name))	    return this.name;	 // FIXME: note that we don't handle on-demand imports here.         return null;      }      public boolean mismatch(String name)      {         return true; // FIXME!      }      public ClassDoc tryFetch(String name)      {         return null;      }   }   private class ResolvedImportPackageFile      implements ResolvedImport   {      private Set topLevelClassNames;      private File packageFile;      private String packageName;      private Map cache = new HashMap();      ResolvedImportPackageFile(File packageFile, String packageName)      {         this.packageFile = packageFile;         this.packageName = packageName;         topLevelClassNames = new HashSet();         File[] files = packageFile.listFiles();         for (int i=0; i<files.length; ++i) {            if (!files[i].isDirectory() && files[i].getName().endsWith(".java")) {               String topLevelClassName = files[i].getName();               topLevelClassName                  = topLevelClassName.substring(0, topLevelClassName.length() - 5);               topLevelClassNames.add(topLevelClassName);            }         }      }      public String match(String name)      {         ClassDoc loadedClass = classNamed(packageName + "." + name);         if (null != loadedClass) {            return loadedClass.qualifiedName();         }         else {            String topLevelName = name;            int ndx = topLevelName.indexOf('.');            String innerClassName = null;            if (ndx > 0) {               innerClassName = topLevelName.substring(ndx + 1);               topLevelName = topLevelName.substring(0, ndx);            }                        if (topLevelClassNames.contains(topLevelName)) {               //System.err.println(this + ".match returns " + packageName + "." + name);               return packageName + "." + name;            }            // FIXME: inner classes            else {               return null;            }         }      }      public boolean mismatch(String name)      {         return null == match(name);      }      public ClassDoc tryFetch(String name)      {         ClassDoc loadedClass = classNamed(packageName + "." + name);         if (null != loadedClass) {            return loadedClass;         }         else if (null != match(name)) {            String topLevelName = name;            int ndx = topLevelName.indexOf('.');            String innerClassName = null;            if (ndx > 0) {               innerClassName = topLevelName.substring(ndx + 1);               topLevelName = topLevelName.substring(0, ndx);            }            ClassDoc topLevelClass = (ClassDoc)cache.get(topLevelName);            if (null == topLevelClass) {               File classFile = new File(packageFile, topLevelName + ".java");               try {                  // FIXME: inner classes                  topLevelClass = parser.processSourceFile(classFile, false, sourceEncoding, null);               }               catch (Exception ignore) {                  printWarning("Could not parse source file " + classFile);               }               cache.put(topLevelName, topLevelClass);            }            if (null == innerClassName) {               return topLevelClass;            }            else {               return getInnerClass(topLevelClass, innerClassName);            }         }         else {            return null;         }      }      public String toString()      {         return "ResolvedImportPackageFile{" + packageFile + "," + packageName + "}";      }   }   private ClassDoc getInnerClass(ClassDoc topLevelClass, String innerClassName)   {      StringTokenizer st = new StringTokenizer(innerClassName, ".");   outer:            while (st.hasMoreTokens()) {         String innerClassNameComponent = st.nextToken();         ClassDoc[] innerClasses = topLevelClass.innerClasses();         for (int i=0; i<innerClasses.length; ++i) {            if (innerClasses[i].name().equals(innerClassNameComponent)) {               topLevelClass = innerClasses[i];               continue outer;            }         }         printWarning("Could not find inner class " + innerClassName + " in class " + topLevelClass.qualifiedName());         return null;      }      return topLevelClass;   }   private class ResolvedImportClassFile      implements ResolvedImport   {      private File classFile;      private String innerClassName;      private String name;      private ClassDoc classDoc;      private boolean alreadyFetched;      private String qualifiedName;      ResolvedImportClassFile(File classFile, String innerClassName, String name, String qualifiedName)      {         this.classFile = classFile;         this.innerClassName = innerClassName;         this.name = name;         this.qualifiedName = qualifiedName;      }      public String toString()      {         return "ResolvedImportClassFile{" + classFile + "," + innerClassName +  "}";      }      public String match(String name)      {         String topLevelName = name;         int ndx = topLevelName.indexOf('.');         String _innerClassName = null;         if (ndx > 0) {            _innerClassName = topLevelName.substring(ndx + 1);            topLevelName = topLevelName.substring(0, ndx);         }         if (this.name.equals(topLevelName)) {            if (null == _innerClassName) {               return qualifiedName;            }            else {               return qualifiedName + "." + _innerClassName;            }         }         else {            return null;         }      }      public boolean mismatch(String name)      {         return null == match(name);      }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?