Skip to content

Commit

Permalink
fix all other "argument" checker framework warn
Browse files Browse the repository at this point in the history
  • Loading branch information
vananiev committed Nov 3, 2024
1 parent b51b9c7 commit b619ea6
Show file tree
Hide file tree
Showing 41 changed files with 203 additions and 76 deletions.
76 changes: 76 additions & 0 deletions checkerframework.astub
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* InvestBook
* Copyright (C) 2024 Spacious Team <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;

package java.util;
public class Objects {

@EnsuresNonNull("#1")
static <T> T requireNonNull(@Nullable T obj);

@EnsuresNonNull("#1")
static <T> T requireNonNull(@Nullable T obj, String message);

@EnsuresNonNull("#1")
static <T> T requireNonNull(@Nullable T obj, Supplier<String> messageSupplier);

@EnsuresNonNullIf(expression="#1", result=true)
static boolean nonNull(@Nullable Object obj);

@EnsuresNonNullIf(expression="#1", result=false)
static boolean isNull(@Nullable Object obj);
}


package org.springframework.util;
class StringUtils {

@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasText(@Nullable CharSequence str);

@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasText(@Nullable String str);

@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasLength(@Nullable CharSequence str);

@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasLength(@Nullable String str);
}


package org.springframework.util;
class CollectionUtils {

@EnsuresNonNullIf(expression="#1", result=false)
static boolean isEmpty(@Nullable Collection<?> collection);

@EnsuresNonNullIf(expression="#1", result=false)
static boolean isEmpty(@Nullable Map<?, ?> map);
}


