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
/******************************************************************************* * 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 (tagName.equals(TagElement.TAG_EXCEPTION)) { 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; } }