Package org.eclipse.php.internal.core.compiler.ast.nodes

Source Code of org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocTag

/*******************************************************************************
* 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.compiler.ast.nodes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.references.TypeReference;
import org.eclipse.dltk.ast.references.VariableReference;

public class PHPDocTag extends ASTNode implements PHPDocTagKinds {

  public static final String ERROR = "ERROR!!!"; //$NON-NLS-1$
  public static final String THROWS_NAME = "throws"; //$NON-NLS-1$
  public static final String VERSION_NAME = "version"; //$NON-NLS-1$
  public static final String USES_NAME = "uses"; //$NON-NLS-1$
  public static final String TUTORIAL_NAME = "tutorial"; //$NON-NLS-1$
  public static final String SUBPACKAGE_NAME = "subpackage"; //$NON-NLS-1$
  public static final String SINCE_NAME = "since"; //$NON-NLS-1$
  public static final String LINK_NAME = "link"; //$NON-NLS-1$
  public static final String LICENSE_NAME = "license"; //$NON-NLS-1$
  public static final String INTERNAL_NAME = "internal"; //$NON-NLS-1$
  public static final String IGNORE_NAME = "ignore"; //$NON-NLS-1$
  public static final String FILESOURCE_NAME = "filesource"; //$NON-NLS-1$
  public static final String EXAMPLE_NAME = "example"; //$NON-NLS-1$
  public static final String DESC_NAME = "desc"; //$NON-NLS-1$
  public static final String COPYRIGHT_NAME = "copyright"; //$NON-NLS-1$
  public static final String CATEGORY_NAME = "category"; //$NON-NLS-1$
  public static final String ACCESS_NAME = "access"; //$NON-NLS-1$
  public static final String PACKAGE_NAME = "package"; //$NON-NLS-1$
  public static final String VAR_NAME = "var"; //$NON-NLS-1$
  public static final String TODO_NAME = "todo"; //$NON-NLS-1$
  public static final String STATICVAR_NAME = "staticvar"; //$NON-NLS-1$
  public static final String STATIC_NAME = "static"; //$NON-NLS-1$
  public static final String SEE_NAME = "see"; //$NON-NLS-1$
  public static final String PARAM_NAME = "param"; //$NON-NLS-1$
  public static final String RETURN_NAME = "return"; //$NON-NLS-1$
  public static final String NAME_NAME = "name"; //$NON-NLS-1$
  public static final String GLOBAL_NAME = "global"; //$NON-NLS-1$
  public static final String FINAL_NAME = "final"; //$NON-NLS-1$
  public static final String DEPRECATED_NAME = "deprecated"; //$NON-NLS-1$
  public static final String AUTHOR_NAME = "author"; //$NON-NLS-1$
  public static final String ABSTRACT_NAME = "abstract"; //$NON-NLS-1$
  public static final String PROPERTY_NAME = "property"; //$NON-NLS-1$
  public static final String PROPERTY_READ_NAME = "property-read"; //$NON-NLS-1$
  public static final String PROPERTY_WRITE_NAME = "property-write"; //$NON-NLS-1$
  public static final String METHOD_NAME = "method"; //$NON-NLS-1$
  public static final String NAMESPACE_NAME = "namespace"; //$NON-NLS-1$

  private static final SimpleReference[] EMPTY = {};
  private final int tagKind;
  private String value;
  private SimpleReference[] references;
  private SimpleReference[] referencesWithOrigOrder;
  private List<Scalar> texts;

  public PHPDocTag(int start, int end, int tagKind, String value,
      List<Scalar> texts) {
    super(start, end);
    this.tagKind = tagKind;
    this.value = value;
    updateReferences(start, end);
    this.texts = texts;
  }

  public List<Scalar> getTexts() {
    return texts;
  }

  public String[] getDescTexts() {
    // For all unsupported tags
    int wordSize = 0;
    if (referencesWithOrigOrder.length == 0) {
      // No references were found
      wordSize = 0;
    } else if (tagKind == RETURN || tagKind == VAR || tagKind == THROWS
        || tagKind == SEE) {
      // The word following the tag name was splitted into several
      // references
      wordSize = 1;
    } else if (tagKind == PARAM || tagKind == PROPERTY
        || tagKind == PROPERTY_READ || tagKind == PROPERTY_WRITE) {
      // The two words following the tag name were splitted into two
      // references
      wordSize = 2;
    }
    List<String> result = new ArrayList<String>();
    for (int i = 0; i < texts.size(); i++) {
      String text = texts.get(i).getValue();
      if (wordSize <= 0) {
        result.add(text);
      } else {
        if (text.trim().length() == 0) {
          continue;
        }
        List<String> commentWords = Arrays.asList(text.trim().split(
            "[ \r\n]")); //$NON-NLS-1$
        commentWords = removeEmptyString(commentWords);
        if (commentWords.size() <= wordSize) {
          wordSize = wordSize - commentWords.size();
        } else {
          text = removeFirstWords(text, commentWords, wordSize);
          result.add(text);
          wordSize = 0;
        }
      }

    }
    String[] texts = new String[result.size()];
    result.toArray(texts);
    return texts;
  }

  public static List<String> removeEmptyString(List<String> commentWords) {
    List<String> result = new ArrayList<String>();
    for (int i = 0; i < commentWords.size(); i++) {
      String word = commentWords.get(i);
      if (word.trim().length() != 0) {
        result.add(word);
      }

    }
    return result;
  }

  private String removeFirstWords(String text, List<String> commentWords,
      int wordSize) {
    for (int i = 0; i < wordSize; i++) {
      int index = text.indexOf(commentWords.get(i));
      text = text.substring(commentWords.get(i).length() + index);
    }
    return text.trim();
  }

  private static int getNonWhitespaceIndex(String line, int startIndex) {
    int i = startIndex;
    for (; i < line.length(); ++i) {
      if (!Character.isWhitespace(line.charAt(i))) {
        return i;
      }
    }
    return i;
  }

  private static int getWhitespaceIndex(String line, int startIndex) {
    int i = startIndex;
    for (; i < line.length(); ++i) {
      if (Character.isWhitespace(line.charAt(i))) {
        return i;
      }
    }
    return i;
  }

  private static int getClassStartIndex(String line, int startIndex) {
    int i = startIndex;
    for (; i < line.length(); ++i) {
      if (line.charAt(i) != '|') {
        return i;
      }
    }
    return i;
  }

  private static int getClassEndIndex(String line, int startIndex) {
    int i = startIndex;
    for (; i < line.length(); ++i) {
      if (line.charAt(i) == '|') {
        return i;
      }
    }
    return i;
  }

  private void updateReferences(int start, int end) {

    int valueStart = start + getTagKind(tagKind).length() + 1;

    if (tagKind == RETURN || tagKind == VAR || tagKind == THROWS
        || tagKind == SEE) {

      int wordStart = getNonWhitespaceIndex(value, 0);
      int wordEnd = getWhitespaceIndex(value, wordStart);
      if (wordStart < wordEnd) {

        String word = value.substring(wordStart, wordEnd);

        int classStart = getClassStartIndex(word, 0);
        int classEnd = getClassEndIndex(word, classStart);
        List<TypeReference> types = new LinkedList<TypeReference>();

        while (classStart < classEnd) {
          String className = word.substring(classStart, classEnd);
          types.add(new TypeReference(valueStart + wordStart
              + classStart, valueStart + wordStart + classEnd,
              className));

          classStart = getClassStartIndex(word, classEnd);
          classEnd = getClassEndIndex(word, classStart);
        }
        if (types.size() > 0) {
          references = types.toArray(new TypeReference[types.size()]);
          referencesWithOrigOrder = references;
        }
      }
    } else if (tagKind == PARAM || tagKind == PROPERTY
        || tagKind == PROPERTY_READ || tagKind == PROPERTY_WRITE) {

      int firstWordStart = getNonWhitespaceIndex(value, 0);
      int firstWordEnd = getWhitespaceIndex(value, firstWordStart);
      if (firstWordStart < firstWordEnd) {

        int secondWordStart = getNonWhitespaceIndex(value, firstWordEnd);
        int secondWordEnd = getWhitespaceIndex(value, secondWordStart);
        if (secondWordStart < secondWordEnd) {

          String firstWord = value.substring(firstWordStart,
              firstWordEnd);
          String secondWord = value.substring(secondWordStart,
              secondWordEnd);
          if (firstWord.charAt(0) == '$') {
            references = new SimpleReference[2];
            references[0] = new VariableReference(valueStart
                + firstWordStart, valueStart + firstWordEnd,
                firstWord);
            references[1] = new TypeReference(valueStart
                + secondWordStart, valueStart + secondWordEnd,
                secondWord);
            referencesWithOrigOrder = references;
          } else if (secondWord.charAt(0) == '$') {
            references = new SimpleReference[2];
            references[0] = new VariableReference(valueStart
                + secondWordStart, valueStart + secondWordEnd,
                secondWord);
            references[1] = new TypeReference(valueStart
                + firstWordStart, valueStart + firstWordEnd,
                firstWord);
            referencesWithOrigOrder = new SimpleReference[2];
            referencesWithOrigOrder[0] = references[1];
            referencesWithOrigOrder[1] = references[0];
          }
        }
      }
    }
    if (references == null) {
      references = EMPTY;
    }
    if (referencesWithOrigOrder == null) {
      referencesWithOrigOrder = EMPTY;
    }
  }

  public void traverse(ASTVisitor visitor) throws Exception {
    boolean visit = visitor.visit(this);
    if (visit) {
      for (SimpleReference ref : references) {
        ref.traverse(visitor);
      }
    }
    visitor.endvisit(this);
  }

  public int getKind() {
    return ASTNodeKinds.PHP_DOC_TAG;
  }

  public int getTagKind() {
    return this.tagKind;
  }

  public String getValue() {
    return value;
  }

  public SimpleReference[] getReferences() {
    return references;
  }

  public SimpleReference[] getReferencesWithOrigOrder() {
    return referencesWithOrigOrder;
  }

  public void adjustStart(int start) {
    setStart(sourceStart() + start);
    setEnd(sourceEnd() + start);
  }

  public static String getTagKind(int kind) {
    switch (kind) {
    case ABSTRACT:
      return ABSTRACT_NAME;
    case AUTHOR:
      return AUTHOR_NAME;
    case DEPRECATED:
      return DEPRECATED_NAME;
    case FINAL:
      return FINAL_NAME;
    case GLOBAL:
      return GLOBAL_NAME;
    case NAME:
      return NAME_NAME;
    case RETURN:
      return RETURN_NAME;
    case PARAM:
      return PARAM_NAME;
    case SEE:
      return SEE_NAME;
    case STATIC:
      return STATIC_NAME;
    case STATICVAR:
      return STATICVAR_NAME;
    case TODO:
      return TODO_NAME;
    case VAR:
      return VAR_NAME;
    case PACKAGE:
      return PACKAGE_NAME;
    case ACCESS:
      return ACCESS_NAME;
    case CATEGORY:
      return CATEGORY_NAME;
    case COPYRIGHT:
      return COPYRIGHT_NAME;
    case DESC:
      return DESC_NAME;
    case EXAMPLE:
      return EXAMPLE_NAME;
    case FILESOURCE:
      return FILESOURCE_NAME;
    case IGNORE:
      return IGNORE_NAME;
    case INTERNAL:
      return INTERNAL_NAME;
    case LICENSE:
      return LICENSE_NAME;
    case LINK:
      return LINK_NAME;
    case SINCE:
      return SINCE_NAME;
    case SUBPACKAGE:
      return SUBPACKAGE_NAME;
    case TUTORIAL:
      return TUTORIAL_NAME;
    case USES:
      return USES_NAME;
    case VERSION:
      return VERSION_NAME;
    case THROWS:
      return THROWS_NAME;
    case PROPERTY:
      return PROPERTY_NAME;
    case PROPERTY_READ:
      return PROPERTY_READ_NAME;
    case PROPERTY_WRITE:
      return PROPERTY_WRITE_NAME;
    case METHOD:
      return METHOD_NAME;
    case NAMESPACE:
      return NAMESPACE_NAME;
    }
    return ERROR;
  }

}
TOP

Related Classes of org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocTag

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.