/******************************************************************************* * 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 org2.eclipse.php.internal.core.compiler.ast.nodes; import java.util.LinkedList; import java.util.List; import com.aptana.editor.php.epl.PHPEplPlugin; import org2.eclipse.dltk.ast.references.SimpleReference; import org2.eclipse.dltk.ast.references.TypeReference; import org2.eclipse.dltk.ast.references.VariableReference; import org2.eclipse.php.internal.core.ast.nodes.AST; import org2.eclipse.php.internal.core.ast.nodes.Comment; import org2.eclipse.php.internal.core.documentModel.phpElementData.IPHPDocTag; public class PHPDocTag extends Comment implements IPHPDocTag { private static final long serialVersionUID = 7543654184965368295L; 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$ private static final SimpleReference[] EMPTY = {}; private final int tagKind; private String value; private SimpleReference[] references; public PHPDocTag(int start, int end, AST ast, int tagKind, String value) { super(start, end, ast, PHPDocTag.TYPE_PHPDOC); this.tagKind = tagKind; this.value = PHPEplPlugin.getDefault().sharedString(value); updateReferences(start, end); } 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 == PHPDocTagKinds.RETURN || tagKind == PHPDocTagKinds.VAR || tagKind == PHPDocTagKinds.THROWS) { 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()]); } } } else if (tagKind == PHPDocTagKinds.PARAM) { 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); } 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); } } } } if (references == null) { references = EMPTY; } } public int getTagKind() { return this.tagKind; } public String getValue() { return value; } public SimpleReference[] getReferences() { return references; } // public void adjustStart(int start) { // setStart(sourceStart() + start); // setEnd(sourceEnd() + start); // } public static String getTagKind(int kind) { switch (kind) { case PHPDocTagKinds.ABSTRACT: return ABSTRACT_NAME; case PHPDocTagKinds.AUTHOR: return AUTHOR_NAME; case PHPDocTagKinds.DEPRECATED: return DEPRECATED_NAME; case PHPDocTagKinds.FINAL: return FINAL_NAME; case PHPDocTagKinds.GLOBAL: return GLOBAL_NAME; case PHPDocTagKinds.NAME: return NAME_NAME; case PHPDocTagKinds.RETURN: return RETURN_NAME; case PHPDocTagKinds.PARAM: return PARAM_NAME; case PHPDocTagKinds.SEE: return SEE_NAME; case PHPDocTagKinds.STATIC: return STATIC_NAME; case PHPDocTagKinds.STATICVAR: return STATICVAR_NAME; case PHPDocTagKinds.TODO: return TODO_NAME; case PHPDocTagKinds.VAR: return VAR_NAME; case PHPDocTagKinds.PACKAGE: return PACKAGE_NAME; case PHPDocTagKinds.ACCESS: return ACCESS_NAME; case PHPDocTagKinds.CATEGORY: return CATEGORY_NAME; case PHPDocTagKinds.COPYRIGHT: return COPYRIGHT_NAME; case PHPDocTagKinds.DESC: return DESC_NAME; case PHPDocTagKinds.EXAMPLE: return EXAMPLE_NAME; case PHPDocTagKinds.FILESOURCE: return FILESOURCE_NAME; case PHPDocTagKinds.IGNORE: return IGNORE_NAME; case PHPDocTagKinds.INTERNAL: return INTERNAL_NAME; case PHPDocTagKinds.LICENSE: return LICENSE_NAME; case PHPDocTagKinds.LINK: return LINK_NAME; case PHPDocTagKinds.SINCE: return SINCE_NAME; case PHPDocTagKinds.SUBPACKAGE: return SUBPACKAGE_NAME; case PHPDocTagKinds.TUTORIAL: return TUTORIAL_NAME; case PHPDocTagKinds.USES: return USES_NAME; case PHPDocTagKinds.VERSION: return VERSION_NAME; case PHPDocTagKinds.THROWS: return THROWS_NAME; case PHPDocTagKinds.PROPERTY: return PROPERTY_NAME; case PHPDocTagKinds.PROPERTY_READ: return PROPERTY_READ_NAME; case PHPDocTagKinds.PROPERTY_WRITE: return PROPERTY_WRITE_NAME; case PHPDocTagKinds.METHOD: return METHOD_NAME; } return ERROR; } /** * Returns {@link #getTagKind()} for this doc tag type. */ public int getID() { return getTagKind(); } }