fix(JavaDoc): Refactoring misplaced tags

GitOrigin-RevId: 313091e94f8b65d379615f91dca7b975428aeeba
This commit is contained in:
Mathias Boulay
2024-09-02 11:23:40 +02:00
committed by intellij-monorepo-bot
parent feb3dd7614
commit 19b9a28603
61 changed files with 1266 additions and 18 deletions

View File

@@ -181,9 +181,16 @@ public class JDParser {
}
}
} else {
String newLine = StringUtil.trimStart(line, "/// ");
if (Strings.areSameInstance(newLine, line)) {
newLine = StringUtil.trimStart(line, "///");
// Note: Markdown comments are not trimmed like html ones, except for javadoc tags
String newLine;
int tagStart = CharArrayUtil.shiftForward(line, 3, " \t");
if (tagStart != line.length()) {
newLine = line.substring(tagStart);
} else {
newLine = StringUtil.trimStart(line, "/// ");
if (Strings.areSameInstance(newLine, line)) {
newLine = StringUtil.trimStart(line, "///");
}
}
line = newLine;
}

View File

@@ -133,12 +133,12 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
CharTable charTable = SharedImplUtil.findCharTableByTree(tag);
if (JavaFileCodeStyleFacade.forContext(psiFile).isJavaDocLeadingAsterisksEnabled() || isMarkdownComment()) {
tag.addChild(Factory.createSingleLeafElement(TokenType.WHITE_SPACE, "\n ", charTable, manager));
tag.addChild(Factory.createSingleLeafElement(TokenType.WHITE_SPACE, getNewLikeBuffer(), charTable, manager));
tag.addChild(Factory.createSingleLeafElement(DOC_COMMENT_LEADING_ASTERISKS, getLeadingToken(), charTable, manager));
tag.addChild(Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", charTable, manager));
}
else {
tag.addChild(Factory.createSingleLeafElement(TokenType.WHITE_SPACE, "\n ", charTable, manager));
tag.addChild(Factory.createSingleLeafElement(TokenType.WHITE_SPACE, getNewLikeBuffer(), charTable, manager));
}
}
@@ -147,16 +147,20 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
boolean needToAddNewline = false;
if (last.getElementType() == DOC_TAG && first.getElementType() == DOC_TAG) {
if (anchor == null) {
anchor = getLastChildNode(); // this is a '*/'
ASTNode prevBeforeWS = TreeUtil.skipElementsBack(anchor.getTreePrev(), TokenSet.WHITE_SPACE);
if (prevBeforeWS != null) {
anchor = prevBeforeWS;
if (isMarkdownComment()) {
anchor = getLastChildNode();
before = Boolean.FALSE;
} else {
anchor = getLastChildNode(); // this is a '*/'
ASTNode prevBeforeWS = TreeUtil.skipElementsBack(anchor.getTreePrev(), TokenSet.WHITE_SPACE);
if (prevBeforeWS != null) {
anchor = prevBeforeWS;
before = Boolean.FALSE;
} else {
before = Boolean.TRUE;
}
needToAddNewline = true;
}
else {
before = Boolean.TRUE;
}
needToAddNewline = true;
}
if (anchor.getElementType() != DOC_TAG) {
@@ -166,8 +170,8 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
CharTable charTable = SharedImplUtil.findCharTableByTree(this);
PsiManager psiManager = getManager();
if (JavaFileCodeStyleFacade.forContext(getContainingFile()).isJavaDocLeadingAsterisksEnabled() || isMarkdownComment()) {
TreeElement newLine = Factory.createSingleLeafElement(TokenType.WHITE_SPACE, "\n ", charTable, psiManager);
if (isMarkdownComment() || JavaFileCodeStyleFacade.forContext(getContainingFile()).isJavaDocLeadingAsterisksEnabled()) {
TreeElement newLine = Factory.createSingleLeafElement(TokenType.WHITE_SPACE, getNewLikeBuffer(), charTable, psiManager);
TreeElement leadingAsterisk = Factory.createSingleLeafElement(DOC_COMMENT_LEADING_ASTERISKS, getLeadingToken(), charTable, psiManager);
TreeElement commentData = Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", charTable, psiManager);
newLine.getTreeParent().addChild(leadingAsterisk);
@@ -176,7 +180,7 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
anchor = commentData;
}
else {
TreeElement newLine = Factory.createSingleLeafElement(TokenType.WHITE_SPACE, "\n ", charTable, psiManager);
TreeElement newLine = Factory.createSingleLeafElement(TokenType.WHITE_SPACE, getNewLikeBuffer(), charTable, psiManager);
anchor = super.addInternal(newLine, newLine, anchor, Boolean.FALSE);
}
before = Boolean.FALSE;
@@ -258,10 +262,11 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
return true;
}
private static boolean nodeOnSameLineWithCommentStartBlock(@NotNull ASTNode node) {
ASTNode current = TreeUtil.findSiblingBackward(node, DOC_COMMENT_START);
private boolean nodeOnSameLineWithCommentStartBlock(@NotNull ASTNode node) {
ASTNode current = TreeUtil.findSiblingBackward(node, isMarkdownComment() ? DOC_COMMENT_LEADING_ASTERISKS : DOC_COMMENT_START);
if (current == null) return false;
if (current == node) return true;
if (isMarkdownComment() && current != getFirstChild()) return false;
while (current.getTreeNext() != node) {
current = current.getTreeNext();
if (current.textContains('\n')) return false;
@@ -269,10 +274,16 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
return true;
}
/** @return The leading token depending on comment type */
private String getLeadingToken() {
return isMarkdownComment() ? LEADING_TOKEN_MARKDOWN : LEADING_TOKEN;
}
/** @return Content to insert on a new line. Markdown comments handle spacing differently */
private String getNewLikeBuffer() {
return isMarkdownComment() ? "\n" : "\n ";
}
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
if (child.getElementType() == DOC_TAG) {

View File

@@ -0,0 +1,5 @@
package com.siyeh.igtest.internationalization.unnecessary_unicode_escape;
/// We should not get any warning in this file for brackets
/// As demonstrated by [String#copyValueOf(char\d[\])]
class UnnecessaryUnicodeEscape {}

View File

@@ -0,0 +1,7 @@
class A {
void method<caret>(boolean a){}
/// {@link #method(boolean)}
void bar() {}
}

View File

@@ -0,0 +1,9 @@
import java.util.List;
class A {
void method(List<String> y, boolean a){}
/// {@link #method(List, boolean)}
void bar() {}
}

View File

@@ -0,0 +1,26 @@
/// Copyright 2000-2013 JetBrains s.r.o.
///
/// Licensed 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.
class Test {
/// Blah blah
///
/// @param arg too many
/// @return zero
public static int <caret>get(int arg) {
return 0;
}
}

View File

@@ -0,0 +1,26 @@
/// Copyright 2000-2013 JetBrains s.r.o.
///
/// Licensed 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.
class Test {
/// Blah blah
///
/// @param newArgs too many
/// @return zero
public static int <caret>get(double newArgs) {
return 0;
}
}

View File

@@ -0,0 +1,11 @@
class A {
/// Foo
///
/// @param i1 an int
/// @param i2 another int
void <caret>foo(int i1, int i2) {
}
}

View File

@@ -0,0 +1,10 @@
class A {
/// Foo
///
/// @param i1 an int
void foo(int i1) {
}
}

View File

@@ -0,0 +1,29 @@
/// Copyright 2000-2011 JetBrains s.r.o.
///
/// Licensed 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.
class C {
/// This is the role -
/// @param role another desc
/// @param labelExpression blah-blah
/// @return return description
public Integer ex<caret>ample(int role, String labelExpression) {
switch (role) {
case Constants.FOO:
break;
}
return 1;
}
}

View File

@@ -0,0 +1,29 @@
/// Copyright 2000-2011 JetBrains s.r.o.
///
/// Licensed 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.
class C {
/// This is the role -
///
/// @param role another desc
/// @return return description
public Integer example(int role) {
switch (role) {
case Constants.FOO:
break;
}
return 1;
}
}

View File

@@ -0,0 +1,9 @@
public class Test {
/// @param i
/// @param j
public void <caret>test123(int i,
int j) {
}
}

View File

@@ -0,0 +1,10 @@
public class Test {
/// @param i
/// @param j
/// @return
public Exception test123(int i,
int j) {
}
}

View File

@@ -0,0 +1,15 @@
class A {
/// Demo.
///
/// @param a
/// a.
/// @param b
/// b.
/// @param c
/// c.
public void <caret>demo(int a, int b, int c) {
}
}

View File

@@ -0,0 +1,15 @@
class A {
/// Demo.
///
/// @param a
/// a.
/// @param b
/// b.
/// @param c
/// c.
public void <caret>demo(int a, int b, int c) {
}
}

View File

@@ -0,0 +1,12 @@
class A {
/// Demo.
///
/// @param b b.
/// @param a a.
/// @param c c.
public void demo(int b, int a, int c) {
}
}

View File

@@ -0,0 +1,12 @@
class A {
/// Demo.
///
/// @param b b.
/// @param a a.
/// @param c c.
public void demo(int b, int a, int c) {
}
}

View File

@@ -0,0 +1,13 @@
class A {
/// Demo.
///
/// @param a
/// a.
/// @param b
/// b.
/// @param c
/// c.
public void <caret>demo(int a, int b, int c) {
}
}

View File

@@ -0,0 +1,10 @@
class A {
/// Demo.
///
/// @param b b.
/// @param a a.
/// @param c c.
public void demo(int b, int a, int c) {
}
}

View File

@@ -0,0 +1,23 @@
public class MyClass3
{
/// This method does amazing things.
///
/// @param a First parameter.
/// @param b Second parameter.
/// @param c Third parameter.
///
/// @return A magic string.
///
/// @since Blabla 1.2.
public String <caret>myMethod(int a, long b, boolean c)
{
return "Hi there!";
}
public static void main(String[] args)
{
System.out.println(new MyClass3().myMethod(1, "2", true));
}
}

View File

@@ -0,0 +1,22 @@
public class MyClass3
{
/// This method does amazing things.
///
/// @param b Second parameter.
/// @param a First parameter.
/// @param c Third parameter.
/// @param d
/// @return A magic string.
/// @since Blabla 1.2.
public String myMethod(int b, long a, boolean c, short d)
{
return "Hi there!";
}
public static void main(String[] args)
{
System.out.println(new MyClass3().myMethod(1, "2", true, ));
}
}

View File

@@ -0,0 +1,13 @@
class X {
/// Has a method called {@link #mymethod(int, int)}.
public class TestRefactorLink {
/// @return nothing
/// @param y yparam
/// @param z zparam
public void <caret>mymethod(int y, int z) { }
}
}

View File

@@ -0,0 +1,13 @@
class X {
/// Has a method called {@link #mymethod(int, int)}.
public class TestRefactorLink {
/// @return nothing
/// @param y yparam
/// @param z zparam
public void <caret>mymethod(int y, int z) { }
}
}

View File

@@ -0,0 +1,13 @@
class X {
/// Has a method called {@link #mymethod(int, int)}.
public class TestRefactorLink {
/// @param z zparam
/// @param y yparam
/// @return nothing
public void mymethod(int z, int y) { }
}
}

View File

@@ -0,0 +1,12 @@
class X {
/// Has a method called {@link #mymethod(int)}.
public class TestRefactorLink {
/// @return nothing
/// @param y yparam
public void <caret>mymethod(int y) { }
}
}

View File

@@ -0,0 +1,12 @@
class X {
/// Has a method called {@link #mymethod(boolean)}.
public class TestRefactorLink {
/// @param z yparam
/// @return nothing
public void mymethod(boolean z) { }
}
}

View File

@@ -0,0 +1,11 @@
class X {
/// Has a method called {@link #mymethod(boolean)}.
public class TestRefactorLink {
/// @param a aparam
public void <caret>mymethod(boolean a) { }
}
}

View File

@@ -0,0 +1,12 @@
class X {
/// Has a method called {@link #mymethod(boolean, boolean)}.
public class TestRefactorLink {
/// @param z
/// @param a aparam
public void mymethod(boolean z, boolean a) { }
}
}

View File

@@ -0,0 +1,11 @@
class X {
/// Has a method called {@link #mymethod(boolean)}.
public class TestRefactorLink {
/// @param x aparam
public void <caret>mymethod(boolean a) { }
}
}

View File

@@ -0,0 +1,12 @@
class X {
/// Has a method called {@link #mymethod(boolean, boolean)}.
public class TestRefactorLink {
/// @param x aparam
/// @param b
public void mymethod(boolean a, boolean b) { }
}
}

View File

@@ -0,0 +1,9 @@
class X {
public class TestRefactorLink {
/// Description
public void <caret>mymethod() { }
}
}

View File

@@ -0,0 +1,9 @@
class X {
public class TestRefactorLink {
/// Description
public void mymethod(boolean a) { }
}
}

View File

@@ -0,0 +1,7 @@
class X {
/// @param a aparam
/// @param b bparam
public void <caret>mymethod(boolean a, boolean b) { }
}

View File

@@ -0,0 +1,8 @@
class X {
/// @param a aparam
/// @param c
/// @param b1 bparam
public void mymethod(boolean a, boolean c, boolean b1) { }
}

View File

@@ -0,0 +1,13 @@
class X {
/// Has a method called {@link #mymethod(int, int)}.
public class TestRefactorLink {
/// @param z zparam
/// @param y yparam
/// @return nothing
public void mymethod(int z, int y) { }
}
}

View File

@@ -0,0 +1,27 @@
/// Record javadoc
/// @param x x
record Rec(int x) {
public R<caret>ec(int x) {
this.x = x;
}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(1);
System.out.println(rec.x());
}
void foo(Object obj) {
switch (obj) {
case Rec(int x) when x == 42 -> System.out.println(x);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
if (obj instanceof Rec(int x) && x == 42) {
System.out.println(x);
}
}
}

View File

@@ -0,0 +1,22 @@
/// @param point1 point1
/// @param point2 point2
record Rect(Point point1, Point point2) {
Rec<caret>t(Point point1, Point point2) {
this.point1 = point1;
this.point2 = point2;
}
}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point point1, Point point2) when point1.equals(point2) -> {}
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2)) rect when x1 == x2 -> System.out.println(point1);
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2) -> System.out.println(point2);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
}
}

View File

@@ -0,0 +1,23 @@
/// @param point1 point1
/// @param point2 point2
/// @param i
record Rect(Point point1, Point point2, int i) {
Rect(Point point1, Point point2, int i) {
this.point1 = point1;
this.point2 = point2;
}
}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {}
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
}
}

