net.sourceforge.pmd.lang.java.ast.JModifier Maven / Gradle / Ivy
The newest version!
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol;
/**
* A Java modifier. The ordering of constants respects the ordering
* recommended by the JLS.
*/
// Note: the class is named JModifier and not Modifier to avoid conflict
// with java.lang.reflect.Modifier
public enum JModifier {
// for anything
PUBLIC(Modifier.PUBLIC),
PROTECTED(Modifier.PROTECTED),
PRIVATE(Modifier.PRIVATE),
/** Modifier {@code "sealed"} (preview feature of JDK 15). */
SEALED(0),
/** Modifier {@code "non-sealed"} (preview feature of JDK 15). */
NON_SEALED("non-sealed", 0),
ABSTRACT(Modifier.ABSTRACT),
STATIC(Modifier.STATIC),
FINAL(Modifier.FINAL),
// for methods
SYNCHRONIZED(Modifier.SYNCHRONIZED),
NATIVE(Modifier.NATIVE),
DEFAULT(0),
// not for fields
STRICTFP(Modifier.STRICT),
// for fields
TRANSIENT(Modifier.TRANSIENT),
VOLATILE(Modifier.VOLATILE);
private final String token;
private final int reflect;
JModifier(int reflect) {
this.token = name().toLowerCase(Locale.ROOT);
this.reflect = reflect;
}
JModifier(String token, int reflect) {
this.token = token;
this.reflect = reflect;
}
/**
* Returns the constant of java.lang.reflect.Modifier that this
* modifier corresponds to. Be aware that the following constants
* are source-level modifiers only, for which this method returns 0:
*
* - {@link #DEFAULT}: this doesn't exist at the class file level.
* A default method is a non-static non-abstract public method declared
* in an interface ({@link JMethodSymbol#isDefaultMethod()}.
*
- {@link #SEALED}: a sealed class has an attribute {@code PermittedSubclasses}
* with a non-zero length (in the compiled class file)
*
- {@link #NON_SEALED}: this doesn't exist at the class file level at all.
* But a class must have the non-sealed modifier in source if it
* is neither sealed, nor final, and appears in the {@code PermittedSubclasses}
* attribute of some direct supertype.
*
*/
public int getReflectMod() {
return reflect;
}
/**
* Returns how the modifier is written in source.
*/
public String getToken() {
return token;
}
@Override
public String toString() {
return getToken();
}
public static int toReflect(Collection mods) {
int res = 0;
for (JModifier mod : mods) {
res |= mod.getReflectMod();
}
return res;
}
/**
* Gets a modifier from its name.
*
* @throws IllegalArgumentException if the name is incorrect
*/
public static @NonNull JModifier fromToken(@NonNull String token) {
return valueOf(token.toLowerCase(Locale.ROOT));
}
}