Package org.eclipse.php.internal.core.typeinference

Source Code of org.eclipse.php.internal.core.typeinference.DefineMethodUtils$FunctionInvocationSearcher

package org.eclipse.php.internal.core.typeinference;

import java.util.*;

import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.expressions.CallArgumentsList;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.statements.Statement;
import org.eclipse.dltk.core.*;
import org.eclipse.php.internal.core.Logger;
import org.eclipse.php.internal.core.compiler.ast.nodes.*;
import org.eclipse.php.internal.core.compiler.ast.parser.ASTUtils;

public class DefineMethodUtils {

  public static String DEFINE = "define"; //$NON-NLS-1$

  public static PHPCallExpression getDefineNodeByField(
      ModuleDeclaration module, IField field) throws ModelException {
    FunctionInvocationSearcher visitor = new FunctionInvocationSearcher(
        module, field);
    try {
      module.traverse(visitor);
    } catch (Exception e) {
      if (DLTKCore.DEBUG) {
        Logger.logException(e);
      }
    }
    return visitor.getResult();
  }

  public static PHPDocBlock getDefinePHPDocBlockByField(
      ModuleDeclaration module, IField field) throws ModelException {
    if (module instanceof PHPModuleDeclaration) {
      if (getDefineNodeByField(module, field) == null) {
        return null;
      }
      PHPModuleDeclaration phpModule = (PHPModuleDeclaration) module;
      List<PHPDocBlock> phpDocBlocks = phpModule.getPhpDocBlocks();
      if (phpDocBlocks != null && !phpDocBlocks.isEmpty()) {
        List statements = phpModule.getStatements();
        ISourceRange sourceRange = field.getNameRange();
        ASTNode previousStatement = null;
        for (Iterator iterator = statements.iterator(); iterator
            .hasNext();) {
          ASTNode statement = (ASTNode) iterator.next();
          if (statement.sourceStart() <= sourceRange.getOffset()
              && statement.sourceEnd() >= (sourceRange
                  .getOffset() + sourceRange.getLength())) {
            // define statement
            phpDocBlocks = getPHPDocBlockBetweenStatements(
                previousStatement, statement, phpDocBlocks);
            if (phpDocBlocks.isEmpty()) {
              return null;
            }
            Collections.sort(phpDocBlocks,
                new Comparator<PHPDocBlock>() {
                  public int compare(PHPDocBlock o1,
                      PHPDocBlock o2) {
                    return o1.sourceStart()
                        - o2.sourceStart();
                  }
                });
            return phpDocBlocks.get(phpDocBlocks.size() - 1);
          }
          previousStatement = statement;
        }
        PHPCallExpression callExpression = getDefineNodeByField(
            phpModule, field);
        callExpression.getReceiver();
      }
    }
    return null;
  }

  private static List<PHPDocBlock> getPHPDocBlockBetweenStatements(
      ASTNode previousStatement, ASTNode statement,
      List<PHPDocBlock> phpDocBlocks) {
    if (previousStatement == null) {
      return getPHPDocBlockBetweenRange(-1, statement.sourceStart(),
          phpDocBlocks);
    } else {
      return getPHPDocBlockBetweenRange(previousStatement.sourceEnd(),
          statement.sourceStart(), phpDocBlocks);
    }
  }

  private static List<PHPDocBlock> getPHPDocBlockBetweenRange(int start,
      int end, List<PHPDocBlock> phpDocBlocks) {
    List<PHPDocBlock> result = new ArrayList<PHPDocBlock>();
    for (Iterator iterator = phpDocBlocks.iterator(); iterator.hasNext();) {
      PHPDocBlock phpDocBlock = (PHPDocBlock) iterator.next();
      if (phpDocBlock.sourceStart() >= start
          && phpDocBlock.sourceEnd() <= end) {
        result.add(phpDocBlock);
      }
    }
    return result;
  }

  public static class FunctionInvocationSearcher extends ASTVisitor {

    private int bestScore = Integer.MAX_VALUE;
    private int modelStart;
    private int modelEnd;
    private int modelCutoffStart;
    private int modelCutoffEnd;
    private String elementName;
    private PHPCallExpression result;

    public FunctionInvocationSearcher(ModuleDeclaration moduleDeclaration,
        IMember modelElement) throws ModelException {
      ISourceRange sourceRange = modelElement.getSourceRange();
      modelStart = sourceRange.getOffset();
      modelEnd = modelStart + sourceRange.getLength();
      modelCutoffStart = modelStart - 100;
      modelCutoffEnd = modelEnd + 100;
      elementName = modelElement.getElementName();
    }

    public PHPCallExpression getResult() {
      return result;
    }

    protected void checkElementDeclaration(PHPCallExpression s) {
      if (s.getName().equals(DEFINE)) {
        CallArgumentsList args = s.getArgs();
        if (args != null && args.getChilds() != null) {
          ASTNode argument = (ASTNode) args.getChilds().get(0);
          if (argument instanceof Scalar) {
            String constant = ASTUtils
                .stripQuotes(((Scalar) argument).getValue());
            if (constant.equals(elementName)) {
              int astStart = s.sourceStart();
              int astEnd = s.sourceEnd();
              int diff1 = modelStart - astStart;
              int diff2 = modelEnd - astEnd;
              int score = diff1 * diff1 + diff2 * diff2;
              if (score < bestScore) {
                bestScore = score;
                result = s;
              }
            }
          }

        }
      }
    }

    protected boolean interesting(ASTNode s) {
      if (s.sourceStart() < 0 || s.sourceEnd() < s.sourceStart()) {
        return true;
      }
      if (modelCutoffEnd < s.sourceStart()
          || modelCutoffStart >= s.sourceEnd()) {
        return false;
      }
      return true;
    }

    public boolean visit(Expression s) throws Exception {
      if (!interesting(s)) {
        return false;
      }
      return true;
    }

    public boolean visit(Statement s) throws Exception {
      if (!interesting(s)) {
        return false;
      }
      if (s instanceof ExpressionStatement) {
        if (((ExpressionStatement) s).getExpr() instanceof PHPCallExpression) {
          checkElementDeclaration((PHPCallExpression) ((ExpressionStatement) s)
              .getExpr());

        }
      }
      return true;
    }

    public boolean visit(ModuleDeclaration s) throws Exception {
      if (!interesting(s)) {
        return false;
      }
      return true;
    }

    public boolean visitGeneral(ASTNode s) throws Exception {
      if (!interesting(s)) {
        return false;
      }
      return true;
    }
  }
}
TOP

Related Classes of org.eclipse.php.internal.core.typeinference.DefineMethodUtils$FunctionInvocationSearcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.