View File

@@ -0,0 +1,29 @@
/// Record javadoc
///
/// @param x x
/// @param y
record Rec(int x, int y) {
public Rec(int x, int y) {
this.x = x;
}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(1, );
System.out.println(rec.x());
}
void foo(Object obj) {
switch (obj) {
case Rec(int x, int y) when x == 42 -> System.out.println(x);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
if (obj instanceof Rec(int x, int y) && x == 42) {
System.out.println(x);
}
}
}

View File

@@ -0,0 +1,42 @@
/// @param x x
/// @param y y
/// @param z z
record Rec(int x, int y, int z) {
public R<caret>ec(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int x() {return x;}
public int y() {return y;}
public int z() {return z;}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(1, 2, 3);
System.out.println(rec.x());
System.out.println(rec.y());
System.out.println(rec.z());
}
void foo(Object obj) {
switch (obj) {
case Rec(int x, int y, int z) when x + y + z == 42 -> System.out.println(x + y + z);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
if (obj instanceof Rec(int x, int y, int z) rec) {
System.out.println(x + y + z);
}
}
void bar(Rec[] recs) {
for (Rec(int x, int y, int z) : recs) {
System.out.println(x + y + z);
}
}
}

View File

@@ -0,0 +1,24 @@
/// @param point1 point1
/// @param point2 point2
/// @param i i
record Rect(Point point1, Point point2, int i) {
Rec<caret>t(Point point1, Point point2, int i) {
this.point1 = point1;
this.point2 = point2;
this.i = i;
}
}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {}
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
}
}

