Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladislav.Soroka
2017-05-25 12:28:39 +03:00
11 changed files with 176 additions and 115 deletions
@@ -99,6 +99,8 @@ public class JavaDocFormattingPanel extends OptionTreeWithPreviewPanel {
initBooleanField("JD_DO_NOT_WRAP_ONE_LINE_COMMENTS", ApplicationBundle.message("checkbox.do.not.wrap.one.line.comments"), OTHER_GROUP);
initBooleanField("JD_PRESERVE_LINE_FEEDS", ApplicationBundle.message("checkbox.preserve.line.feeds"), OTHER_GROUP);
initBooleanField("JD_PARAM_DESCRIPTION_ON_NEW_LINE", ApplicationBundle.message("checkbox.param.description.on.new.line"), OTHER_GROUP);
initBooleanField("JD_INDENT_ON_CONTINUATION", ApplicationBundle.message("checkbox.param.indent.on.continuation"), OTHER_GROUP);
}
protected int getRightMargin() {
@@ -37,19 +37,20 @@ public class JDClassComment extends JDParamListOwnerComment {
@Override
protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) {
super.generateSpecial(prefix, sb);
String continuationPrefix = prefix + javadocContinuationIndent();
if (!isNull(myAuthorsList)) {
JDTag tag = JDTag.AUTHOR;
for (String author : myAuthorsList) {
sb.append(prefix);
sb.append(tag.getWithEndWhitespace());
sb.append(myFormatter.getParser().formatJDTagDescription(author, tag.getDescriptionPrefix(prefix)));
sb.append(myFormatter.getParser().formatJDTagDescription(author,
prefix + tag.getWithEndWhitespace(),
continuationPrefix));
}
}
if (!isNull(myVersion)) {
sb.append(prefix);
JDTag tag = JDTag.VERSION;
sb.append(tag.getWithEndWhitespace());
sb.append(myFormatter.getParser().formatJDTagDescription(myVersion, tag.getDescriptionPrefix(prefix)));
sb.append(myFormatter.getParser().formatJDTagDescription(myVersion,
prefix + tag.getWithEndWhitespace(),
continuationPrefix));
}
}
@@ -68,4 +69,4 @@ public class JDClassComment extends JDParamListOwnerComment {
public void setVersion(@NotNull String version) {
this.myVersion = version;
}
}
}
@@ -15,6 +15,10 @@
*/
package com.intellij.psi.impl.source.codeStyle.javadoc;
import com.intellij.formatting.IndentInfo;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,6 +56,19 @@ public class JDComment {
myMultiLineComment = value;
}
@NotNull
protected String javadocContinuationIndent() {
if (!myFormatter.getSettings().JD_INDENT_ON_CONTINUATION) return "";
return continuationIndent();
}
@NotNull
protected String continuationIndent() {
CodeStyleSettings settings = myFormatter.getSettings();
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(JavaFileType.INSTANCE);
return new IndentInfo(0, indentOptions.CONTINUATION_INDENT_SIZE, 0).generateNewWhiteSpace(indentOptions);
}
@Nullable
public String generate(@NotNull String indent) {
final String prefix;
@@ -66,8 +83,7 @@ public class JDComment {
int start = sb.length();
if (!isNull(myDescription)) {
sb.append(prefix);
sb.append(myFormatter.getParser().formatJDTagDescription(myDescription, prefix, false));
sb.append(myFormatter.getParser().formatJDTagDescription(myDescription, prefix));
if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_DESCRIPTION) {
sb.append(prefix);
@@ -77,39 +93,34 @@ public class JDComment {
generateSpecial(prefix, sb);
final String continuationPrefix = prefix + javadocContinuationIndent();
if (!isNull(myUnknownList) && myFormatter.getSettings().JD_KEEP_INVALID_TAGS) {
for (String aUnknownList : myUnknownList) {
sb.append(prefix);
sb.append(myFormatter.getParser().formatJDTagDescription(aUnknownList, prefix));
sb.append(myFormatter.getParser().formatJDTagDescription(aUnknownList, prefix, continuationPrefix));
}
}
if (!isNull(mySeeAlsoList)) {
JDTag tag = JDTag.SEE;
for (String aSeeAlsoList : mySeeAlsoList) {
sb.append(prefix);
sb.append(tag.getWithEndWhitespace());
StringBuilder tagDescription = myFormatter.getParser()
.formatJDTagDescription(aSeeAlsoList, prefix, true, tag.getDescriptionPrefix(prefix).length());
.formatJDTagDescription(aSeeAlsoList, prefix + tag.getWithEndWhitespace(), continuationPrefix);
sb.append(tagDescription);
}
}
if (!isNull(mySince)) {
JDTag tag = JDTag.SINCE;
sb.append(prefix);
sb.append(tag.getWithEndWhitespace());
StringBuilder tagDescription = myFormatter.getParser()
.formatJDTagDescription(mySince, prefix, true, tag.getDescriptionPrefix(prefix).length());
.formatJDTagDescription(mySince, prefix + tag.getWithEndWhitespace(), continuationPrefix);
sb.append(tagDescription);
}
if (myDeprecated != null) {
JDTag tag = JDTag.DEPRECATED;
sb.append(prefix);
sb.append(tag.getWithEndWhitespace());
StringBuilder tagDescription = myFormatter.getParser()
.formatJDTagDescription(myDeprecated, prefix, true, tag.getDescriptionPrefix(prefix).length());
.formatJDTagDescription(myDeprecated, prefix + tag.getWithEndWhitespace(), continuationPrefix);
sb.append(tagDescription);
}
@@ -28,7 +28,7 @@ import java.util.List;
*/
public class JDMethodComment extends JDParamListOwnerComment {
private String myReturnTag;
private List<NameDesc> myThrowsList;
private List<TagDescription> myThrowsList;
public JDMethodComment(@NotNull CommentFormatter formatter) {
super(formatter);
@@ -41,9 +41,10 @@ public class JDMethodComment extends JDParamListOwnerComment {
if (myReturnTag != null) {
if (myFormatter.getSettings().JD_KEEP_EMPTY_RETURN || !myReturnTag.trim().isEmpty()) {
JDTag tag = JDTag.RETURN;
sb.append(prefix);
sb.append(tag.getWithEndWhitespace());
sb.append(myFormatter.getParser().formatJDTagDescription(myReturnTag, prefix, true, tag.getDescriptionPrefix(prefix).length()));
sb.append(myFormatter.getParser().formatJDTagDescription(myReturnTag,
prefix + tag.getWithEndWhitespace(),
prefix + javadocContinuationIndent()));
if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_RETURN) {
sb.append(prefix);
sb.append('\n');
@@ -69,6 +70,6 @@ public class JDMethodComment extends JDParamListOwnerComment {
if (myThrowsList == null) {
myThrowsList = ContainerUtilRt.newArrayList();
}
myThrowsList.add(new NameDesc(className, description));
myThrowsList.add(new TagDescription(className, description));
}
}
@@ -16,11 +16,7 @@
package com.intellij.psi.impl.source.codeStyle.javadoc;
import com.intellij.formatting.IndentInfo;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,7 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class JDParamListOwnerComment extends JDComment {
protected List<NameDesc> myParamsList;
protected List<TagDescription> myParamsList;
public JDParamListOwnerComment(@NotNull CommentFormatter formatter) {
super(formatter);
@@ -53,7 +49,7 @@ public class JDParamListOwnerComment extends JDComment {
}
@Nullable
public NameDesc getParameter(@Nullable String name) {
public TagDescription getParameter(@Nullable String name) {
return getNameDesc(name, myParamsList);
}
@@ -61,13 +57,13 @@ public class JDParamListOwnerComment extends JDComment {
if (myParamsList == null) {
myParamsList = ContainerUtilRt.newArrayList();
}
myParamsList.add(new NameDesc(name, description));
myParamsList.add(new TagDescription(name, description));
}
@Nullable
private static NameDesc getNameDesc(@Nullable String name, @Nullable List<NameDesc> list) {
private static TagDescription getNameDesc(@Nullable String name, @Nullable List<TagDescription> list) {
if (list == null) return null;
for (NameDesc aList : list) {
for (TagDescription aList : list) {
if (aList.name.equals(name)) {
return aList;
}
@@ -79,56 +75,69 @@ public class JDParamListOwnerComment extends JDComment {
* Generates parameters or exceptions
*
*/
protected void generateList(@NotNull String prefix,
protected void generateList(@NotNull final String prefix,
@NotNull StringBuilder sb,
@NotNull List<NameDesc> list,
@NotNull List<TagDescription> tagBlocks,
@NotNull String tag,
boolean align_comments,
boolean generate_empty_tags,
boolean wrapDescription)
boolean descriptionOnNewLine)
{
CodeStyleSettings settings = myFormatter.getSettings();
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(JavaFileType.INSTANCE);
String continuationIndent = new IndentInfo(0, indentOptions.CONTINUATION_INDENT_SIZE, 0).generateNewWhiteSpace(indentOptions);
int maxNameLength = maxTagDescriptionNameLength(tagBlocks, align_comments, generate_empty_tags, descriptionOnNewLine);
StringBuilder fill = new StringBuilder(prefix.length() + tag.length() + maxNameLength + 1);
fill.append(prefix);
StringUtil.repeatSymbol(fill, ' ', maxNameLength + 1 + tag.length());
for (TagDescription nd : tagBlocks) {
if (isNull(nd.desc) && !generate_empty_tags) continue;
if (descriptionOnNewLine && !isNull(nd.desc)) {
sb.append(prefix).append(tag).append(nd.name).append("\n");
sb.append(formatJDTagDescription(nd.desc, prefix + continuationIndent()));
}
else if (align_comments) {
int spacesNumber = maxNameLength + 1 - nd.name.length();
String spaces = StringUtil.repeatSymbol(' ', Math.max(0, spacesNumber));
String firstLinePrefix = prefix + tag + nd.name + spaces;
sb.append(formatJDTagDescription(nd.desc, firstLinePrefix, fill));
}
else {
String description = (nd.desc == null) ? "" : nd.desc;
StringBuilder tagDescription = formatJDTagDescription(tag + nd.name + " " + description, prefix, prefix + javadocContinuationIndent());
sb.append(tagDescription);
}
}
}
private static int maxTagDescriptionNameLength(@NotNull List<TagDescription> tagBlocks,
boolean align_comments,
boolean generate_empty_tags,
boolean descriptionOnNewLine)
{
int max = 0;
if (align_comments && !wrapDescription) {
for (NameDesc nd: list) {
int currentLength = nd.name.length();
if (isNull(nd.desc) && !generate_empty_tags) continue;
//finding longest parameter length
if (currentLength > max) {
max = currentLength;
if (align_comments && !descriptionOnNewLine) {
for (TagDescription tagDescription: tagBlocks) {
int current = tagDescription.name.length();
if (isNull(tagDescription.desc) && !generate_empty_tags) continue;
if (current > max) {
max = current;
}
}
}
StringBuilder fill = new StringBuilder(prefix.length() + tag.length() + max + 1);
fill.append(prefix);
StringUtil.repeatSymbol(fill, ' ', max + 1 + tag.length());
String wrapParametersPrefix = prefix + continuationIndent;
for (NameDesc nd : list) {
if (isNull(nd.desc) && !generate_empty_tags) continue;
if (wrapDescription && !isNull(nd.desc)) {
sb.append(prefix).append(tag).append(nd.name).append("\n");
sb.append(wrapParametersPrefix);
sb.append(myFormatter.getParser().formatJDTagDescription(nd.desc, wrapParametersPrefix));
}
else if (align_comments) {
sb.append(prefix);
sb.append(tag);
sb.append(nd.name);
int spacesNumber = max + 1 - nd.name.length();
StringUtil.repeatSymbol(sb, ' ', Math.max(0, spacesNumber));
sb.append(myFormatter.getParser().formatJDTagDescription(nd.desc, fill));
}
else {
sb.append(prefix);
String description = (nd.desc == null) ? "" : nd.desc;
sb.append(myFormatter.getParser().formatJDTagDescription(tag + nd.name + " " + description, prefix));
}
}
return max;
}
private StringBuilder formatJDTagDescription(@Nullable String description,
@NotNull CharSequence firstLinePrefix,
@NotNull CharSequence continuationPrefix) {
return myFormatter.getParser().formatJDTagDescription(description, firstLinePrefix, continuationPrefix);
}
private StringBuilder formatJDTagDescription(@Nullable String description, @NotNull CharSequence prefix) {
return formatJDTagDescription(description, prefix, prefix);
}
}
@@ -536,16 +536,6 @@ public class JDParser {
},
};
@NotNull
protected StringBuilder formatJDTagDescription(@Nullable String s, @NotNull CharSequence prefix) {
return formatJDTagDescription(s, prefix, false, 0);
}
@NotNull
protected StringBuilder formatJDTagDescription(@Nullable String s, @NotNull CharSequence prefix, boolean wrapLinesShorterRightMargin) {
return formatJDTagDescription(s, prefix, false, 0, wrapLinesShorterRightMargin);
}
private static boolean lineHasUnclosedPreTag(@NotNull String line) {
return StringUtil.getOccurrenceCount(line, PRE_TAG_START) > StringUtil.getOccurrenceCount(line, PRE_TAG_END);
}
@@ -555,36 +545,36 @@ public class JDParser {
}
@NotNull
protected StringBuilder formatJDTagDescription(@Nullable String str,
@NotNull CharSequence prefix,
boolean firstLineShorter,
int firstLinePrefixLength) {
return formatJDTagDescription(str, prefix, firstLineShorter, firstLinePrefixLength, true);
protected StringBuilder formatJDTagDescription(@Nullable String str, @NotNull CharSequence prefix) {
return formatJDTagDescription(str, prefix, prefix);
}
/**
* Returns formatted JavaDoc tag description, according to selected configuration
* @param str JavaDoc tag description
* @param prefix JavaDoc prefix(like " * ") which will be appended to every new line
* @param firstLineShorter flag if first line should be shorter (has another prefix length than other lines)
* @param firstLinePrefixLength first line prefix length
* Returns formatted JavaDoc tag description, according to selected configuration. Prefixs
* may be specified for the first lines and all subsequent lines. This distinction allows
* partially manual formatting of the first line (by moving content from the description
* to the first line prefix) and allow continuation lines to use different indentation.
*
* @param str JavaDoc tag description
* @param firstLinePrefix prefix to be added to the first line
* @param continuationPrefix prefix to be added to lines after the first
* @return formatted JavaDoc tag description
*/
@NotNull
protected StringBuilder formatJDTagDescription(@Nullable String str,
@NotNull CharSequence prefix,
boolean firstLineShorter,
int firstLinePrefixLength,
boolean isWrapLinesShorterRightMargin)
@NotNull CharSequence firstLinePrefix,
@NotNull CharSequence continuationPrefix)
{
final int rightMargin = mySettings.getRightMargin(JavaLanguage.INSTANCE);
final int maxCommentLength = rightMargin - prefix.length();
StringBuilder sb = new StringBuilder();
final int maxCommentLength = rightMargin - continuationPrefix.length();
final int firstLinePrefixLength = firstLinePrefix.length();
final boolean firstLineShorter = firstLinePrefixLength > continuationPrefix.length();
StringBuilder sb = new StringBuilder(firstLinePrefix);
List<String> list;
boolean canWrap = isWrapLinesShorterRightMargin || hasLineLongerThan(str, maxCommentLength);
boolean canWrap = !mySettings.JD_PRESERVE_LINE_FEEDS || hasLineLongerThan(str, maxCommentLength);
//If wrap comments selected, comments should be wrapped by the right margin
if (mySettings.WRAP_COMMENTS && canWrap) {
list = toArrayWrapping(str, maxCommentLength);
@@ -628,7 +618,7 @@ public class JDParser {
for (int i = 0; i < list.size(); i++) {
String line = list.get(i);
if (line.isEmpty() && !mySettings.JD_KEEP_EMPTY_LINES) continue;
if (i != 0) sb.append(prefix);
if (i != 0) sb.append(continuationPrefix);
if (line.isEmpty() && mySettings.JD_P_AT_EMPTY_LINES && !insidePreTag) {
sb.append(P_START_TAG);
}
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.impl.source.codeStyle.javadoc;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,11 +36,6 @@ public enum JDTag {
this.myTag = tag;
}
@NotNull
public String getDescriptionPrefix(@NotNull String prefix) {
return prefix + StringUtil.repeatSymbol(' ', getWithEndWhitespace().length());
}
@NotNull
public String getWithEndWhitespace() {
return "@" + myTag + " ";
@@ -22,11 +22,11 @@ import org.jetbrains.annotations.Nullable;
*
* @author Dmitry Skavish
*/
public class NameDesc {
public class TagDescription {
@NotNull public final String name;
@Nullable public final String desc;
public NameDesc(@NotNull String name, @Nullable String desc) {
public TagDescription(@NotNull String name, @Nullable String desc) {
this.name = name;
this.desc = desc;
}
@@ -16,6 +16,7 @@
package com.intellij.java.psi.formatter.java;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
@@ -550,6 +551,7 @@ public class JavadocFormatterTest extends AbstractJavaFormatterTest {
public void testDoNotMergeCommentLines() {
getSettings().getRootSettings().ENABLE_JAVADOC_FORMATTING = true;
getSettings().getRootSettings().JD_PRESERVE_LINE_FEEDS = true;
getSettings().getRootSettings().WRAP_COMMENTS = true;
doClassTest(
@@ -937,4 +939,53 @@ public class JavadocFormatterTest extends AbstractJavaFormatterTest {
"}"
);
}
public void test_ContinuationDescriptionFormatting() {
getCurrentCodeStyleSettings().setRightMargin(JavaLanguage.INSTANCE, 40);
getCurrentCodeStyleSettings().getIndentOptions(JavaFileType.INSTANCE).CONTINUATION_INDENT_SIZE = 2;
getCurrentCodeStyleSettings().JD_INDENT_ON_CONTINUATION = true;
getCurrentCodeStyleSettings().JD_ALIGN_PARAM_COMMENTS = false;
getCurrentCodeStyleSettings().JD_ALIGN_EXCEPTION_COMMENTS = false;
getCurrentCodeStyleSettings().WRAP_COMMENTS = true;
doClassTest(
"/**\n" +
" * Just some random text\n" +
" * @param aParameter randomness in life does not mean it's easy to generate random text\n" +
" * @param bParameter another random parameter with qualified epoch\n" +
" * @author rumor oculus rivierra underground sound\n" +
" * @myrandomtag just write what you want and cranberries with bicycle\n" +
" * @return super string with everything involved, be aware\n" +
" */\n" +
"String test(int aParameter, int bParameter) {\n" +
" return \"\";\n" +
"} \n",
"/**\n" +
" * Just some random text\n" +
" *\n" +
" * @param aParameter randomness in\n" +
" * life does not mean it's easy to\n" +
" * generate random text\n" +
" * @param bParameter another\n" +
" * random parameter with qualified\n" +
" * epoch\n" +
" * @return super string with\n" +
" * everything involved, be aware\n" +
" * @author rumor oculus rivierra\n" +
" * underground sound\n" +
" * @myrandomtag just write what\n" +
" * you want and cranberries with\n" +
" * bicycle\n" +
" */\n" +
"String test(int aParameter, int bParameter) {\n" +
" return \"\";\n" +
"}\n"
);
}
}
@@ -410,10 +410,11 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
public boolean JD_LEADING_ASTERISKS_ARE_ENABLED = true;
public boolean JD_PRESERVE_LINE_FEEDS;
public boolean JD_PARAM_DESCRIPTION_ON_NEW_LINE;
public boolean JD_INDENT_ON_CONTINUATION = false;
// endregion
// region Legacy(!) XML formatting options
@@ -509,6 +509,7 @@ checkbox.keep.empty.lines=Keep empty lines
checkbox.do.not.wrap.one.line.comments=Do not wrap one line comments
checkbox.preserve.line.feeds=Preserve line feeds
checkbox.param.description.on.new.line=Parameter descriptions on new line
checkbox.param.indent.on.continuation=Indent continuation lines
title.javadoc=JavaDoc
option.table.sizing.text=Chop down if long.
title.choose.code.style.scheme=Choose Code Style Scheme
@@ -793,4 +794,4 @@ settings.editor.scheme.copy.to.project.message=Overwrite project settings with v
settings.editor.scheme.import.success={0} was imported to {1} scheme.
settings.editor.scheme.import.failure=Import failed: {0} is not a valid scheme.
title.save.code.style.scheme.as=Duplicate Code Style Scheme As
title.save.color.scheme.as=Duplicate Color Scheme As
title.save.color.scheme.as=Duplicate Color Scheme As