Package org.eclipse.php.internal.core.index

Source Code of org.eclipse.php.internal.core.index.PhpElementResolver$IndexMethod

/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.core.index;

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import org.eclipse.dltk.ast.Modifiers;
import org.eclipse.dltk.core.*;
import org.eclipse.dltk.core.SourceRange;
import org.eclipse.dltk.core.index2.IElementResolver;
import org.eclipse.dltk.internal.core.*;
import org.eclipse.php.core.compiler.IPHPModifiers;
import org.eclipse.php.core.compiler.PHPFlags;
import org.eclipse.php.internal.core.Constants;
import org.eclipse.php.internal.core.Logger;
import org.eclipse.php.internal.core.model.IncludeField;

public class PhpElementResolver implements IElementResolver {

  private static final Pattern SEPARATOR_PATTERN = Pattern.compile(","); //$NON-NLS-1$
  private static final String[] EMPTY = new String[0];

  public IModelElement resolve(int elementType, int flags, int offset,
      int length, int nameOffset, int nameLength, String elementName,
      String metadata, String doc, String qualifier, String parent,
      ISourceModule sourceModule) {

    ModelElement parentElement = (ModelElement) sourceModule;
    if (qualifier != null) {
      // namespace:
      parentElement = new IndexType(parentElement, qualifier,
          Modifiers.AccNameSpace, 0, 0, 0, 0, null, doc);
    }
    if (parent != null) {
      parentElement = new SourceType(parentElement, parent);
    }

    switch (elementType) {
    case IModelElement.TYPE:
      String[] superClassNames = null;
      if (metadata != null) {
        superClassNames = SEPARATOR_PATTERN.split(metadata);
      }
      return new IndexType(parentElement, elementName, flags, offset,
          length, nameOffset, nameLength, superClassNames, doc);

    case IModelElement.METHOD:
      String[] parameters;
      if (metadata != null) {
        parameters = SEPARATOR_PATTERN.split(metadata);
      } else {
        parameters = EMPTY;
      }
      return new IndexMethod(parentElement, elementName, flags, offset,
          length, nameOffset, nameLength, parameters, doc);

    case IModelElement.FIELD:
      return new IndexField(parentElement, elementName, flags, offset,
          length, nameOffset, nameLength, doc);

    case IModelElement.IMPORT_DECLARATION:
      // XXX: replace with import declaration element
      return new IncludeField(parentElement, metadata);

    default:
      Logger.log(Logger.WARNING, PhpElementResolver.class.getName()
          + ": Unsupported element type (" + elementType + ")"); //$NON-NLS-1$ //$NON-NLS-2$
    }
    return null;
  }

  /**
   * See
   * {@link PhpIndexingVisitor#encodeDocInfo(org.eclipse.dltk.ast.declarations.Declaration)}
   * for the encoding routine
   *
   * @param doc
   *            String representation of encoded PHPDoc info
   * @return map of encoded information, or <code>null</code> in case PHPDoc
   *         info is <code>null</code>
   */
  protected static Map<String, String> decodeDocInfo(String doc) {
    if (doc == null) {
      return null;
    }
    Map<String, String> info = new HashMap<String, String>();
    StringTokenizer tok = new StringTokenizer(doc, ";"); //$NON-NLS-1$
    while (tok.hasMoreTokens()) {
      String key = tok.nextToken();
      String value = null;
      int i = key.indexOf(':');
      if (i != -1) {
        value = key.substring(i + 1);
        key = key.substring(0, i);
      }
      info.put(key, value);
    }
    return info;
  }

  /**
   * Deprecated, use modifiers instead
   *
   * @param doc
   * @return
   */
  @Deprecated
  protected static boolean isDeprecated(String doc) {
    Map<String, String> info = decodeDocInfo(doc);
    return (info != null && info.containsKey("d")); //$NON-NLS-1$
  }

  private static class IndexField extends SourceField implements
      IPHPDocAwareElement {

    private int flags;
    private ISourceRange sourceRange;
    private ISourceRange nameRange;
    private String doc;

    public IndexField(ModelElement parent, String name, int flags,
        int offset, int length, int nameOffset, int nameLength,
        String doc) {
      super(parent, name);
      this.flags = flags;
      this.sourceRange = new SourceRange(offset, length);
      this.nameRange = new SourceRange(nameOffset, nameLength);
      this.doc = doc;
    }

    public int getFlags() throws ModelException {
      return flags;
    }

    public ISourceRange getNameRange() throws ModelException {
      return nameRange;
    }

    public ISourceRange getSourceRange() throws ModelException {
      return sourceRange;
    }

    public boolean isDeprecated() {
      return PHPFlags.isDeprecated(flags);
    }

    public String[] getReturnTypes() {
      return null;
    }
  }

