public boolean visit(MethodDeclaration method) throws Exception {

    methodGlobalVars.add(new HashSet<String>());

    ASTNode parentDeclaration = null;
    if (!declarations.empty()) {
      parentDeclaration = declarations.peek();
    }

    // In case we are entering a nested element - just add to the deferred
    // list
    // and get out of the nested element visiting process
    if (parentDeclaration instanceof MethodDeclaration) {
      if (fLastNamespace == null) {
        deferredDeclarations.add(method);
      } else {
        deferredNamespacedDeclarations.add(method);
      }
      return false;
    }

    if (parentDeclaration instanceof InterfaceDeclaration) {
      method.setModifier(Modifiers.AccAbstract);
    }

    method.setModifiers(markAsDeprecated(method.getModifiers(), method));

    declarations.push(method);

    for (PHPSourceElementRequestorExtension visitor : extensions) {
      visitor.visit(method);
    }

    boolean visit = visitMethodDeclaration(method);

    if (visit) {
      // Process method argument (local variable) declarations:
      List<Argument> arguments = method.getArguments();
      for (Argument arg : arguments) {
        ISourceElementRequestor.FieldInfo info = new ISourceElementRequestor.FieldInfo();
        info.name = arg.getName();
        info.modifiers = Modifiers.AccPublic;
        info.nameSourceStart = arg.getNameStart();
        info.nameSourceEnd = arg.getNameEnd() - 1;
        info.declarationStart = arg.sourceStart();
        fRequestor.enterField(info);
        fRequestor.exitField(arg.sourceEnd() - 1);
      }
    }
    return visit;
  }
 private void selectOnSuper(ModuleDeclaration parsedUnit, RubySuperExpression superExpr) {
   RubyClassType selfClass =
       RubyTypeInferencingUtils.determineSelfClass(
           mixinModel, sourceModule, parsedUnit, superExpr.sourceStart());
   MethodDeclaration enclosingMethod = ASTUtils.getEnclosingMethod(wayToNode, superExpr, false);
   if (enclosingMethod != null) {
     String name = enclosingMethod.getName();
     RubyMixinClass rubyClass = mixinModel.createRubyClass(selfClass);
     RubyMixinClass superclass = rubyClass.getSuperclass();
     RubyMixinMethod method = superclass.getMethod(name);
     if (method != null) {
       IMethod[] sourceMethods = method.getSourceMethods();
       addArrayToCollection(sourceMethods, selectionElements);
     }
   }
 }
 private void selectionOnMethodDeclaration(
     ModuleDeclaration parsedUnit, MethodDeclaration methodDeclaration) {
   IModelElement elementAt = null;
   try {
     elementAt = sourceModule.getElementAt(methodDeclaration.sourceStart() + 1);
   } catch (ModelException e) {
     RubyPlugin.log(e);
   }
   if (elementAt != null) selectionElements.add(elementAt);
 }
  protected void findLocalMethods(
      char[] token, boolean canCompleteEmptyToken, List methods, List methodNames) {
    if (methods == null || methods.size() == 0) return;

    int length = token.length;
    if (canCompleteEmptyToken || length > 0) {
      for (int i = 0; i < methods.size(); i++) {
        MethodDeclaration method = (MethodDeclaration) methods.get(i);
        String name = ((String) (methodNames.get(i)));
        if (length <= name.length() && CharOperation.prefixEquals(token, name, false)) {
          int relevance = computeBaseRelevance();
          relevance += computeRelevanceForInterestingProposal();
          relevance += computeRelevanceForCaseMatching(token, name);
          relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no

          // accept result
          this.noProposal = false;
          if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
            CompletionProposal proposal =
                this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
            // proposal.setSignature(getSignature(typeBinding));
            // proposal.setPackageName(q);
            // proposal.setTypeName(displayName);
            List arguments = method.getArguments();
            if (arguments != null && arguments.size() > 0) {
              String[] args = new String[arguments.size()];
              for (int j = 0; j < arguments.size(); ++j) {
                args[j] = ((Argument) arguments.get(j)).getName();
              }
              proposal.setParameterNames(args);
            }

            proposal.setName(name);
            proposal.setCompletion(name);
            // proposal.setFlags(Flags.AccDefault);
            proposal.setRelevance(relevance);
            accept(proposal);
          }
        }
      }
    }
  }
 private String[] processParameterTypes(MethodDeclaration methodDeclaration) {
   List<?> args = methodDeclaration.getArguments();
   PHPDocBlock docBlock = ((PHPMethodDeclaration) methodDeclaration).getPHPDoc();
   String[] parameterType = new String[args.size()];
   for (int a = 0; a < args.size(); a++) {
     Argument arg = (Argument) args.get(a);
     if (arg instanceof FormalParameter) {
       SimpleReference type = ((FormalParameter) arg).getParameterType();
       if (type != null) {
         parameterType[a] = type.getName();
       } else if (docBlock != null) {
         for (PHPDocTag tag : docBlock.getTags(PHPDocTag.PARAM)) {
           if (tag.isValidParamTag()
               && tag.getVariableReference().getName().equals(arg.getName())) {
             parameterType[a] = tag.getSingleTypeReference().getName();
             break;
           }
         }
       }
     }
   }
   return parameterType;
 }
 private String[] processParamterTypes(MethodDeclaration methodDeclaration) {
   final List args = methodDeclaration.getArguments();
   final PHPDocBlock docBlock = ((PHPMethodDeclaration) methodDeclaration).getPHPDoc();
   final String[] parameterType = new String[args.size()];
   for (int a = 0; a < args.size(); a++) {
     final Argument arg = (Argument) args.get(a);
     if (arg instanceof FormalParameter) {
       final SimpleReference type = ((FormalParameter) arg).getParameterType();
       if (type != null) {
         parameterType[a] = type.getName();
       } else if (docBlock != null) {
         for (final PHPDocTag tag : docBlock.getTags(PHPDocTag.PARAM)) {
           final SimpleReference[] refs = tag.getReferences();
           if (refs.length == 2) {
             if (refs[0].getName().equals(arg.getName())) {
               parameterType[a] = refs[1].getName();
             }
           }
         }
       }
     }
   }
   return parameterType;
 }
  private boolean visitMethodDeclaration(MethodDeclaration method) throws Exception {
    this.fNodes.push(method);
    List<?> args = method.getArguments();

    String[] parameter = new String[args.size()];
    String[] initializers = new String[args.size()];
    for (int a = 0; a < args.size(); a++) {
      Argument arg = (Argument) args.get(a);
      parameter[a] = arg.getName();
      if (arg.getInitialization() != null) {
        if (arg.getInitialization() instanceof Literal) {
          Literal scalar = (Literal) arg.getInitialization();
          initializers[a] = scalar.getValue();
        } else {
          initializers[a] = DEFAULT_VALUE;
        }
      }
    }

    ISourceElementRequestor.MethodInfo mi = new ISourceElementRequestor.MethodInfo();
    mi.parameterNames = parameter;
    mi.name = method.getName();
    mi.modifiers = method.getModifiers();
    mi.nameSourceStart = method.getNameStart();
    mi.nameSourceEnd = method.getNameEnd() - 1;
    mi.declarationStart = method.sourceStart();
    mi.parameterInitializers = initializers;

    modifyMethodInfo(method, mi);

    fInfoStack.push(mi);
    this.fRequestor.enterMethod(mi);

    this.fInMethod = true;
    this.fCurrentMethod = method;
    return true;
  }
  @SuppressWarnings("unchecked")
  public boolean visit(MethodDeclaration method) throws Exception {
    fNodes.push(method);
    methodGlobalVars.add(new HashSet<String>());
    int modifiers = method.getModifiers();
    PHPDocBlock doc = null;
    if (method instanceof IPHPDocAwareDeclaration) {
      IPHPDocAwareDeclaration declaration = (IPHPDocAwareDeclaration) method;
      doc = declaration.getPHPDoc();
    }
    Declaration parentDeclaration = null;
    if (!declarations.empty()) {
      parentDeclaration = declarations.peek();
    }
    declarations.push(method);

    // In case we are entering a nested element - just add to the deferred
    // list
    // and get out of the nested element visiting process
    if (parentDeclaration instanceof MethodDeclaration) {
      if (fCurrentNamespace == null) {
        deferredDeclarations.add(method);
      } else {
        deferredNamespacedDeclarations.add(method);
      }
      return visitGeneral(method);
    }

    if (parentDeclaration instanceof InterfaceDeclaration) {
      method.setModifier(Modifiers.AccAbstract);
    }

    String methodName = method.getName();

    // Determine whether this method represents constructor:
    if (methodName.equalsIgnoreCase(CONSTRUCTOR_NAME)
        || (parentDeclaration instanceof ClassDeclaration
            && methodName.equalsIgnoreCase(((ClassDeclaration) parentDeclaration).getName()))) {
      modifiers |= IPHPModifiers.Constructor;
    }

    if (parentDeclaration == null
        || (parentDeclaration instanceof TypeDeclaration
            && parentDeclaration == fCurrentNamespace)) {
      modifiers |= Modifiers.AccGlobal;
    }
    if (!Flags.isPrivate(modifiers)
        && !Flags.isProtected(modifiers)
        && !Flags.isPublic(modifiers)) {
      modifiers |= Modifiers.AccPublic;
    }

    modifiers = markAsDeprecated(modifiers, method);

    StringBuilder metadata = new StringBuilder();
    if (fCurrentQualifier != null) {
      metadata.append(fCurrentQualifierCounts.get(fCurrentQualifier));
      metadata.append(";"); // $NON-NLS-1$
    }
    List<Argument> arguments = method.getArguments();
    if (arguments != null) {
      Iterator<Argument> i = arguments.iterator();
      while (i.hasNext()) {
        Argument arg = (Argument) i.next();

        String type = NULL_VALUE;
        if (arg instanceof FormalParameter) {
          FormalParameter fp = (FormalParameter) arg;
          if (fp.getParameterType() != null) {
            if (fp.getParameterType().getName() != null) {
              type = fp.getParameterType().getName();
            }
          }
        }
        if (type == NULL_VALUE && doc != null) {
          type = getParamType(doc, arg.getName(), type);
        }

        metadata.append(type);
        metadata.append(PARAMETER_SEPERATOR);
        metadata.append(arg.getName());
        metadata.append(PARAMETER_SEPERATOR);
        String defaultValue = NULL_VALUE;
        if (arg.getInitialization() != null) {
          if (arg.getInitialization() instanceof Literal) {
            Literal scalar = (Literal) arg.getInitialization();
            defaultValue = scalar.getValue();
          } else {
            defaultValue = DEFAULT_VALUE;
          }
        }
        metadata.append(defaultValue);
        if (i.hasNext()) {
          metadata.append(","); // $NON-NLS-1$
        }
      }
    }

    // Add method declaration:
    modifyDeclaration(
        method,
        new DeclarationInfo(
            IModelElement.METHOD,
            modifiers,
            method.sourceStart(),
            method.sourceEnd() - method.sourceStart(),
            method.getNameStart(),
            method.getNameEnd() - method.getNameStart(),
            methodName,
            metadata.length() == 0 ? null : metadata.toString(),
            encodeDocInfo(method),
            fCurrentQualifier,
            fCurrentParent));

    for (PhpIndexingVisitorExtension visitor : extensions) {
      visitor.visit(method);
    }

    return visitGeneral(method);
  }
  @Override
  @SuppressWarnings("unchecked")
  public boolean visit(MethodDeclaration s) throws Exception {
    IProject project = sourceModule.getScriptProject().getProject();
    if (project == null || !project.isAccessible() || !project.hasNature(TwigNature.NATURE_ID)) {
      return false;
    }
    if (!methods.contains(s)) methods.add(s);

    if (s instanceof PHPMethodDeclaration) {

      PHPMethodDeclaration phpMethod = (PHPMethodDeclaration) s;

      if (inTwigExtension && phpMethod.getName().equals(TwigCoreConstants.GET_FILTERS)) {

        phpMethod.traverse(
            new PHPASTVisitor() {

              @Override
              public boolean visit(ArrayElement s) throws Exception {

                Expression key = s.getKey();
                Expression value = s.getValue();

                if (key == null | value == null) {
                  return false;
                }

                if (key.getClass() == Scalar.class
                    && value.getClass() == ClassInstanceCreation.class) {

                  Scalar name = (Scalar) key;
                  ClassInstanceCreation filterClass = (ClassInstanceCreation) value;

                  CallArgumentsList ctorParams = filterClass.getCtorParams();
                  Object child = ctorParams.getChilds().get(0);

                  if (child instanceof VariableReference
                      && ((VariableReference) child).getName().equals("$this")
                      && filterClass
                          .getClassName()
                          .toString()
                          .equals((TwigCoreConstants.TWIG_FILTER_METHOD))) {

                    if (ctorParams.getChilds().size() > 2
                        && ctorParams.getChilds().get(1) instanceof Scalar) {
                      Scalar internal = (Scalar) ctorParams.getChilds().get(1);
                      String elemName = name.getValue().replaceAll("['\"]", "");
                      Filter filter = new Filter(elemName);
                      filter.setInternalFunction(internal.getValue().replaceAll("['\"]", ""));
                      filter.setPhpClass(currentClass.getName());
                      filters.add(filter);
                    }
                  }

                  if (!(child instanceof Scalar)) {
                    return true;
                  }

                  Scalar internal = (Scalar) child;

                  if (filterClass
                      .getClassName()
                      .toString()
                      .equals(TwigCoreConstants.TWIG_FILTER_FUNCTION)) {

                    String elemName = name.getValue().replaceAll("['\"]", "");

                    Filter filter = new Filter(elemName);
                    filter.setInternalFunction(internal.getValue().replaceAll("['\"]", ""));
                    filter.setPhpClass(currentClass.getName());

                    filters.add(filter);
                  }
                }
                return true;
              }
            });

      } else if (inTwigExtension && TwigCoreConstants.GET_TESTS.equals(s.getName())) {

        phpMethod.traverse(
            new PHPASTVisitor() {

              @Override
              public boolean visit(ArrayElement s) throws Exception {

                Expression key = s.getKey();
                Expression value = s.getValue();

                if (key == null || value == null) return false;

                if (key.getClass() == Scalar.class
                    && value.getClass() == ClassInstanceCreation.class) {

                  Scalar name = (Scalar) key;
                  ClassInstanceCreation functionClass = (ClassInstanceCreation) value;

                  CallArgumentsList args = functionClass.getCtorParams();
                  if (!(args.getChilds().get(0) instanceof Scalar)) {
                    return true;
                  }
                  Scalar internalFunction = (Scalar) args.getChilds().get(0);

                  if (internalFunction == null) return true;

                  if (functionClass
                      .getClassName()
                      .toString()
                      .equals(TwigCoreConstants.TWIG_TEST_FUNCTION)) {

                    String elemName = name.getValue().replaceAll("['\"]", "");

                    JSONObject metadata = new JSONObject();
                    metadata.put(TwigType.PHPCLASS, currentClass.getName());

                    Test test = new Test(elemName);
                    test.setPhpClass(currentClass.getName());
                    test.setInternalFunction(internalFunction.getValue().replaceAll("['\"]", ""));
                    tests.add(test);
                  }
                }
                return true;
              }
            });

      } else if (inTwigExtension && TwigCoreConstants.GET_FUNCTIONS.equals(s.getName())) {

        phpMethod.traverse(
            new PHPASTVisitor() {
              @Override
              public boolean visit(ArrayElement s) throws Exception {

                Expression key = s.getKey();
                Expression value = s.getValue();

                if (key == null || value == null) {
                  return false;
                }

                if (key.getClass() == Scalar.class
                    && value.getClass() == ClassInstanceCreation.class) {

                  Scalar name = (Scalar) key;
                  ClassInstanceCreation functionClass = (ClassInstanceCreation) value;
                  CallArgumentsList args = functionClass.getCtorParams();
                  String functionClassName = functionClass.getClassName().toString();
                  int index = -1;

                  if (functionClassName.equals(TwigCoreConstants.TWIG_FUNCTION_FUNCTION)) {
                    index = 0;
                  } else if (functionClassName.equals(TwigCoreConstants.TWIG_FUNCTION_METHOD)) {
                    index = 1;
                  }

                  if (index > -1 && args.getChilds().get(index) instanceof Scalar) {

                    Scalar internalFunction = (Scalar) args.getChilds().get(index);

                    if (internalFunction == null) {
                      return true;
                    }

                    String elemName = name.getValue().replaceAll("['\"]", "");
                    JSONObject metadata = new JSONObject();
                    metadata.put(TwigType.PHPCLASS, currentClass.getName());

                    Function function = new Function(elemName);
                    function.setPhpClass(currentClass.getName());
                    function.setInternalFunction(
                        internalFunction.getValue().replaceAll("['\"]", ""));
                    functions.add(function);
                  }
                }
                return true;
              }
            });

      } else if (inTokenParser && TwigCoreConstants.PARSE_TOKEN_METHOD.equals(s.getName())) {

        inTagParseMethod = true;

      } else if (inTokenParser && TwigCoreConstants.PARSE_GET_TAG_METHOD.equals(s.getName())) {

        phpMethod.traverse(
            new PHPASTVisitor() {
              @Override
              public boolean visit(ReturnStatement s) throws Exception {
                if (s.getExpr().getClass() == Scalar.class) {
                  Scalar scalar = (Scalar) s.getExpr();
                  tag.setStartTag(scalar.getValue().replaceAll("['\"]", ""));
                }
                return false;
              }
            });
      }
    }

    return false;
  }
  @Override
  public boolean endvisit(ModuleDeclaration s) throws Exception {
    for (Test test : tests) {
      for (MethodDeclaration method : methods) {
        if (method.getName().equals(test.getInternalFunction())) {

          PHPMethodDeclaration phpMethod = (PHPMethodDeclaration) method;
          PHPDocBlock doc = phpMethod.getPHPDoc();

          if (doc != null) {
            test.addDoc(doc);
          }

          Logger.debugMSG(
              "indexing test tag: "
                  + test.getElementName()
                  + " with metadata: "
                  + test.getMetadata());

          ReferenceInfo info =
              new ReferenceInfo(
                  ITwigModelElement.TEST, 0, 0, test.getElementName(), test.getMetadata(), null);
          addReferenceInfo(info);
        }
      }
    }

    for (Function function : functions) {

      for (MethodDeclaration method : methods) {

        if (method.getName().equals(function.getInternalFunction())) {

          PHPMethodDeclaration phpMethod = (PHPMethodDeclaration) method;
          PHPDocBlock doc = phpMethod.getPHPDoc();

          if (doc != null) {
            function.addDoc(doc);
          }

          function.addArgs(method.getArguments());

          Logger.debugMSG(
              "indexing function: "
                  + function.getElementName()
                  + " with metadata: "
                  + function.getMetadata());
          ReferenceInfo info =
              new ReferenceInfo(
                  ITwigModelElement.FUNCTION,
                  0,
                  0,
                  function.getElementName(),
                  function.getMetadata(),
                  null);
          addReferenceInfo(info);
        }
      }
    }

    for (Filter filter : filters) {

      for (MethodDeclaration method : methods) {

        if (method.getName().equals(filter.getInternalFunction())) {

          PHPMethodDeclaration phpMethod = (PHPMethodDeclaration) method;
          PHPDocBlock doc = phpMethod.getPHPDoc();

          if (doc != null) {
            filter.addDoc(doc);
          }

          filter.addArgs(method.getArguments());

          Logger.debugMSG(
              "indexing filter: "
                  + filter.getElementName()
                  + " with metadata: "
                  + filter.getMetadata());
          ReferenceInfo info =
              new ReferenceInfo(
                  ITwigModelElement.FILTER,
                  0,
                  0,
                  filter.getElementName(),
                  filter.getMetadata(),
                  null);
          addReferenceInfo(info);
        }
      }
    }

    return true;
  }