org.eclipse.jdt.internal.compiler.impl.IrritantSet.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jdt.internal.compiler.impl.IrritantSet.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contributions for
 *                          bug 349326 - [1.7] new warning for missing try-with-resources
 *                        bug 186342 - [compiler][null] Using annotations for null checking
 *                        bug 370639 - [compiler][resource] restore the default for resource leak warnings
 *                        bug 265744 - Enum switch should warn about missing default
 *                        bug 374605 - Unreasonable warning for enum-based switch statements
 *                        bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
 *                        Bug 441208 - [1.8][null]SuppressWarnings("null") does not suppress / marked Unnecessary
 *                        Bug 410218 - Optional warning for arguments of "unexpected" types to Map#get(Object), Collection#remove(Object) et al.
 *******************************************************************************/

package org.eclipse.jdt.internal.compiler.impl;

import org.eclipse.jdt.internal.compiler.ast.ASTNode;

/**
 * Represent a set of irritant flags. Irritants are organized in up to 8 group
 * of 29, allowing for a maximum of 232 distinct irritants.
 */
public class IrritantSet {

    // Reserve two high bits for selecting the right bit pattern
    public final static int GROUP_MASK = ASTNode.Bit32 | ASTNode.Bit31 | ASTNode.Bit30;
    public final static int GROUP_SHIFT = 29;
    public final static int GROUP_MAX = 3; // can be increased up to 8

    // Group prefix for irritants
    public final static int GROUP0 = 0 << GROUP_SHIFT;
    public final static int GROUP1 = 1 << GROUP_SHIFT;
    public final static int GROUP2 = 2 << GROUP_SHIFT;
    // reveal subsequent groups as needed
    // public final static int GROUP3 = 3 << GROUP_SHIFT;
    // public final static int GROUP4 = 4 << GROUP_SHIFT;
    // public final static int GROUP5 = 5 << GROUP_SHIFT;
    // public final static int GROUP6 = 6 << GROUP_SHIFT;
    // public final static int GROUP7 = 7 << GROUP_SHIFT;