View File

@@ -0,0 +1,24 @@
/// @param point2 point2
/// @param point1 point1
/// @param i i
record Rect(Point point2, Point point1, int i) {
Rect(Point point2, Point point1, int i) {
this.point2 = point2;
this.point1 = point1;
this.i = i;
}
}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point point2, Point point1, int i) when point2.equals(point1) -> {}
case Rect(Point(int y1, int x1) point2, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point2);
case Rect(Point(int x1, int y1), Point(int x2, int y2) point1, int i) -> System.out.println(point1);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
}
}

View File

@@ -0,0 +1,42 @@
/// @param y y
/// @param z z
/// @param x x
record Rec(int y, int z, int x) {
public Rec(int y, int z, int x) {
this.y = y;
this.z = z;
this.x = x;
}
public int y() {return y;}
public int z() {return z;}
public int x() {return x;}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(1, 2, 3);
System.out.println(rec.y());
System.out.println(rec.z());
System.out.println(rec.x());
}
void foo(Object obj) {
switch (obj) {
case Rec(int y, int z, int x) when y + z + x == 42 -> System.out.println(y + z + x);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
if (obj instanceof Rec(int y, int z, int x) rec) {
System.out.println(y + z + x);
}
}
void bar(Rec[] recs) {
for (Rec(int y, int z, int x) : recs) {
System.out.println(y + z + x);
}
}
}

