blob: 6b8e2c66819d60e896a793570d66b610d0aa7649 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Red Hat Inc. - subset of JavadocTagsSubProcessor moved to jdt.core.manipulation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.text.correction;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TextElement;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
/**
*
*/
public class JavadocTagsSubProcessorCore {
public static Set<String> getPreviousTypeParamNames(List<TypeParameter> typeParams, ASTNode missingNode) {
Set<String> previousNames= new HashSet<>();
for (TypeParameter curr : typeParams) {
if (curr == missingNode) {
return previousNames;
}
previousNames.add('<' + curr.getName().getIdentifier() + '>');
}
return previousNames;
}
public static TagElement findTag(Javadoc javadoc, String name, String arg) {
List<TagElement> tags= javadoc.tags();
for (TagElement curr : tags) {
if (name.equals(curr.getTagName())) {
if (arg != null) {
String argument= getArgument(curr);
if (arg.equals(argument)) {
return curr;
}
} else {
return curr;
}
}
}
return null;
}
public static TagElement findParamTag(Javadoc javadoc, String arg) {
List<TagElement> tags= javadoc.tags();
for (TagElement curr : tags) {
String currName= curr.getTagName();
if (TagElement.TAG_PARAM.equals(currName)) {
String argument= getArgument(curr);
if (arg.equals(argument)) {
return curr;
}
}
}
return null;
}
public static TagElement findThrowsTag(Javadoc javadoc, String arg) {
List<TagElement> tags= javadoc.tags();
for (TagElement curr : tags) {
String currName= curr.getTagName();
if (TagElement.TAG_THROWS.equals(currName) || TagElement.TAG_EXCEPTION.equals(currName)) {
String argument= getArgument(curr);
if (arg.equals(argument)) {
return curr;
}
}
}
return null;
}
public static void insertTag(ListRewrite rewriter, TagElement newElement, Set<String> sameKindLeadingNames) {
insertTag(rewriter, newElement, sameKindLeadingNames, null);
}
public static void insertTag(ListRewrite rewriter, TagElement newElement, Set<String> sameKindLeadingNames, TextEditGroup groupDescription) {
List<? extends ASTNode> tags= rewriter.getRewrittenList();
String insertedTagName= newElement.getTagName();
ASTNode after= null;
int tagRanking= getTagRanking(insertedTagName);
for (int i= tags.size() - 1; i >= 0; i--) {
TagElement curr= (TagElement) tags.get(i);
String tagName= curr.getTagName();
if (tagName == null || tagRanking > getTagRanking(tagName)) {
after= curr;
break;
}
if (sameKindLeadingNames != null && isSameTag(insertedTagName, tagName)) {
String arg= getArgument(curr);
if (arg != null && sameKindLeadingNames.contains(arg)) {
after= curr;
break;
}
}
}
if (after != null) {
rewriter.insertAfter(newElement, after, groupDescription);
} else {
rewriter.insertFirst(newElement, groupDescription);
}
}
private static boolean isSameTag(String insertedTagName, String tagName) {
if (insertedTagName.equals(tagName)) {
return true;
}
if (TagElement.TAG_EXCEPTION.equals(tagName)) {
return TagElement.TAG_THROWS.equals(insertedTagName);
}
return false;
}
private static String[] TAG_ORDER= { // see http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html#orderoftags
TagElement.TAG_AUTHOR,
TagElement.TAG_VERSION,
TagElement.TAG_PARAM,
TagElement.TAG_RETURN,
TagElement.TAG_THROWS, // synonym to TAG_EXCEPTION
TagElement.TAG_SEE,
TagElement.TAG_SINCE,
TagElement.TAG_SERIAL,
TagElement.TAG_DEPRECATED
};
private static int getTagRanking(String tagName) {
if (TagElement.TAG_EXCEPTION.equals(tagName)) {
tagName= TagElement.TAG_THROWS;
}
for (int i= 0; i < TAG_ORDER.length; i++) {
if (tagName.equals(TAG_ORDER[i])) {
return i;
}
}
return TAG_ORDER.length;
}
private static String getArgument(TagElement curr) {
List<? extends ASTNode> fragments= curr.fragments();
if (!fragments.isEmpty()) {
Object first= fragments.get(0);
if (first instanceof Name) {
return ASTNodes.getSimpleNameIdentifier((Name) first);
} else if (first instanceof TextElement && TagElement.TAG_PARAM.equals(curr.getTagName())) {
String text= ((TextElement) first).getText();
if ("<".equals(text) && fragments.size() >= 3) { //$NON-NLS-1$
Object second= fragments.get(1);
Object third= fragments.get(2);
if (second instanceof Name && third instanceof TextElement && ">".equals(((TextElement) third).getText())) { //$NON-NLS-1$
return '<' + ASTNodes.getSimpleNameIdentifier((Name) second) + '>';
}
} else if (text.startsWith(String.valueOf('<')) && text.endsWith(String.valueOf('>')) && text.length() > 2) {
return text.substring(1, text.length() - 1);
}
}
}
return null;
}
private JavadocTagsSubProcessorCore() {
}
}