| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.php.editor.parser; |
| |
| import java.util.ArrayList; |
| import org.netbeans.modules.php.editor.parser.astnodes.PHPDocNode; |
| import org.netbeans.modules.php.editor.parser.astnodes.PHPDocStaticAccessType; |
| import org.netbeans.modules.php.editor.parser.astnodes.PHPDocTag; |
| import org.netbeans.modules.php.editor.parser.astnodes.PHPDocTypeNode; |
| import org.netbeans.modules.php.editor.parser.astnodes.PHPDocVarTypeTag; |
| import org.netbeans.modules.php.editor.parser.astnodes.PHPVarComment; |
| |
| /** |
| * PHPVarComment pattern: The first one is the IDE's own pattern. See |
| * {@link https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md} |
| * about the second one. |
| * <pre> |
| * /* @var $variableName TypeName */ |
| * /** @var TypeName $variableName Description */ |
| * </pre> |
| * |
| * @author Petr Pisl |
| */ |
| public class PHPVarCommentParser { |
| |
| private static final String PHPDOCTAG = "@" + PHPDocTag.Type.VAR.name().toLowerCase(); //NOI18N |
| |
| PHPVarComment parse(final int startOffset, final int endOffset, final String comment) { |
| boolean isPHPDoc = comment.startsWith("/**"); // NOI18N |
| int variableIndex = isPHPDoc ? 2 : 1; |
| int typeIndex = isPHPDoc ? 1 : 2; |
| |
| int index = comment.indexOf(PHPDOCTAG); |
| if (index > -1) { |
| String definition = comment.substring(index); |
| index = definition.indexOf("*/"); //NOI18N |
| if (index > -1) { |
| definition = definition.substring(0, index); |
| } |
| int startDocNode; |
| int endPosition = 0; |
| String[] parts = definition.split("[ \t]+"); //NOI18N |
| if (isExpectedPartsLength(isPHPDoc, parts) |
| && parts[variableIndex].charAt(0) == '$') { //NOI18N |
| //counting types |
| String[] types = parts[typeIndex].split("[|]"); //NOI18N |
| int typePosition = startOffset + comment.indexOf(parts[typeIndex]); |
| ArrayList<PHPDocTypeNode> typeNodes = new ArrayList<>(); |
| for (String type: types) { |
| startDocNode = typePosition + parts[typeIndex].indexOf(type); |
| index = type.indexOf("::"); //NOI18N |
| boolean isArray = (type.indexOf('[') > 0 && type.indexOf(']') > 0); |
| if (isArray) { |
| type = type.substring(0, type.indexOf('[')).trim(); |
| } |
| PHPDocTypeNode docType; |
| endPosition = startDocNode + type.length(); |
| if (index == -1) { |
| docType = new PHPDocTypeNode(startDocNode, endPosition, type, isArray); |
| } else { |
| String className = type.substring(0, index); |
| String constantName = type.substring(index + 2, type.length()); |
| PHPDocNode classNameNode = new PHPDocNode(startDocNode, startDocNode + className.length(), className); |
| PHPDocNode constantNode = new PHPDocNode(startDocNode + className.length() + 2, startDocNode + type.length(), constantName); |
| docType = new PHPDocStaticAccessType(startDocNode, startDocNode + type.length(), type, classNameNode, constantNode); |
| } |
| typeNodes.add(docType); |
| } |
| // counting variable |
| String variableName = parts[variableIndex]; |
| int indexOfArrayDimension = parts[variableIndex].indexOf("["); //NOI18N |
| if (indexOfArrayDimension != -1) { |
| variableName = parts[variableIndex].substring(0, indexOfArrayDimension); |
| } |
| startDocNode = startOffset + comment.indexOf(variableName); |
| PHPDocNode variableNode = new PHPDocNode(startDocNode, startDocNode + variableName.length(), variableName); |
| startDocNode = startOffset + comment.indexOf(PHPDOCTAG); |
| PHPDocVarTypeTag variableType = new PHPDocVarTypeTag(startDocNode, endPosition, PHPDocTag.Type.VAR, definition, typeNodes, variableNode); |
| return new PHPVarComment(startOffset, endOffset, variableType); |
| } |
| } |
| return null; |
| } |
| |
| private boolean isExpectedPartsLength(boolean isPHPDoc, String[] parts) { |
| if (isPHPDoc) { |
| return parts.length >= 3; |
| } |
| return parts.length == 3; |
| } |
| } |