View File

@@ -0,0 +1,41 @@
/// Record javadoc
/// @param x x
/// @param y y
/// @param z z
record Rec(int x, int y, int z) {
/// Constructor javadoc
/// @param x x
/// @param y y
/// @param z z
public R<caret>ec(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int x() {return x;}
public int y() {return y;}
public int z() {return z;}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(1, 2, 3);
System.out.println(rec.x());
System.out.println(rec.y());
System.out.println(rec.z());
}
void foo(Object obj) {
switch (obj) {
case Rec(int x, int y, int z) when x + y + z == 42 -> System.out.println(x + y + z);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
boolean b = obj instanceof Rec(int x, int y, int z) && x + y + z == 42;
}
}

View File

@@ -0,0 +1,24 @@
/// @param point1 point1
/// @param point2 point2
/// @param i i
record Rect(Point point1, Point point2, int i) {
Rec<caret>t(Point point1, Point point2, int i) {
this.point1 = point1;
this.point2 = point2;
this.i = i;
}
}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {}
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
default -> {}
}
}
}

View File

@@ -0,0 +1,24 @@
/// @param i i
/// @param point2 point2
/// @param point1 point1
record Rect(int i, Point point2, Point point1) {
Rect(int i, Point point2, Point point1) {
this.point1 = point1;
this.point2 = point2;
this.i = i;
}
}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(int i, Point point2, Point point1) when point1.equals(point2) -> {}
case Rect(int i, Point(int y2, int x2), Point(int y1, int x1) point1) rect when x1 == x2 -> System.out.println(point1);
case Rect(int i, Point(int x2, int y2) point2, Point(int x1, int y1)) -> System.out.println(point2);
default -> {}
}
}
}