  private static class IndexMethod extends SourceMethod implements
      IPHPDocAwareElement {

    private final static Pattern ARRAY_TYPE_PATTERN = Pattern
        .compile("array\\[.*\\]"); //$NON-NLS-1$
    private int flags;
    private ISourceRange sourceRange;
    private ISourceRange nameRange;
    private IParameter[] parameters;
    private String doc;

    public IndexMethod(ModelElement parent, String name, int flags,
        int offset, int length, int nameOffset, int nameLength,
        String[] parameterNames, String doc) {

      super(parent, name);
      this.flags = flags;
      this.sourceRange = new SourceRange(offset, length);
      this.nameRange = new SourceRange(nameOffset, nameLength);
      // MethodParameterInfo
      this.parameters = new IParameter[0];
      if (parameterNames != null) {
        this.parameters = new IParameter[parameterNames.length];
        for (int i = 0; i < parameterNames.length; i++) {
          String[] values = parameterNames[i].split("\\" //$NON-NLS-1$
              + PhpIndexingVisitor.PARAMETER_SEPERATOR);
          if (values.length == 1) {
            this.parameters[i] = new MethodParameterInfo(values[0]);
          } else {
            String type = values[0];
            if (PhpIndexingVisitor.NULL_VALUE.equals(type)) {
              type = null;
            }
            if (type != null) {
              type = type.replace(Constants.DOT,
                  Constants.TYPE_SEPERATOR_CHAR);
            }
            String param = values[1];

            String defaultValue = values[2];
            if (PhpIndexingVisitor.NULL_VALUE.equals(defaultValue)) {
              defaultValue = null;
            }
            this.parameters[i] = new MethodParameterInfo(param,
                type, defaultValue);
          }
        }
      }
      this.doc = doc;
    }

    public int getFlags() throws ModelException {
      return flags;
    }

    public ISourceRange getNameRange() throws ModelException {
      return super.getNameRange();
    }

    public ISourceRange getSourceRange() throws ModelException {
      return sourceRange;
    }

    public IParameter[] getParameters() throws ModelException {
      return parameters;
    }

    @Override
    public String[] getParameterNames() throws ModelException {
      return SourceMethodUtils.getParameterNames(parameters);
    }

    public boolean isConstructor() throws ModelException {
      return (flags & IPHPModifiers.Constructor) != 0;
    }

    public boolean isDeprecated() {
      return PHPFlags.isDeprecated(flags);
    }

    public String[] getReturnTypes() {
      Map<String, String> info = decodeDocInfo(doc);
      if (info != null) {
        String types = info.get("r"); //$NON-NLS-1$
        if (types != null) {
          String[] returnTypes = types.split(","); //$NON-NLS-1$
          for (int i = 0; i < returnTypes.length; i++) {
            returnTypes[i] = returnTypes[i].replaceAll("~", ","); //$NON-NLS-1$ //$NON-NLS-2$
          }
          return returnTypes;
        }
      }
      return null;
    }
  }

  private static class IndexType extends SourceType implements
      IPHPDocAwareElement {

    private int flags;
    private ISourceRange sourceRange;
    private ISourceRange nameRange;
    private String[] superClassNames;
    private String doc;

    public IndexType(ModelElement parent, String name, int flags,
        int offset, int length, int nameOffset, int nameLength,
        String[] superClassNames, String doc) {
      super(parent, name);
      this.flags = flags;
      this.sourceRange = new SourceRange(offset, length);
      this.nameRange = new SourceRange(nameOffset, nameLength);
      this.superClassNames = superClassNames;
      this.doc = doc;
    }

    public int getFlags() throws ModelException {
      return flags;
    }

    public ISourceRange getNameRange() throws ModelException {
      return super.getNameRange();
    }

    public ISourceRange getSourceRange() throws ModelException {
      return sourceRange;
    }

    public String[] getSuperClasses() throws ModelException {
      return superClassNames;
    }

    public boolean isDeprecated() {
      return PHPFlags.isDeprecated(flags);
    }

    public String[] getReturnTypes() {
      return null;
    }
  }
}
TOP

Related Classes of org.eclipse.php.internal.core.index.PhpElementResolver$IndexMethod

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.