    // Predefine sets of irritants matching warning tokens
    public static final IrritantSet ALL = new IrritantSet(0xFFFFFFFF & ~GROUP_MASK);
    public static final IrritantSet BOXING = new IrritantSet(CompilerOptions.AutoBoxing);
    public static final IrritantSet CAST = new IrritantSet(CompilerOptions.UnnecessaryTypeCheck);
    public static final IrritantSet DEPRECATION = new IrritantSet(CompilerOptions.UsingDeprecatedAPI);
    public static final IrritantSet TERMINAL_DEPRECATION = new IrritantSet(
            CompilerOptions.UsingTerminallyDeprecatedAPI);
    public static final IrritantSet DEP_ANN = new IrritantSet(CompilerOptions.MissingDeprecatedAnnotation);
    public static final IrritantSet FALLTHROUGH = new IrritantSet(CompilerOptions.FallthroughCase);
    public static final IrritantSet FINALLY = new IrritantSet(CompilerOptions.FinallyBlockNotCompleting);
    public static final IrritantSet HIDING = new IrritantSet(CompilerOptions.MaskedCatchBlock);
    public static final IrritantSet INCOMPLETE_SWITCH = new IrritantSet(CompilerOptions.MissingEnumConstantCase);
    public static final IrritantSet NLS = new IrritantSet(CompilerOptions.NonExternalizedString);
    public static final IrritantSet NULL = new IrritantSet(CompilerOptions.NullReference);
    public static final IrritantSet RAW = new IrritantSet(CompilerOptions.RawTypeReference);
    public static final IrritantSet RESTRICTION = new IrritantSet(CompilerOptions.ForbiddenReference);
    public static final IrritantSet SERIAL = new IrritantSet(CompilerOptions.MissingSerialVersion);
    public static final IrritantSet STATIC_ACCESS = new IrritantSet(CompilerOptions.IndirectStaticAccess);
    public static final IrritantSet STATIC_METHOD = new IrritantSet(CompilerOptions.MethodCanBeStatic);
    public static final IrritantSet SYNTHETIC_ACCESS = new IrritantSet(CompilerOptions.AccessEmulation);
    public static final IrritantSet SYNCHRONIZED = new IrritantSet(
            CompilerOptions.MissingSynchronizedModifierInInheritedMethod);
    public static final IrritantSet SUPER = new IrritantSet(CompilerOptions.OverridingMethodWithoutSuperInvocation);
    public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
    public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
    public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(
            CompilerOptions.UnqualifiedFieldAccess);
    public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable);
    public static final IrritantSet UNLIKELY_ARGUMENT_TYPE = new IrritantSet(
            CompilerOptions.UnlikelyCollectionMethodArgumentType);
    public static final IrritantSet API_LEAK = new IrritantSet(CompilerOptions.APILeak);
    public static final IrritantSet MODULE = new IrritantSet(CompilerOptions.UnstableAutoModuleName);

    public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
    public static final IrritantSet PREVIEW = new IrritantSet(CompilerOptions.PreviewFeatureUsed);
    public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default   
    public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below
    public static final IrritantSet COMPILER_DEFAULT_INFOS = new IrritantSet(0); // see static initializer below
    static {
        COMPILER_DEFAULT_INFOS
                // group-2 infos enabled by default
                .set(CompilerOptions.UnlikelyEqualsArgumentType | CompilerOptions.SuppressWarningsNotAnalysed);

        COMPILER_DEFAULT_WARNINGS
                // group-0 warnings enabled by default
                .set(CompilerOptions.MethodWithConstructorName | CompilerOptions.OverriddenPackageDefaultMethod
                        | CompilerOptions.UsingDeprecatedAPI | CompilerOptions.MaskedCatchBlock
                        | CompilerOptions.UnusedLocalVariable | CompilerOptions.NoImplicitStringConversion
                        | CompilerOptions.AssertUsedAsAnIdentifier | CompilerOptions.UnusedImport
                        | CompilerOptions.NonStaticAccessToStatic | CompilerOptions.NoEffectAssignment
                        | CompilerOptions.IncompatibleNonInheritedInterfaceMethod
                        | CompilerOptions.UnusedPrivateMember | CompilerOptions.FinallyBlockNotCompleting)
                // group-1 warnings enabled by default
                .set(CompilerOptions.UncheckedTypeOperation | CompilerOptions.FinalParameterBound
                        | CompilerOptions.MissingSerialVersion | CompilerOptions.EnumUsedAsAnIdentifier
                        | CompilerOptions.ForbiddenReference | CompilerOptions.VarargsArgumentNeedCast
                        | CompilerOptions.NullReference | CompilerOptions.AnnotationSuperInterface
                        | CompilerOptions.TypeHiding | CompilerOptions.DiscouragedReference
                        | CompilerOptions.UnhandledWarningToken | CompilerOptions.RawTypeReference
                        | CompilerOptions.UnusedLabel | CompilerOptions.UnusedTypeArguments
                        | CompilerOptions.UnusedWarningToken | CompilerOptions.ComparingIdentical
                        | CompilerOptions.MissingEnumConstantCase)
                // group-2 warnings enabled by default
                .set(CompilerOptions.DeadCode | CompilerOptions.Tasks | CompilerOptions.UnclosedCloseable
                        | CompilerOptions.NullUncheckedConversion | CompilerOptions.RedundantNullAnnotation
                        | CompilerOptions.NonnullParameterAnnotationDropped
                        | CompilerOptions.PessimisticNullAnalysisForFreeTypeVariables
                        | CompilerOptions.NonNullTypeVariableFromLegacyInvocation
                        | CompilerOptions.UnlikelyCollectionMethodArgumentType
                        | CompilerOptions.UsingTerminallyDeprecatedAPI | CompilerOptions.APILeak
                        | CompilerOptions.UnstableAutoModuleName | CompilerOptions.PreviewFeatureUsed);
        // default errors IF AnnotationBasedNullAnalysis is enabled:
        COMPILER_DEFAULT_ERRORS
                .set(CompilerOptions.NullSpecViolation | CompilerOptions.NullAnnotationInferenceConflict);

        ALL.setAll();
        HIDING.set(CompilerOptions.FieldHiding).set(CompilerOptions.LocalVariableHiding)
                .set(CompilerOptions.TypeHiding);
        NULL.set(CompilerOptions.PotentialNullReference).set(CompilerOptions.RedundantNullCheck)
                .set(CompilerOptions.NullSpecViolation).set(CompilerOptions.NullAnnotationInferenceConflict)
                .set(CompilerOptions.NullUncheckedConversion).set(CompilerOptions.RedundantNullAnnotation)
                .set(CompilerOptions.NonnullParameterAnnotationDropped)
                .set(CompilerOptions.MissingNonNullByDefaultAnnotation)
                .set(CompilerOptions.PessimisticNullAnalysisForFreeTypeVariables)
                .set(CompilerOptions.NonNullTypeVariableFromLegacyInvocation);

        RESTRICTION.set(CompilerOptions.DiscouragedReference);
        STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
        UNUSED.set(CompilerOptions.UnusedArgument).set(CompilerOptions.UnusedExceptionParameter)
                .set(CompilerOptions.UnusedPrivateMember).set(CompilerOptions.UnusedDeclaredThrownException)
                .set(CompilerOptions.UnusedLabel).set(CompilerOptions.UnusedImport)
                .set(CompilerOptions.UnusedTypeArguments).set(CompilerOptions.RedundantSuperinterface)
                .set(CompilerOptions.DeadCode).set(CompilerOptions.UnusedObjectAllocation)
                .set(CompilerOptions.UnusedTypeParameter)
                .set(CompilerOptions.RedundantSpecificationOfTypeArguments);
        STATIC_METHOD.set(CompilerOptions.MethodCanBePotentiallyStatic);
        RESOURCE.set(CompilerOptions.PotentiallyUnclosedCloseable)
                .set(CompilerOptions.ExplicitlyClosedAutoCloseable);
        INCOMPLETE_SWITCH.set(CompilerOptions.MissingDefaultCase);
        String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
        if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$
            UNCHECKED.set(CompilerOptions.RawTypeReference);
        }

        JAVADOC.set(CompilerOptions.MissingJavadocComments).set(CompilerOptions.MissingJavadocTags);

        UNLIKELY_ARGUMENT_TYPE.set(CompilerOptions.UnlikelyEqualsArgumentType);
    }
    // Internal state

    private int[] bits = new int[GROUP_MAX];

    /**
     * Constructor with initial irritant set
     */
    public IrritantSet(int singleGroupIrritants) {
        initialize(singleGroupIrritants);
    }

    /**
     * Constructor with initial irritant set
     */
    public IrritantSet(IrritantSet other) {
        initialize(other);
    }

    public boolean areAllSet() {
        for (int i = 0; i < GROUP_MAX; i++) {
            if (this.bits[i] != (0xFFFFFFFF & ~GROUP_MASK))
                return false;
        }
        return true;
    }

    public IrritantSet clear(int singleGroupIrritants) {
        int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
        this.bits[group] &= ~singleGroupIrritants;
        return this;
    }

    public IrritantSet clearAll() {
        for (int i = 0; i < GROUP_MAX; i++) {
            this.bits[i] = 0;
        }
        return this;
    }

    /**
     * Initialize a set of irritants in one group
     * 
     * @param singleGroupIrritants
     */
    public void initialize(int singleGroupIrritants) {
        if (singleGroupIrritants == 0)
            return;
        int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
        this.bits[group] = singleGroupIrritants & ~GROUP_MASK; // erase group information
    }

    public void initialize(IrritantSet other) {
        if (other == null)
            return;
        System.arraycopy(other.bits, 0, this.bits = new int[GROUP_MAX], 0, GROUP_MAX);
    }

    /**
     * Returns true if any of the irritants in given other set is positionned in receiver
     * @param other
     */
    public boolean isAnySet(IrritantSet other) {
        if (other == null)
            return false;
        for (int i = 0; i < GROUP_MAX; i++) {
            if ((this.bits[i] & other.bits[i]) != 0)
                return true;
        }
        return false;
    }

    /**
     * Returns true if all of the irritants in the given irritant set are set in receiver
     * @param irritantSet the given irritant set
     */
    public boolean hasSameIrritants(IrritantSet irritantSet) {
        if (irritantSet == null)
            return false;
        for (int i = 0; i < GROUP_MAX; i++) {
            if (this.bits[i] != irritantSet.bits[i])
                return false;
        }
        return true;
    }

    public boolean isSet(int singleGroupIrritants) {
        int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
        return (this.bits[group] & singleGroupIrritants) != 0;
    }

    public int[] getBits() {
        return this.bits;
    }

    public IrritantSet set(int singleGroupIrritants) {
        int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
        this.bits[group] |= (singleGroupIrritants & ~GROUP_MASK); // erase the group bits
        return this;
    }

    /**
     * Return updated irritantSet or null if it was a no-op
     * 
     * @param other
     */
    public IrritantSet set(IrritantSet other) {
        if (other == null)
            return this;
        boolean wasNoOp = true;
        for (int i = 0; i < GROUP_MAX; i++) {
            int otherIrritant = other.bits[i] & ~GROUP_MASK; // erase the
            // group
            // bits
            if ((this.bits[i] & otherIrritant) != otherIrritant) {
                wasNoOp = false;
                this.bits[i] |= otherIrritant;
            }
        }
        return wasNoOp ? null : this;
    }

    public IrritantSet setAll() {
        for (int i = 0; i < GROUP_MAX; i++) {
            this.bits[i] |= 0xFFFFFFFF & ~GROUP_MASK; // erase the group
            // bits;
        }
        return this;
    }
}