mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
for "Result of method call ignored" inspection GitOrigin-RevId: e3face53d7745d416fba8a22f2e02a1954f71442
806 lines
25 KiB
Java
806 lines
25 KiB
Java
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
|
package com.siyeh.ig.bugs;
|
|
|
|
import com.intellij.codeInspection.LocalInspectionTool;
|
|
import com.intellij.openapi.util.registry.Registry;
|
|
import com.intellij.psi.JavaCodeFragmentFactory;
|
|
import com.intellij.psi.PsiFile;
|
|
import com.intellij.testFramework.LightProjectDescriptor;
|
|
import com.siyeh.ig.LightJavaInspectionTestCase;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
@SuppressWarnings("ALL")
|
|
public class IgnoreResultOfCallInspectionTest extends LightJavaInspectionTestCase {
|
|
@Override
|
|
protected LocalInspectionTool getInspection() {
|
|
return new IgnoreResultOfCallInspection();
|
|
}
|
|
|
|
@NotNull
|
|
@Override
|
|
protected LightProjectDescriptor getProjectDescriptor() {
|
|
return JAVA_15;
|
|
}
|
|
|
|
@Override
|
|
protected String[] getEnvironmentClasses() {
|
|
return new String[]{
|
|
"""
|
|
package java.util.regex;
|
|
|
|
public class Pattern {
|
|
public static Pattern compile(String regex) {return null;}
|
|
|
|
public Matcher matcher(CharSequence input) {return null;}
|
|
}
|
|
""",
|
|
"""
|
|
package java.util.regex;
|
|
|
|
public class Matcher {
|
|
public boolean find() {return true;}
|
|
}
|
|
""",
|
|
"""
|
|
package javax.annotation;
|
|
|
|
import java.lang.annotation.Documented;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.lang.annotation.Target;
|
|
|
|
import javax.annotation.meta.When;
|
|
|
|
@Documented
|
|
@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.PACKAGE })
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
public @interface CheckReturnValue {
|
|
When when() default When.ALWAYS;
|
|
}
|
|
""",
|
|
"""
|
|
package com.google.errorprone.annotations;
|
|
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
|
import static java.lang.annotation.ElementType.METHOD;
|
|
import static java.lang.annotation.ElementType.PACKAGE;
|
|
import static java.lang.annotation.ElementType.TYPE;
|
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
import java.lang.annotation.Documented;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.Target;
|
|
@Documented
|
|
@Target({METHOD,CONSTRUCTOR,TYPE,PACKAGE})
|
|
@Retention(value=RUNTIME)
|
|
public @interface CheckReturnValue {}
|
|
""",
|
|
"""
|
|
package org.jetbrains.annotations;
|
|
import java.lang.annotation.Documented;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Target;
|
|
@Documented
|
|
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.PACKAGE})
|
|
public @interface CheckReturnValue {}
|
|
""",
|
|
"""
|
|
package org.springframework.lang;
|
|
import java.lang.annotation.Documented;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Target;
|
|
@Documented
|
|
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.PACKAGE})
|
|
public @interface CheckReturnValue {}
|
|
""",
|
|
"""
|
|
package org.assertj.core.util;
|
|
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
|
import static java.lang.annotation.ElementType.METHOD;
|
|
import static java.lang.annotation.ElementType.PACKAGE;
|
|
import static java.lang.annotation.ElementType.TYPE;
|
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.Target;
|
|
@Target({CONSTRUCTOR,METHOD,PACKAGE,TYPE})
|
|
@Retention(value=CLASS)
|
|
public @interface CheckReturnValue {}
|
|
""",
|
|
"""
|
|
package a;
|
|
public @interface CheckReturnValue {}
|
|
""",
|
|
"""
|
|
package com.google.errorprone.annotations;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.lang.annotation.Target;
|
|
@Target({ElementType.METHOD, ElementType.TYPE})
|
|
@Retention(RetentionPolicy.CLASS)
|
|
public @interface CanIgnoreReturnValue {}
|
|
""",
|
|
"""
|
|
package org.assertj.core.util;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.lang.annotation.Target;
|
|
@Target({CONSTRUCTOR,METHOD,PACKAGE,TYPE})
|
|
@Retention(value=CLASS)
|
|
public @interface CanIgnoreReturnValue{}
|
|
""",
|
|
"""
|
|
package org.apache.commons.lang3;
|
|
public class Validate {
|
|
public native static <T> T notNull(T object);
|
|
}""",
|
|
"""
|
|
package org.junit.jupiter.api.function;
|
|
public interface Executable {
|
|
void execute() throws Throwable;
|
|
}""",
|
|
"""
|
|
package org.junit.jupiter.api;
|
|
import org.junit.jupiter.api.function.Executable;
|
|
import java.util.function.Supplier;
|
|
public class Assertions {
|
|
public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable) {
|
|
return null;
|
|
}
|
|
public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier) {
|
|
return null;
|
|
}
|
|
}""",
|
|
"""
|
|
package org.assertj.core.api.ThrowableAssert;
|
|
public interface ThrowingCallable {
|
|
void call() throws Throwable;
|
|
}""",
|
|
"""
|
|
package org.assertj.core.api;
|
|
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
|
public class Assertions {
|
|
public static Object assertThatThrownBy(ThrowingCallable shouldRaiseThrowable) {
|
|
return null;
|
|
}
|
|
}""",
|
|
"""
|
|
package org.mockito;
|
|
public interface MockedStatic<T> {
|
|
Object when(Verification v);
|
|
interface Verification {
|
|
void apply();
|
|
}
|
|
}""",
|
|
"""
|
|
package java.nio;
|
|
public abstract class ByteBuffer{
|
|
abstract boolean hasRemaining();
|
|
}
|
|
""",
|
|
"""
|
|
package java.nio.channels;
|
|
import java.nio.ByteBuffer;
|
|
import java.io.IOException;
|
|
public abstract class FileChannel{
|
|
public abstract int write(ByteBuffer src) throws IOException;
|
|
}
|
|
"""};
|
|
}
|
|
|
|
public void testJetbrainsAnnotationOnClass() {
|
|
doTest("""
|
|
import org.jetbrains.annotations.CheckReturnValue;
|
|
|
|
@CheckReturnValue
|
|
class Test {
|
|
|
|
String foo() {
|
|
return "foo";
|
|
}
|
|
|
|
public static void main(String[] args){
|
|
new Test()./*Result of 'Test.foo()' is ignored*/foo/**/();
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testSpringAnnotationOnClass() {
|
|
doTest("""
|
|
import org.springframework.lang.CheckReturnValue;
|
|
|
|
@CheckReturnValue
|
|
class Test {
|
|
|
|
String foo() {
|
|
return "foo";
|
|
}
|
|
|
|
public static void main(String[] args){
|
|
new Test()./*Result of 'Test.foo()' is ignored*/foo/**/();
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testCanIgnoreReturnValue() {
|
|
doTest("""
|
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|
import javax.annotation.CheckReturnValue;
|
|
|
|
@CheckReturnValue
|
|
class Test {
|
|
int lookAtMe() { return 1; }
|
|
|
|
@CanIgnoreReturnValue
|
|
int ignoreMe() { return 2; }
|
|
|
|
void run() {
|
|
/*Result of 'Test.lookAtMe()' is ignored*/lookAtMe/**/(); // Bad! This line should produce a warning.
|
|
ignoreMe(); // OK. This line should *not* produce a warning.
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testCanIgnoreReturnValue2() {
|
|
doTest(
|
|
"""
|
|
class TestClass {
|
|
|
|
public void m() {
|
|
var javax = new Javax();
|
|
javax./*Result of 'Javax.unannotated()' is ignored*/unannotated/**/();
|
|
javax.assertJ();
|
|
javax.errorProne();
|
|
|
|
var errorProne = new ErrorProne();
|
|
errorProne./*Result of 'ErrorProne.unannotated()' is ignored*/unannotated/**/();
|
|
errorProne.assertJ();
|
|
errorProne.errorProne();
|
|
|
|
var assertJ = new AssertJ();
|
|
assertJ./*Result of 'AssertJ.unannotated()' is ignored*/unannotated/**/();
|
|
assertJ.assertJ();
|
|
assertJ.errorProne();
|
|
|
|
}
|
|
|
|
@javax.annotation.CheckReturnValue
|
|
public static class Javax {
|
|
int unannotated() {
|
|
return 3;
|
|
}
|
|
|
|
@org.assertj.core.util.CanIgnoreReturnValue
|
|
int assertJ() {
|
|
return 3;
|
|
}
|
|
|
|
@com.google.errorprone.annotations.CanIgnoreReturnValue
|
|
int errorProne() {
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
@com.google.errorprone.annotations.CheckReturnValue
|
|
public static class ErrorProne {
|
|
int unannotated() {
|
|
return 3;
|
|
}
|
|
|
|
@org.assertj.core.util.CanIgnoreReturnValue
|
|
int assertJ() {
|
|
return 3;
|
|
}
|
|
|
|
@com.google.errorprone.annotations.CanIgnoreReturnValue
|
|
int errorProne() {
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
@org.assertj.core.util.CheckReturnValue
|
|
public static class AssertJ {
|
|
int unannotated() {
|
|
return 3;
|
|
}
|
|
|
|
@org.assertj.core.util.CanIgnoreReturnValue
|
|
int assertJ() {
|
|
return 3;
|
|
}
|
|
|
|
@com.google.errorprone.annotations.CanIgnoreReturnValue
|
|
int errorProne() {
|
|
return 3;
|
|
}
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testCanIgnoreReturnValue3() {
|
|
doTest(
|
|
"""
|
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|
import com.google.errorprone.annotations.CheckReturnValue;
|
|
@CheckReturnValue
|
|
class Test {
|
|
static int lookAtMe() { return 1; }
|
|
@CanIgnoreReturnValue
|
|
static int ignoreMe() { return 2; }
|
|
void run() {
|
|
/*Result of 'Test.lookAtMe()' is ignored*/lookAtMe/**/(); // <- inspection\s
|
|
ignoreMe(); // <- also inspection
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testCustomCheckReturnValue() {
|
|
doTest("""
|
|
import a.CheckReturnValue;
|
|
|
|
class Test {
|
|
@CheckReturnValue
|
|
int lookAtMe() { return 1; }
|
|
|
|
void run() {
|
|
/*Result of 'Test.lookAtMe()' is ignored*/lookAtMe/**/();
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testObjectMethods() {
|
|
doTest("""
|
|
class C {
|
|
void foo(Object o, String s) {
|
|
o./*Result of 'Object.equals()' is ignored*/equals/**/(s);
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testMatcher() {
|
|
doTest("""
|
|
class C {
|
|
void matcher() {
|
|
final java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("baaaa");
|
|
final java.util.regex.Matcher matcher = pattern.matcher("babaaaaaaaa");
|
|
matcher./*Result of 'Matcher.find()' is ignored*/find/**/();
|
|
matcher.notifyAll();
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testReader() {
|
|
doTest("import java.io.Reader;" +
|
|
"import java.io.IOException;" +
|
|
"class U {" +
|
|
" void m(Reader r) throws IOException {" +
|
|
" r./*Result of 'Reader.read()' is ignored*/read/**/();" +
|
|
" }" +
|
|
"}");
|
|
}
|
|
|
|
public void testJSR305Annotation() {
|
|
doTest("import javax.annotation.CheckReturnValue;" +
|
|
"class A {" +
|
|
" @CheckReturnValue" +
|
|
" static Object a() {" +
|
|
" return null;" +
|
|
" }" +
|
|
" void b() {" +
|
|
" /*Result of 'A.a()' is ignored*/a/**/();" +
|
|
" }" +
|
|
"}");
|
|
}
|
|
|
|
public void testRandomGetter() {
|
|
doTest("class A {" +
|
|
" private String name;" +
|
|
" public String getName() {" +
|
|
" return name;" +
|
|
" }" +
|
|
" void m() {" +
|
|
" /*Result of 'A.getName()' is ignored*/getName/**/();" +
|
|
" }" +
|
|
"}");
|
|
}
|
|
|
|
public void testJSR305Annotation2() {
|
|
doTest("import javax.annotation.CheckReturnValue;" +
|
|
"@CheckReturnValue " +
|
|
"class A {" +
|
|
" static Object a() {" +
|
|
" return null;" +
|
|
" }" +
|
|
" void b() {" +
|
|
" /*Result of 'A.a()' is ignored*/a/**/();" +
|
|
" }" +
|
|
"}");
|
|
}
|
|
|
|
public void testJSR305Annotation3() {
|
|
doTest("import javax.annotation.CheckReturnValue;" +
|
|
"@CheckReturnValue " +
|
|
"class Parent {" +
|
|
" class A {" +
|
|
" Object a() {" +
|
|
" return null;" +
|
|
" }" +
|
|
" void b() {" +
|
|
" /*Result of 'A.a()' is ignored*/a/**/();" +
|
|
" }" +
|
|
" }" +
|
|
"}");
|
|
}
|
|
|
|
public void testInference() {
|
|
Registry.get("ide.ignore.call.result.inspection.honor.inferred.pure").setValue(true, getTestRootDisposable());
|
|
doTest(
|
|
"""
|
|
class Test {
|
|
private static <T> T checkNotNull(T reference) {
|
|
if (reference == null) {
|
|
throw new NullPointerException();
|
|
}
|
|
return reference;
|
|
}
|
|
\s
|
|
private static String twice(String s) {
|
|
return s+s;
|
|
}
|
|
\s
|
|
void test(String string) {
|
|
checkNotNull(string);
|
|
/*Result of 'Test.twice()' is ignored*/twice/**/("foo");
|
|
/*Result of 'Test.twice()' is ignored*/twice/**/("bar");
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testPureMethod() {
|
|
doTest(
|
|
"""
|
|
import org.jetbrains.annotations.Contract;
|
|
|
|
class Util {
|
|
@Contract(pure=true)
|
|
static Object util() { return null; }
|
|
}
|
|
|
|
class C {
|
|
static {
|
|
Util./*Result of 'Util.util()' is ignored*/util/**/();
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testPureMethodReturningThis() {
|
|
doTest(
|
|
"""
|
|
import org.jetbrains.annotations.Contract;
|
|
|
|
class Test {
|
|
boolean closed;
|
|
\s
|
|
@Contract(pure=true, value="->this")
|
|
Test validate() {
|
|
if(closed) throw new IllegalStateException();
|
|
return this;
|
|
}
|
|
\s
|
|
void test() {
|
|
validate();
|
|
System.out.println("ok");
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testPureMethodInVoidFunctionalExpression() {
|
|
doTest(
|
|
"""
|
|
import org.jetbrains.annotations.Contract;
|
|
|
|
class Util {
|
|
@Contract(pure=true)
|
|
static Object util() { return null; }
|
|
}
|
|
|
|
class C {
|
|
static {
|
|
Runnable r = () -> Util./*Result of 'Util.util()' is ignored*/util/**/();
|
|
Runnable r1 = Util::/*Result of 'Util.util()' is ignored*/util/**/;
|
|
Runnable r2 = Object::new; // Reported by ResultOfObjectAllocationIgnoredInspection
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testStream() {
|
|
doTest(
|
|
"""
|
|
import java.util.stream.*;
|
|
import java.util.*;
|
|
|
|
class Test {
|
|
void test() {
|
|
Stream.of("a", "b", "c")./*Result of 'Stream.collect()' is ignored*/collect/**/(Collectors.toSet());
|
|
Stream.of("a", "b", "c")./*Result of 'Stream.collect()' is ignored*/collect/**/(Collectors.toCollection(() -> new ArrayList<>()));
|
|
Set<String> result = new TreeSet<>();
|
|
result.add("-");
|
|
// violates stream principles, but quite widely used (IDEA-164501);
|
|
// this inspection should not warn here; probably some other inspection should suggest better option\s
|
|
Stream.of("a", "b", "c").collect(Collectors.toCollection(() -> result));
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testPattern() {
|
|
doTest(
|
|
"""
|
|
import java.util.regex.Pattern;
|
|
import java.util.Set;
|
|
|
|
class Test {
|
|
void test(Set<String> names) {
|
|
names.forEach(Pattern::/*Result of 'Pattern.compile()' is ignored*/compile/**/);
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testPatternCaught() {
|
|
doTest(
|
|
"""
|
|
import java.util.regex.*;
|
|
import java.util.Set;
|
|
|
|
class Test {
|
|
void test(Set<String> names) {
|
|
try {
|
|
names.forEach(Pattern::compile);
|
|
}
|
|
catch (PatternSyntaxException e) {
|
|
throw new RuntimeException("Pattern error", e);
|
|
}
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testOptionalOrElseThrow() {
|
|
//noinspection OptionalUsedAsFieldOrParameterType
|
|
doTest(
|
|
"""
|
|
import java.util.Optional;
|
|
|
|
class Test {
|
|
void test(Optional<String> opt) {
|
|
opt.orElseThrow(RuntimeException::new);
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testParamContract() {
|
|
doTest(
|
|
"""
|
|
class X{
|
|
public static int atLeast(int min, int actual, String varName) {
|
|
if (actual < min) throw new IllegalArgumentException('\\'' + varName + " must be at least " + min + ": " + actual);
|
|
return actual;
|
|
}
|
|
|
|
public byte[] getMemory(int address, int length) {
|
|
atLeast(0, address, "address");
|
|
atLeast(1, length, "length");
|
|
|
|
return new byte[length];
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testInForExpressionList() {
|
|
//noinspection StatementWithEmptyBody
|
|
doTest(
|
|
"""
|
|
class X {
|
|
void test(String s) {
|
|
for(int i=0; i<10; i++, s./*Result of 'String.trim()' is ignored*/trim/**/()) {}
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testInSwitchExpression() {
|
|
//noinspection SwitchStatementWithTooFewBranches
|
|
doTest("""
|
|
class X {
|
|
String test(String s) {
|
|
return switch(s) {
|
|
default -> s.trim();
|
|
};
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testOptionalGet() {
|
|
//noinspection ALL
|
|
doTest(
|
|
"""
|
|
class X {
|
|
void test(java.util.Optional<String> opt) {
|
|
opt.get();
|
|
if (opt.isPresent()) opt./*Result of 'Optional.get()' is ignored*/get/**/();
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testCommonsLang3NotNull() {
|
|
doTest(
|
|
"""
|
|
import org.apache.commons.lang3.Validate;
|
|
class X{
|
|
void test(String foo) {
|
|
if (foo == null) return;
|
|
Validate.notNull(foo);
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testVoidType() {
|
|
doTest("""
|
|
class X {
|
|
void a() {
|
|
b();
|
|
}
|
|
\s
|
|
static Void b() {
|
|
return null;
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testIgnoreMethodDefinedInSubclasses() {
|
|
doTest(
|
|
"""
|
|
import java.util.stream.Stream;
|
|
import java.util.*;
|
|
abstract class StreamEx<T> implements Stream<T> {
|
|
public <C extends Collection<? super T>> C into(C collection) {
|
|
return null;
|
|
}
|
|
\s
|
|
public static<T> StreamEx<T> of(T... values) {
|
|
return null;\s
|
|
}
|
|
\s
|
|
public static void main(String[] args) {
|
|
List<Integer> list = new ArrayList<>();
|
|
StreamEx.of(1, 2, 3).into(list);
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testStringBuilderMethods() {
|
|
//noinspection DataFlowIssue,EqualsOnSuspiciousObject,TooBroadScope
|
|
doTest(
|
|
"""
|
|
class X {
|
|
void x() {
|
|
String abc = "abc";
|
|
StringBuilder sb = new StringBuilder(abc);
|
|
|
|
abc./*Result of 'String.substring()' is ignored*/substring/**/(0, 1); // OK, warning: Result of `String.substring()` is ignored
|
|
abc./*Result of 'String.compareTo()' is ignored*/compareTo/**/(null);
|
|
sb./*Result of 'AbstractStringBuilder.substring()' is ignored*/substring/**/(0, 1); // KO, no warning
|
|
sb./*Result of 'Object.equals()' is ignored*/equals/**/(null);
|
|
sb./*Result of 'AbstractStringBuilder.capacity()' is ignored*/capacity/**/();
|
|
sb./*Result of 'AbstractStringBuilder.chars()' is ignored*/chars/**/();
|
|
sb./*Result of 'AbstractStringBuilder.codePointAt()' is ignored*/codePointAt/**/(1);
|
|
sb./*Result of 'AbstractStringBuilder.codePointBefore()' is ignored*/codePointBefore/**/(1);
|
|
sb./*Result of 'AbstractStringBuilder.codePointCount()' is ignored*/codePointCount/**/(0, 1);
|
|
sb./*Result of 'AbstractStringBuilder.codePoints()' is ignored*/codePoints/**/();
|
|
sb./*Result of 'StringBuilder.compareTo()' is ignored*/compareTo/**/(null);
|
|
sb./*Result of 'AbstractStringBuilder.offsetByCodePoints()' is ignored*/offsetByCodePoints/**/(0, 1);
|
|
System.out.println(sb);
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testParseShort() {
|
|
doTest(
|
|
"""
|
|
class X {
|
|
boolean validate(String s) {
|
|
try {
|
|
Short.parseShort(s);
|
|
return true;
|
|
}
|
|
catch (NumberFormatException e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
@SuppressWarnings("Convert2Lambda")
|
|
public void testIgnoreInTestContainers() {
|
|
doTest(
|
|
"""
|
|
import org.junit.jupiter.api.function.Executable;
|
|
import org.mockito.MockedStatic;
|
|
class X {
|
|
public static String name(){return "name";}
|
|
public void test(String s, MockedStatic<Object> mockedStatic){
|
|
mockedStatic.when(X::name);
|
|
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class, ()->Short.parseShort(s));
|
|
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class, ()->Short.parseShort(s),
|
|
() -> {
|
|
Short./*Result of 'Short.parseShort()' is ignored*/parseShort/**/(s);
|
|
return "test";
|
|
});
|
|
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class, ()-> {
|
|
Short.parseShort("s");
|
|
});
|
|
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class, ()-> {
|
|
twice("abc");
|
|
});
|
|
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class, (new Executable() {
|
|
@Override
|
|
public void execute() {
|
|
twice("abc");
|
|
}}));
|
|
org.assertj.core.api.Assertions.assertThatThrownBy((((()->Short.parseShort(s)))));
|
|
}
|
|
private static String twice(String s) {
|
|
return s+s;
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testArgumentSideEffects() {
|
|
doTest("""
|
|
import java.nio.channels.FileChannel;
|
|
import java.nio.ByteBuffer;
|
|
import java.io.IOException;
|
|
class X {
|
|
public static void withoutSideEffects(FileChannel fch, ByteBuffer[] srcs) throws IOException {
|
|
fch./*Result of 'FileChannel.write()' is ignored*/write/**/(srcs);
|
|
}
|
|
public static long useResult(FileChannel fch, ByteBuffer[] srcs) throws IOException {
|
|
return fch.write(srcs);
|
|
}
|
|
public static void hasSideEffect(FileChannel fch, ByteBuffer[] srcs) throws IOException {
|
|
do{
|
|
fch.write(srcs);
|
|
} while (test(srcs));
|
|
}
|
|
|
|
public static boolean test(ByteBuffer[] srcs){
|
|
return srcs[0].hasRemaining();
|
|
}
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testFragment() {
|
|
PsiFile file = JavaCodeFragmentFactory.getInstance(getProject()).createCodeBlockCodeFragment("String.format(\"hello\");", null, true);
|
|
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
|
|
myFixture.testHighlighting(true, false, false);
|
|
}
|
|
} |