⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tablemaker.java

📁 Checkstyle 可寻找:·不能使用的或者多余的输入 ·空格更好的地方不使用跳格符
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    * @throws <code>SymbolTableException</code>
    * @see #addImports()
    * @see #setSuperclass()
    * @see #addInterfaces()
    */
    public void finish() throws SymbolTableException {
      if ( _node != null ) {
        addImports();
        setSuperclass();
        addInterfaces();
      }
    }

    /**
    * Adds all packages and classes that are imported by this class
    * to the class for later reference
    */
    private void addImports() throws ClassImportException {
      IPackage java = new ExternalPackage("java", null);
      IPackage lang = new ExternalPackage("lang", java);
      java.addDefinition(lang);
      _def.importPackage(lang);

      Vector unprocessedImports = _def.getUnprocessedImports();
      for ( int i = 0; i < unprocessedImports.size(); i++ ) {
        SymTabAST importNode = (SymTabAST)unprocessedImports.get(i);
        SymTabAST imported = (SymTabAST)importNode.getFirstChild();
        SymTabAST lastPart = (SymTabAST)imported.getFirstChild().getNextSibling();

        DotIterator it = new DotIterator(imported);
        SymTabAST current = null;
        String className = null;
        IClass importedClass = null;

        // attempt at each token to find the class
        //   first in source
        //   then on classpath
        //
        // if there are more tokens left
        //   continue until you hit the last token
        //   if it's a star
        //     import all inner classes
        //   else
        //     import the explicitly named inner class
        // else import the class
        //
        // if no classes were found, import the package

        while(it.hasNext()) {
          current = it.nextNode();
          if (className == null) {
            className = current.getText();
          }
          else {
            if (!current.getText().equals("*")) {
              className += "." + current.getText();
            }
            else {
              break;
            }
          }
          importedClass = findOrLoadClass(className, importedClass);

          if (importedClass != null) {
            break;
          }
        }

        if (it.hasNext()) {
          boolean isImported = false;
          while(it.hasNext()) {
            current = it.nextNode();
            if (current.getText().equals("*")) {
              importInnerClasses(importedClass);
              isImported = true;
            }
            else {
              className += "$" + current.getText();
              importedClass = findOrLoadClass(className, importedClass);
            }
          }
          if (!isImported) {
            _def.importClass(importedClass);
          }
        }
        else {
          if (importedClass != null) {
            _def.importClass(importedClass);
          }
          else {
            if (current != null && current.getText().equals("*")) {
              IPackage pkg = symbolTable.getPackage(className);
              if (pkg == null) {
                pkg = getPackage(className);
              }
              _def.importPackage(pkg);
            }
            else {
              //TODO: can we safely ignore this?
              //throw new ClassImportException(className);
              ;
            }
          }
        }

        // now set definitions where appropriate
        imported.ignoreChildren();
        if ((lastPart.getType() == TokenTypes.IDENT)
            //TODO: guard added for class not loaded
            //This is OK for single file processing, but not
            //multiple files.
            && (importedClass != null)
            )
        {
          lastPart.setDefinition(importedClass, null, true);
          lastPart.setMeaningfulness(true);
        }
      }
    }

    /**
     * creates <code>ExternalPackage</code>
     * @param packageName name of the package
     * @return <code>ExternalPackage</code>
     * @see net.sourceforge.transmogrify.symtab.ExternalPackage
     */
    private ExternalPackage getPackage(String packageName) {
      return new ExternalPackage(packageName, null);
    }

    /**
     * stores the inner classes in the approriate ClassDef
     * @param outerClass
     * @return <code>void</code>
     */
    private void importInnerClasses(IClass outerClass) {
      IClass[] innerClasses = outerClass.getInnerClasses();

      for (int i = 0; i < innerClasses.length; i++) {
        _def.importClass(innerClasses[i]);
      }
    }

    /**
     * creates <code>ExternalClass</code> based on a java class
     * @param className class to be loaded
     * @return <code>IClass</code>
     * @see net.sourceforge.transmogrify.symtab.ExternalClass
     */
    private IClass loadClass(String className) {
      IClass result = null;

      try {
        Class javaClass
          = ClassManager.getClassLoader().loadClass(className);

        result = new ExternalClass(javaClass);
      }
      catch (ClassNotFoundException ignoreMe) {}

      return result;
    }

    /**
     * find a class from <code>BaseCode</code> or its parent
     * @param className name of the class to be load or found
     * @param parentClass its parent class
     * @return <code>IClass</code>
     * @see net.sourceforge.transmogrify.symtab.SymbolTable
     * @see net.sourceforge.transmogrify.symtab.IClass
     * @see #loadClass(String)
     */
    private IClass findOrLoadClass(String className, IClass parentClass) {
      IClass result = null;

      if (parentClass == null) {
        result = symbolTable.getBaseScope().getClassDefinition(className);
      }
      else {
        int index = className.lastIndexOf("$");
        if (index < 0) {
          index = className.lastIndexOf(".");
        }

        result = parentClass.getClassDefinition(className.substring(index + 1));
      }

      if (result == null) {
        result = loadClass(className);
      }

      return result;
    }

    /**
    *
    * If the class has a super class a reference to this super class
    * is added to this class.
    * @return <code>void</code>
    * @see net.sourceforge.transmogrify.symtab.ClassDef
    */
    private void setSuperclass() {
      if (_def.getTreeNode().getType() == TokenTypes.CLASS_DEF) {
        SymTabAST extendsNode = getExtendsNode(_def);
        if ( extendsNode != null ) {
          String superclassName = ASTUtil.constructDottedName(extendsNode);
          IClass superclass = _def.getClassDefinition(superclassName);
          if ( superclass != null ) {
            _def.setSuperclass( superclass );
            superclass.addSubclass( _def );
          }
        }
        else {
          _def.setSuperclass(new ExternalClass(Object.class));
        }
      }
      else {
        _def.setSuperclass(new ExternalClass(Object.class));
      }
    }

    /**
    *
    * If the class implements an interface a reference to this interface
    * is added to this class.
    * @return <code>void</code>
    * @see net.sourceforge.transmogrify.symtab.ClassDef
    */
    private void addInterfaces() {
      SymTabAST implementsClause = null;

      if (_def.getTreeNode().getType() == TokenTypes.CLASS_DEF) {
        implementsClause
          = _node.findFirstToken(TokenTypes.IMPLEMENTS_CLAUSE);
      }
      else {
        implementsClause
          = _node.findFirstToken(TokenTypes.EXTENDS_CLAUSE);
      }

      if ( implementsClause != null ) {
        SymTabAST interfaceNode = (SymTabAST)implementsClause.getFirstChild();
        while ( interfaceNode != null ) {
          IClass implemented =
            _def.getClassDefinition(interfaceNode.getText());
          if ( implemented != null ) {
            _def.addInterface( implemented );
            implemented.addImplementor( _def );
          }
        interfaceNode = (SymTabAST)(interfaceNode.getNextSibling());
        }
      }
    }
  }

  /**
   *
   * Completes a Variable by setting all required references
   *
   */
  class VariableFinisher extends DefinitionFinisher {
    VariableDef _def = null;


    /**
    *
    * Constructor. Creates a VariableFinishes from the <code>Definition</code>
    * @param def VariableDef to be finished
    * @see net.sourceforge.transmogrify.symtab.VariableDef
    */
    public VariableFinisher( Definition def ) {
      super( def );
      _def = (VariableDef)def;
    }


    /**
    *
    * Finishes the variable by setting the Type
    * @return <code>void</code>
    * @see #getType(Definition, SymTabAST)
    * @see net.sourceforge.transmogrify.symtab.VariableDef
    */
    public void finish() {

      SymTabAST typeNode = _node.findFirstToken(TokenTypes.TYPE);

      SymTabAST typeTextNode = (SymTabAST)(typeNode.getFirstChild());
      if ( typeTextNode.getType() == TokenTypes.ARRAY_DECLARATOR ) {
        typeTextNode = (SymTabAST)(typeTextNode.getFirstChild());
      }
      typeTextNode.setLine(ASTUtil.getLine( _def.getTreeNode() ));

      IClass varType = getType(_def, typeNode);
      _def.setType( varType );

    }
  }

  /**
   *
   * Completes a Variable by setting all required references
   *
   */
  class MethodFinisher extends DefinitionFinisher {
    MethodDef _def = null;


    /**
    *
    * Creates a MethodFinisher from a <code> Definition <code>
    * @param def MethodDef to be finished
    * @see net.sourceforge.transmogrify.symtab.MethodDef
    */
    public MethodFinisher( Definition def ) {
      super( def );
      _def = (MethodDef)def;
    }

    /**
    *
    * Completes a method by setting all references to return types,
    * signatures and exceptions.
    * @return <code>void</code>
    * @see #setReturnType()
    * @see #setSignature()
    * @see #setExceptionsThrown()
    */
    public void finish() {
      setReturnType();
      setSignature();
      setExceptionsThrown();
    }

    /**
    *
    * setReturnType adds a reference to the methods return type
    * to the method definition
    * @return <code>void</code>
    * @see net.sourceforge.transmogrify.symtab.MethodDef
    * @see #getType(Definition, SymTabAST)
    * @see #getTypeNode()
    */
    private void setReturnType() {
      IClass type = null;

      if ( isConstructor() ) {
        type = _def.getEnclosingClass();
      }
      else {
        type = getType(_def, getTypeNode());
      }

      _def.setType(type);
    }

    /**
    *
    * setSignature adds a reference to the methods paramaters
    * to the method definition
    * @return <code>void</code>
    * @see #makeVariableDef(SymTabAST, Definition)
    * @see VariableFinisher
    * @see net.sourceforge.transmogrify.symtab.MethodDef
    */
    private void setSignature() {
      SymTabAST parametersNode
        = _node.findFirstToken(TokenTypes.PARAMETERS);

      SymTabAST parameterNode = (SymTabAST)(parametersNode.getFirstChild());
      while ( parameterNode != null ) {
        if (parameterNode.getType() == TokenTypes.PARAMETER_DEF) {
            VariableDef parameter = makeVariableDef( parameterNode, _def );
            new VariableFinisher( parameter ).finish();
            _def.addParameter( parameter );
        }
        parameterNode = (SymTabAST)(parameterNode.getNextSibling());
      }

    }

    /**
    *
    * setExceptionsThrown adds a reference to the methods Exceptions
    * to the method definition
    * @return <code>void</code>
    * @see net.sourceforge.transmogrify.symtab.SymbolTable
    * @see net.sourceforge.transmogrify.symtab.PackageDef
    * @see net.sourceforge.transmogrify.symtab.MethodDef
    */
    private void setExceptionsThrown() {
      IClass exception = null;
      SymTabAST throwsNode
        = _node.findFirstToken(TokenTypes.LITERAL_THROWS);

      if ( throwsNode != null ) {
        SymTabAST exceptionNode = (SymTabAST)(throwsNode.getFirstChild());
        while (exceptionNode != null ) {
          if (exceptionNode.getType() == TokenTypes.DOT) {
            PackageDef pkg = symbolTable.getPackage(ASTUtil.constructPackage(exceptionNode));
            if ( pkg != null ) {
              exception = pkg.getClassDefinition(ASTUtil.constructClass(exceptionNode));
            }
          }
          else {
            exception = _def.getClassDefinition(exceptionNode.getText());
          }
          _def.addException(exception);
          exceptionNode = (SymTabAST)(exceptionNode.getNextSibling());
        }
      }

    }

    /**
    *
    * isConstructor sets the flag in the method definition to indicate
    * whether it is a constructor or not
    * @return <code>boolean</code> <code>true</code> if a node has no return type
    *                              <code>false</code> if a node has a return type
    * @see #getTypeNode()
    */
    private boolean isConstructor() {
      boolean result = false;

      if ( getTypeNode() == null ) {
        result = true;
      }

      return result;
    }

    /**
    *
    * getTypeNode returnss the <code> SymTabAST</code> node that is the
    * return type of this method
    *
    * @return <code>SymTabAST</code>
    */
    private SymTabAST getTypeNode() {
      return _node.findFirstToken(TokenTypes.TYPE);
    }
  }

  class CatchFinisher extends DefinitionFinisher {
    BlockDef _def = null;

    /**
     * constructor that takes a <code>BlockDef</code>
     * @param def <code>BlockDef</code> for the catch block
     */
    public CatchFinisher(BlockDef def) {
      super(def);
      _def = def;
    }

    /**
     * finishes definition creation
     * @return <code>void</code>
     * @see #createExceptionVariable()
     */
    public void finish() {
      createExceptionVariable();
    }

    /**
     * creates <code>VariableDef<code> and finishes creation definition for
     * arguments in the catch clause
     * @return <code>void</code>
     * @see net.sourceforge.transmogrify.symtab.VariableDef
     * @see #makeVariableDef(SymTabAST, Definition)
     * @see VariableFinisher
     */
    private void createExceptionVariable() {
      SymTabAST exceptionNode
        = _def.getTreeNode().findFirstToken(TokenTypes.PARAMETER_DEF);

      VariableDef exception = makeVariableDef(exceptionNode, _def);
      new VariableFinisher(exception).finish();
      _def.addDefinition(exception);
    }
  }

}


⌨️ 快捷键说明

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