0

私は自分のプログラムに注釈を付け始め、nullness 注釈を書き始めました。ガイドラインに従って、クラスの 1 つに注釈を付け、 としてマークしました@AnnotatedFor({"nullness"})。このプログラムは、Oracle JDK 1.7.u21 を使用して Java 7 プラットフォームでコンパイルされています (技術的な制限により、JDK 8 に切り替えることはできません)。このクラスは、ナノ化されていないサードパーティ (Google Guava) および JDK ライブラリ メソッドの束を使用するため、次のように Maven コンパイラ プラグイン引数に-AskipUses=...とともにオプションを含めます。-AuseSafeDefaultsForUnnanotatedSourceCode

<properties>
    <project.checker.annotatedJdk>${org.checkerframework:jdk7:jar}</project.checker.annotatedJdk>
    <project.checker.typeAnnotationsJavac>${org.checkerframework:compiler:jar}</project.checker.typeAnnotationsJavac>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.8</version>
            <executions>
                <execution>
                    <goals>
                        <goal>properties</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <fork>true</fork>
                <annotationProcessors>
                    <annotationProcessor>org.checkerframework.checker.nullness.NullnessChecker</annotationProcessor>
                </annotationProcessors>
                <compilerArgs>
                    <arg>-Xbootclasspath/p:${project.checker.annotatedJdk}</arg>
                    <arg>-J-Xbootclasspath/p:${project.checker.typeAnnotationsJavac}</arg>
                    <arg>-AuseSafeDefaultsForUnannotatedSourceCode</arg>
                    <arg>-AskipUses=com\.google\.common\.|java\.math</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

クラスのソースコード:

package pkg;

import java.util.*;
import java.math.BigDecimal;
import com.google.common.base.*;
import com.google.common.collect.Ordering;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.AnnotatedFor;

@AnnotatedFor({"nullness"})
public class Indicator implements Comparable<Indicator> {

    private static final BigDecimal DEFAULT_SORT_ORDER;
    private static final Ordering<Indicator> ORDERING;

    public static enum IndicatorComparator implements Comparator<Indicator> {

        INSTANCE;

        @Override
        public final int compare(Indicator left, Indicator right) {

            /* nulls-last */
            if (left.sortOrder != null && right.sortOrder != null) {
                return left.sortOrder.compareTo(right.sortOrder);
            } else if (left.sortOrder != null && right.sortOrder == null) {
                return -1;
            } else if (left.sortOrder == null && right.sortOrder != null) {
                return 1;
            } else {
                return 0;
            }

        }
    }

    static {
        DEFAULT_SORT_ORDER = BigDecimal.valueOf(0.0);
        ORDERING = Ordering.from(IndicatorComparator.INSTANCE).nullsLast();
    }

    private final int id;
    private @Nullable String code;
    private @Nullable BigDecimal sortOrder;
    private boolean isGroup;

    private Indicator(Builder builder) {
        id = builder.id;
        code = builder.code;
        sortOrder = builder.sortOrder;
        isGroup = builder.isGroup;
    }

    /* equals and hashcode are not overriden by purpose -- the default version will do */
    @Override
    public int compareTo(final Indicator other) {
        return ORDERING.compare(this, other);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("id", id)
                .add("code", code)
                .add("sortOrder", sortOrder)
                .add("isGroup", isGroup)
                .toString();
    }

    public int getId() {
        return id;
    }

    public Optional<String> getCode() {
        return Optional.fromNullable(code);
    }

    public Optional<BigDecimal> getSortOrder() {
        return Optional.fromNullable(sortOrder);
    }

    public boolean isGroup() {
        return isGroup;
    }

    public void setCode(@Nullable String code) {
        this.code = code;
    }

    public void setSortOrder(@Nullable BigDecimal sortOrder) {
        this.sortOrder = sortOrder;
    }

    public void setGroup(boolean group) {
        this.isGroup = group;
    }

    public static class Builder {

        private int id;
        private @Nullable String code;
        private @Nullable BigDecimal sortOrder;
        private boolean isGroup;

        public Builder() {
            sortOrder = DEFAULT_SORT_ORDER;
        }

        public Builder id(int id) {
            this.id = id;
            return this;
        }

        public Builder code(@Nullable String code) {
            this.code = code;
            return this;
        }

        public Builder sortOrder(@Nullable BigDecimal sortOrder) {
            this.sortOrder = sortOrder;
            return this;
        }

        public Builder isGroup(boolean isGroup) {
            this.isGroup = isGroup;
            return this;
        }

        public Indicator build() {
            return new Indicator(this);
        }
    }
}

プロジェクトをビルドすると、次のようなエラーが発生するため、チェッカーは「スキップ」オプションを無視しているようです

COMPILATION ERROR : 
-------------------------------------------------------------
pkg/Indicator.java:[38,48] error:     [argument.type.incompatible] incompatible types in argument.
found   : @UnknownKeyFor double

required: @KeyForBottom double

38 行目に進みます。

DEFAULT_SORT_ORDER = BigDecimal.valueOf(0.0);

または 39:

pkg/Indicator.java:[39,52] error:     [argument.type.incompatible] incompatible types in argument.
found   : IndicatorComparator

required: Comparator<Indicator>

または 38 再び:

pkg/Indicator.java:[38,47] error:     [assignment.type.incompatible] incompatible types in assignment.
found   : @UnknownInitialization @Nullable BigDecimal

required: @Initialized @NonNull BigDecimal

-AskipUses=などなど・・・オプションを使って解消したつもりだったのですが、色々なチェッカーエラーでログがオーバーフローしてしまいました。

私は何か間違ったことをしていますか?

UPD 07.12.2015: クラスの完全なソース コードを添付しました。UPD 14.12.2015: ソース コードが更新されたため、ケースの再現がはるかに簡単になりました。

4

0 に答える 0