View File

@@ -0,0 +1,43 @@
/// Record javadoc
///
/// @param y y
/// @param z z
/// @param x x
record Rec(int y, int z, int x) {
/// Constructor javadoc
///
/// @param y y
/// @param z z
/// @param x x
public Rec(int y, int z, int x) {
this.x = x;
this.y = y;
this.z = z;
}
public int x() {return x;}
public int y() {return y;}
public int z() {return z;}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(2, 3, 1);
System.out.println(rec.x());
System.out.println(rec.y());
System.out.println(rec.z());
}
void foo(Object obj) {
switch (obj) {
case Rec(int y, int z, int x) when x + y + z == 42 -> System.out.println(x + y + z);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
boolean b = obj instanceof Rec(int y, int z, int x) && x + y + z == 42;
}
}

View File

@@ -0,0 +1,12 @@
/// Record javadoc
record R<caret>ec() {
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec();
System.out.println(rec);
}
}

View File

@@ -0,0 +1,12 @@
/// Record javadoc
record Rec(java.util.List<String> y) {
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec();
System.out.println(rec);
}
}

View File

@@ -0,0 +1,31 @@
/// @param x x
/// @param y y
/// @param z z
record R<caret>ec(int x, int y, int z) {
public int y() {
return this.y;
}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(1, 2, 3);
System.out.println(rec.y());
}
void foo(Object obj) {
switch (obj) {
case Rec(int x, int y, int z) when y == 42 -> System.out.println(y);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
if (!(obj instanceof Rec(int x, int y, int z) && y == 42)) {
System.out.println("hello");
}
else {
System.out.println(y);
}
}
}