package org.slf4j;
interface Logger {

void warn(String format, @Nullable Object arg1, @Nullable Object arg2);

void warn(String format, @Nullable Object... arguments);
}
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,10 @@
<!-- Checker framework inner file https://github.com/typetools/checker-framework/blob/master/checker/src/main/java/org/checkerframework/checker/nullness/permit-nullness-assertion-exception.astub -->
<!-- Append ${path.separator}collection-object-parameters-may-be-null.astub
for https://checkerframework.org/manual/#nullness-collection-arguments -->
<arg>-Astubs=permit-nullness-assertion-exception.astub</arg>
<arg>-Astubs=permit-nullness-assertion-exception.astub${path.separator}checkerframework.astub</arg>
<!-- TODO Remove suppressions, кроме:
methodref (Checker Framework не корректно выводит типы ссылок на методы) -->
<arg>-AsuppressWarnings=dereference.of.nullable,argument,methodref,type.arguments.not.inferred,lambda.param,expression.unparsable</arg>
<arg>-AsuppressWarnings=dereference.of.nullable,methodref,type.arguments.not.inferred,lambda.param,expression.unparsable</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public boolean generatedOnExecution() {
public boolean generatedOnExecution(Object entity, SharedSessionContractImplementor session) {
try {
EventType eventType = beforeExecutionGenerator.getEventTypes().iterator().next();
@SuppressWarnings("argument")
Object id = beforeExecutionGenerator.generate(session, entity, null, eventType);
return isNull(id);
} catch (Exception e) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/ru/investbook/openformat/v1_1_0/AccountPof.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@
@Slf4j
public class AccountPof {

@SuppressWarnings("type.argument")
private static final ThreadLocal<AtomicInteger> idGenerator = ThreadLocal.withInitial(AtomicInteger::new);
@SuppressWarnings("type.argument")
private static final ThreadLocal<Map<String, Integer>> accountNumberToIdMap = ThreadLocal.withInitial(HashMap::new);

@JsonProperty("id")
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ru/investbook/parser/InvestbookApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ private <T> boolean saveWithoutUpdate(T object, Consumer<T> persistFunction, Str
persistFunction.accept(object);
return true;
} catch (ConstraintViolationException e) { // jakarta.validation, not SQL constraint
log.warn("{} {}: {}", errorMsg, object, e.getMessage());
log.warn("{}, {}: {}", errorMsg, e.getMessage(), object);
return false;
} catch (Exception e) {
if (isUniqIndexViolationException(e)) {
Expand All @@ -219,7 +219,7 @@ private <T> Optional<T> saveWithoutUpdateAndGet(T object, Function<T, CreateResu
return Optional.of(result.object());
} catch (Exception e) {
// should not be thrown for duplicate
log.warn("{} {}: {}", errorMsg, object, e.getMessage());
log.warn("{}, {}: {}", errorMsg, e.getMessage(), object);
return Optional.empty();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ protected SecurityCodeAndIsinTable(BrokerReport report) {
codeToFaceValue.put(code, faceValue);
}

@Nullable String shortName = row.getStringCellValueOrDefault(SHORT_NAME, null);
String shortName = row.getStringCellValueOrDefault(SHORT_NAME, "");
if (hasLength(shortName)) {
shortNameToCode.put(shortName, code);
}
Expand All @@ -89,7 +89,7 @@ public String getIsin(String code, String shortName) {
initializeIfNeed();
@Nullable String isin = codeToIsin.get(code);
if (isin == null) {
@Nullable String codeFromName = shortNameToCode.get(shortName);
String codeFromName = shortNameToCode.getOrDefault(shortName, "");
isin = codeToIsin.get(codeFromName);
}
return requireNonNull(isin, "Не найден ISIN");
Expand All @@ -99,7 +99,7 @@ public SecurityType getSecurityType(String code, String shortName) {
initializeIfNeed();
@Nullable SecurityType type = codeToType.get(code);
if (type == null) {
@Nullable String codeFromName = shortNameToCode.get(shortName);
String codeFromName = shortNameToCode.getOrDefault(shortName, "");
type = codeToType.get(codeFromName);
}
return requireNonNull(type, "Не найден тип ценной бумаги");
Expand All @@ -109,7 +109,7 @@ public BigDecimal getFaceValue(String code, String shortName) {
initializeIfNeed();
@Nullable BigDecimal faceValue = codeToFaceValue.get(code);
if (faceValue == null) {
@Nullable String codeFromName = shortNameToCode.get(shortName);
String codeFromName = shortNameToCode.getOrDefault(shortName, "");
faceValue = codeToFaceValue.get(codeFromName);
}
return requireNonNull(faceValue, "Не найдена номинальная стоимость облигации");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.Objects.requireNonNull;
import static ru.investbook.parser.uralsib.PaymentsTable.PaymentsTableHeader.*;

@Slf4j
Expand Down Expand Up @@ -121,7 +122,8 @@ private Integer getClientCode(String account) {
Matcher matcher = clientCodePattern.matcher(account);
//noinspection ResultOfMethodCallIgnored
matcher.find();
return Integer.parseInt(matcher.group(1));
String value = requireNonNull(matcher.group(1));
return Integer.parseInt(value);
} catch (Exception e) {
throw new RuntimeException("Не могу найти код клиента для субсчета " + account);
}
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/ru/investbook/parser/uralsib/PaymentsTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

import static java.lang.Character.isLetterOrDigit;
import static java.lang.Double.parseDouble;
import static java.util.Objects.requireNonNull;
import static ru.investbook.parser.uralsib.PaymentsTable.PaymentsTableHeader.*;
import static ru.investbook.parser.uralsib.UralsibBrokerReport.convertToCurrency;

Expand Down Expand Up @@ -133,7 +134,7 @@ protected Security getSecurityIfCan(TableRow row) {
throw new RuntimeException("Не могу найти ISIN ценной бумаги в отчете брокера по событию:" + description);
}

private boolean contains(String description, String securityParameter) {
private boolean contains(String description, @Nullable String securityParameter) {
if (securityParameter == null) {
return false;
}
Expand All @@ -152,7 +153,8 @@ protected BigDecimal getTax(TableRow row) {
Matcher matcher = taxInformationPattern.matcher(description.toLowerCase());
if (matcher.find()) {
try {
return BigDecimal.valueOf(parseDouble(matcher.group(1)));
String value = requireNonNull(matcher.group(1));
return BigDecimal.valueOf(parseDouble(value));
} catch (Exception e) {
log.info("Не смогу выделить сумму налога из описания: {}", description);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ protected Collection<SecurityEventCashFlow> getRow(CashFlowEventTable.CashFlowEv
.intValueExact();
case AMORTIZATION -> value.divide(getAmortizationPerOneBond(lowercaseDescription), 2, RoundingMode.HALF_UP)
.intValueExact();
case REDEMPTION -> vtbSecurityDepositAndWithdrawalTable.getBondRedemptionCount(security.getIsin())
case REDEMPTION -> vtbSecurityDepositAndWithdrawalTable.getBondRedemptionCount(requireNonNull(security.getIsin()))
.orElseThrow(() -> new IllegalArgumentException("Не удалось определить количество погашенных облигаций " + security.getIsin()));
default -> throw new UnsupportedOperationException();
};
int securityId = getReport().getSecurityRegistrar().declareBondByIsin(security.getIsin(), security::toBuilder);
int securityId = getReport().getSecurityRegistrar().declareBondByIsin(requireNonNull(security.getIsin()), security::toBuilder);
Instant instant = event.getDate();
if (eventType != COUPON) {
// gh-510: чтобы отличать налог на купон, событие налога и купона сдвигаем по времени от амортизации (погашения)
Expand Down Expand Up @@ -132,15 +132,17 @@ private Security getSecurity(String description) {
private static BigDecimal getCouponPerOneBond(String description) {
Matcher matcher = couponPerOneBondPattern.matcher(description);
if (matcher.find()) {
return BigDecimal.valueOf(parseDouble(matcher.group(1)));
String value = requireNonNull(matcher.group(1));
return BigDecimal.valueOf(parseDouble(value));
}
throw new IllegalArgumentException("Не смогу выделить размер купона на одну облигацию из описания: " + description);
}

private static BigDecimal getAmortizationPerOneBond(String description) {
Matcher matcher = amortizationPerOneBondPattern.matcher(description);
if (matcher.find()) {
return BigDecimal.valueOf(parseDouble(matcher.group(1)));
String value = requireNonNull(matcher.group(1));
return BigDecimal.valueOf(parseDouble(value));
}
throw new IllegalArgumentException("Не смогу выделить размер купона на одну облигацию из описания: " + description);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.HashMap;
import java.util.Map;

import static java.util.Objects.requireNonNull;
import static ru.investbook.parser.vtb.VtbSecuritiesTable.VtbSecuritiesTableHeader.NAME_REGNUMBER_ISIN;
import static ru.investbook.parser.vtb.VtbSecuritiesTable.VtbSecuritiesTableHeader.SECTION;

Expand All @@ -53,7 +54,8 @@ protected VtbSecuritiesTable(SingleBrokerReport report) {
}
String description = row.getStringCellValue(NAME_REGNUMBER_ISIN);
Security security = VtbReportHelper.getSecurity(description);
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(security.getIsin(), security::toBuilder);
String isin = requireNonNull(security.getIsin());
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(isin, security::toBuilder);
security = security.toBuilder().id(securityId).build();
String registrationNumber = description.split(",")[1].toUpperCase().trim();
regNumberToSecurity.put(registrationNumber, security);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Optional;
import java.util.Set;

import static java.util.Objects.requireNonNull;
import static ru.investbook.parser.vtb.VtbSecurityFlowTable.VtbSecurityFlowTableHeader.*;

public class VtbSecurityDepositAndWithdrawalTable extends SingleAbstractReportTable<SecurityTransaction> {
Expand Down Expand Up @@ -69,8 +70,9 @@ protected VtbSecurityDepositAndWithdrawalTable(SingleBrokerReport report) {
String description = row.getStringCellValue(NAME_REGNUMBER_ISIN);
Security security = VtbReportHelper.getSecurity(description);
Instant timestamp = row.getInstantCellValue(DATE);
String tradeId = generateTradeId(portfolio, timestamp, security.getIsin());
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(security.getIsin(), security::toBuilder);
String isin = requireNonNull(security.getIsin());
String tradeId = generateTradeId(portfolio, timestamp, isin);
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(isin, security::toBuilder);

return SecurityTransaction.builder()
.tradeId(tradeId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.HashMap;
import java.util.Map;

import static java.util.Objects.requireNonNull;
import static ru.investbook.parser.vtb.VtbSecurityFlowTable.VtbSecurityFlowTableHeader.NAME_REGNUMBER_ISIN;

public class VtbSecurityFlowTable extends SingleAbstractReportTable<Security> {
Expand All @@ -46,7 +47,8 @@ protected VtbSecurityFlowTable(SingleBrokerReport report) {
protected Security parseRow(TableRow row) {
String description = row.getStringCellValue(NAME_REGNUMBER_ISIN);
Security security = VtbReportHelper.getSecurity(description);
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(security.getIsin(), security::toBuilder);
String isin = requireNonNull(security.getIsin());
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(isin, security::toBuilder);
security = security.toBuilder().id(securityId).build();
String registrationNumber = description.split(",")[1].toUpperCase().trim();
regNumberToSecurity.put(registrationNumber, security);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.HashSet;
import java.util.Set;

import static java.util.Objects.requireNonNull;
import static ru.investbook.parser.vtb.VtbBrokerReport.minValue;
import static ru.investbook.parser.vtb.VtbSecurityTransactionTable.VtbSecurityTransactionTableHeader.*;

Expand Down Expand Up @@ -68,7 +69,7 @@ protected SecurityTransaction parseRow(TableRow row) {

Security security = VtbReportHelper.getSecurity(row.getStringCellValue(NAME_AND_ISIN));
securities.add(security);
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(security.getIsin(), security::toBuilder);
int securityId = getReport().getSecurityRegistrar().declareStockOrBondByIsin(requireNonNull(security.getIsin()), security::toBuilder);

return SecurityTransaction.builder()
.timestamp(row.getInstantCellValue(DATE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.util.stream.Collectors;

import static java.util.Collections.singleton;
import static java.util.Objects.nonNull;
import static java.util.Objects.requireNonNull;

@Component
Expand All @@ -78,7 +79,8 @@ public DerivativeEvents getDerivativeEvents(Portfolio portfolio, Security contra
BigDecimal totalProfit = BigDecimal.ZERO;
int currentPosition = 0;
@Nullable LocalDate currentDay = firstEventDate;
while (currentDay != null && currentDay.compareTo(lastEventDate) <= 0) {
//noinspection ConstantValue
while (nonNull(currentDay) && nonNull(lastEventDate) && currentDay.compareTo(lastEventDate) <= 0) {
Deque<Transaction> dailyTransactions = getDailyTransactions(transactions, currentDay);
@Nullable SecurityEventCashFlow cash = securityEventCashFlows.get(currentDay);
//noinspection ConstantValue
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/ru/investbook/report/InternalRateOfReturn.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ public class InternalRateOfReturn {
* Возвращает внутреннюю норму доходности вложений. Не рассчитывается для срочных инструментов, т.к.
* вложение (гарантийное обеспечение) не хранится на данный момент в БД.
*
* @param quote may be null only if current security position is zero
* @return internal rate of return if can be calculated or null otherwise
* @param quote may be null, if current security position equals to 0. Otherwise, null result is returned
* @return internal rate of return, if it can be calculated, or null otherwise
*/
public @Nullable Double calc(
Collection<String> portfolios, Security security, SecurityQuote quote, Instant fromDate, Instant toDate) {
Collection<String> portfolios, Security security, @Nullable SecurityQuote quote, Instant fromDate, Instant toDate) {

try {
boolean isDerivative = (security.getType() == DERIVATIVE);
Expand Down Expand Up @@ -138,12 +138,12 @@ private org.decampo.xirr.Transaction castToXirrTransaction(SecurityEventCashFlow
toLocalDate(cashFlowEntity.getTimestamp()));
}

private Optional<org.decampo.xirr.Transaction> castToXirrTransaction(SecurityQuote quote,
private Optional<org.decampo.xirr.Transaction> castToXirrTransaction(@Nullable SecurityQuote quote,
String toCurrency, int positionCount,
SecurityType securityType) {
return ofNullable(quote)
.map(_quote -> _quote.getDirtyPriceInCurrency(securityType == DERIVATIVE))
.map(dirtyPrice -> convertToCurrency(dirtyPrice, quote.getCurrency(), toCurrency))
.map(dirtyPrice -> convertToCurrency(dirtyPrice, requireNonNull(quote.getCurrency()), toCurrency))
.map(dirtyPrice -> new org.decampo.xirr.Transaction(
positionCount * dirtyPrice.doubleValue(),
toLocalDate(quote.getTimestamp())));
Expand Down
Loading

0 comments on commit b619ea6

Please sign in to comment.