View File

@@ -0,0 +1,18 @@
/// @param point1 point1
/// @param point2 point2
/// @param i i
record Re<caret>ct(Point point1, Point point2, int i) {}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point point1, Point point2, int i) when point2.x() == 42 -> System.out.println(point2);
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
}
}

View File

@@ -0,0 +1,16 @@
/// @param p2 point2
record Rect(Point p2) {}
record Point(int y, int x) {}
class Use {
void foo(Object obj) {
switch (obj) {
case Rect(Point p2) when p2.x() == 42 -> System.out.println(p2);
case Rect(Point(int y2, int x2)) rect when x1 == x2 -> System.out.println(point1);
case Rect(Point(int x2, int y2) p2) -> System.out.println(p2);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
}
}

View File

@@ -0,0 +1,29 @@
/// @param yyy y
record Rec(long yyy) {
public long yyy() {
return this.yyy;
}
}
class Use {
public static void main(String[] args) {
Rec rec = new Rec(2);
System.out.println(rec.yyy());
}
void foo(Object obj) {
switch (obj) {
case Rec(long yyy) when yyy == 42 -> System.out.println(yyy);
default -> throw new IllegalStateException("Unexpected value: " + obj);
}
if (!(obj instanceof Rec(long yyy) && yyy == 42)) {
System.out.println("hello");
}
else {
System.out.println(yyy);
}
}
}

View File

@@ -0,0 +1,6 @@
class X {
/// documentation
public void <caret>mymethod() { }
}

View File

@@ -0,0 +1,8 @@
class X {
/// documentation
///
/// @return
public int mymethod() { }
}

View File

@@ -0,0 +1,6 @@
class X {
/// documentation
public String <caret>mymethod() { }
}

View File

@@ -0,0 +1,6 @@
class X {
/// documentation
public int <caret>mymethod() { }
}

View File

@@ -0,0 +1,8 @@
class X {
/// Has a method called {@link #mymethod(int, int)}.
public class TestRefactorLink {
public void <caret>mymethod(int y, int z) { }
}
}

View File

@@ -0,0 +1,8 @@
class X {
/// Has a method called {@link #mymethod(int, boolean)}.
public class TestRefactorLink {
public void mymethod(int y, boolean b) { }
}
}

View File

@@ -198,6 +198,51 @@ public class JavadocParamTagsTest extends LightIdeaTestCase {
*/""", docComment.getText());
}
public void testMarkdownRemoveTags() {
final PsiElementFactory factory = getFactory();
final PsiMethod method = factory.createMethodFromText(
"""
/// @param p1
/// @param p2
/// @param p3
void m() {}""", null);
final PsiDocComment docComment = method.getDocComment();
assertNotNull(docComment);
WriteCommandAction.runWriteCommandAction(null, () -> docComment.getTags()[1].delete());
assertEquals("""
/// @param p1
/// @param p3""", docComment.getText());
WriteCommandAction.runWriteCommandAction(null, () -> docComment.getTags()[0].delete());
assertEquals("""
/// @param p3""", docComment.getText());
WriteCommandAction.runWriteCommandAction(null, () -> docComment.getTags()[0].delete());
assertEquals("""
///""", docComment.getText());
}
public void testMarkdownAddTags() {
final PsiElementFactory factory = getFactory();
final PsiMethod method = factory.createMethodFromText(
"""
/// Javadoc
/// @param first
void m(int first, int second, int third);""", null);
final PsiDocComment docComment = method.getDocComment();
assertNotNull(docComment);
final PsiDocTag[] tags = docComment.getTags();
final PsiDocTag tag2 = factory.createParamTag("second", "");
docComment.addAfter(tag2, tags[0]);
assertEquals(
"""
/// Javadoc
/// @param first
/// @param second""", docComment.getText());
}
private PsiElementFactory getFactory() {
final PsiManager manager = getPsiManager();
return JavaPsiFacade.getElementFactory(manager.getProject());

View File

@@ -707,5 +707,217 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest {
}, false);
}
/* Markdown javadoc variant */
public void testParamJavadocMarkdown2() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.createNew().withName("z").withType(PsiTypes.booleanType()),
ParameterInfoImpl.create(0).withName("a").withType(PsiTypes.booleanType()),
}, false);
}
public void testRecordHeaderDeleteRenameMarkdown() {
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withName("yyy").withType(PsiTypes.longType())
};
}, false);
}
public void testRecordCanonicalConstructorReorderMarkdown2() {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null);
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(2).withName("i").withType(PsiTypes.intType()),
ParameterInfoImpl.create(1).withName("point2").withType(pointType),
ParameterInfoImpl.create(0).withName("point1").withType(pointType),
};
}, false);
}
public void testJavadocMarkdownOfDeleted() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("role").withType(PsiTypes.intType()),
}, false);
}
public void testRecordCanonicalConstructorAddParameterMarkdown2() {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null);
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("point1").withType(pointType),
ParameterInfoImpl.create(1).withName("point2").withType(pointType),
ParameterInfoImpl.create(-1).withName("i").withType(PsiTypes.intType())
};
}, false);
}
public void testJavadocMarkdownNoNewLineInserted() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("newArgs").withType(PsiTypes.doubleType()),
}, false);
}
public void testMultilineJavadocMarkdownWithoutFormatting() { // IDEA-281568
JavaCodeStyleSettings.getInstance(getProject()).ENABLE_JAVADOC_FORMATTING = false;
doTest(null, null, null, method -> new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withType(PsiTypes.intType()).withName("b"),
ParameterInfoImpl.create(0).withType(PsiTypes.intType()).withName("a"),
ParameterInfoImpl.create(2).withType(PsiTypes.intType()).withName("c"),
}, false);
}
public void testParamJavadocMarkdown1() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("z").withType(PsiTypes.booleanType())
}, false);
}
public void testParamJavadocMarkdown0() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withName("z").withType(PsiTypes.intType()),
ParameterInfoImpl.create(0).withName("y").withType(PsiTypes.intType())
}, false);
}
public void testReturnJavadocMarkdownAdded() {
doTest("int", new ParameterInfoImpl[0], false);
}
public void testRecordCanonicalConstructorRenameMarkdown() {
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("y").withType(PsiTypes.intType()),
ParameterInfoImpl.create(1).withName("z").withType(PsiTypes.intType()),
ParameterInfoImpl.create(2).withName("x").withType(PsiTypes.intType())
};
}, false);
}
public void testParamJavadocMarkdown() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withName("z").withType(PsiTypes.intType()),
ParameterInfoImpl.create(0).withName("y").withType(PsiTypes.intType())
}, false);
}
public void testRecordCanonicalConstructorAddParameterMarkdown() {
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("x").withType(PsiTypes.intType()),
ParameterInfoImpl.create(-1).withName("y").withType(PsiTypes.intType())
};
}, false);
}
public void testParamJavadocMarkdown4() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.createNew().withName("a").withType(PsiTypes.booleanType()),
}, false);
}
public void testSCRMarkdown40895() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("y").withType(PsiTypes.intType()),
ParameterInfoImpl.create(1).withName("b").withType(PsiTypes.booleanType())
}, false);
}
public void testReturnJavadocMarkdownUnchanged() {
doTest("int", new ParameterInfoImpl[0], false);
}
public void testRecordComponentWithImportToBeAddedMarkdown() {
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(-1).withName("y").withType(myFactory.createTypeFromText("java.util.List<java.lang.String>", method))
};
}, false);
}
public void testMethodParametersAlignmentAfterMethodReturnTypeChangeMarkdown() {
getJavaSettings().ALIGN_MULTILINE_PARAMETERS = true;
getJavaSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
doTest(null, null, "Exception", new SimpleParameterGen(), new SimpleExceptionsGen(), false);
}
public void testParamJavadocMarkdown3() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("a").withType(PsiTypes.booleanType()),
ParameterInfoImpl.createNew().withName("b").withType(PsiTypes.booleanType()),
}, false);
}
public void testRecordHeaderDeleteRenameMarkdown2() {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null);
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withName("p2").withType(pointType)
};
}, false);
}
public void testParamJavadocMarkdownRenamedReordered() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("a").withType(PsiTypes.booleanType()),
ParameterInfoImpl.createNew().withName("c").withType(PsiTypes.booleanType()),
ParameterInfoImpl.create(1).withName("b1").withType(PsiTypes.booleanType()),
}, false);
}
public void testJavadocMarkdownGenericsLink() {
doTest(null, new ParameterInfoImpl[]{
ParameterInfoImpl.createNew().withName("y").withType(myFactory.createTypeFromText("java.util.List<java.lang.String>", null)),
ParameterInfoImpl.create(0).withName("a").withType(PsiTypes.booleanType())
}, false);
}
public void testRecordCanonicalConstructorReorderMarkdown() {
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withName("y").withType(PsiTypes.intType()),
ParameterInfoImpl.create(2).withName("z").withType(PsiTypes.intType()),
ParameterInfoImpl.create(0).withName("x").withType(PsiTypes.intType())
};
}, false);
}
public void testMultilineJavadocMarkdown() { // IDEA-281568
doTest(null, null, null, method -> new ParameterInfoImpl[]{
ParameterInfoImpl.create(1).withType(PsiTypes.intType()).withName("b"),
ParameterInfoImpl.create(0).withType(PsiTypes.intType()).withName("a"),
ParameterInfoImpl.create(2).withType(PsiTypes.intType()).withName("c"),
}, false);
}
public void testNoGapsInParameterTagsMarkdown() { // IDEA-139879
doTest(null, null, null, method -> new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withType(PsiTypes.intType()).withName("b"),
ParameterInfoImpl.create(1).withType(PsiTypes.longType()).withName("a"),
ParameterInfoImpl.create(2).withType(PsiTypes.booleanType()).withName("c"),
ParameterInfoImpl.createNew().withType(PsiTypes.shortType()).withName("d"),
}, false);
}
public void testRecordCanonicalConstructorRenameMarkdown2() {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null);
doTest(null, null, null, method -> {
return new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withName("point2").withType(pointType),
ParameterInfoImpl.create(1).withName("point1").withType(pointType),
ParameterInfoImpl.create(2).withName("i").withType(PsiTypes.intType())
};
}, false);
}
public void testJavadocMarkdownNotBrokenAfterDelete() { // IDEA-139879
doTest(null, null, null, method -> new ParameterInfoImpl[]{
ParameterInfoImpl.create(0).withType(PsiTypes.intType()).withName("i1")
}, false);
}
/* workers */
}