use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class AnnotationFileParser method fakeOverriddenMethod.
/**
* Given a method declaration that does not correspond to an element, returns the method it
* directly overrides or implements. As Java does, this prefers a method in a superclass to one in
* an interface.
*
* <p>As with regular overrides, the parameter types must be exact matches; contravariance is not
* permitted.
*
* @param typeElt the type in which the method appears
* @param methodDecl the method declaration that does not correspond to an element
* @return the methods that the given method declaration would override, or null if none
*/
@Nullable
private ExecutableElement fakeOverriddenMethod(TypeElement typeElt, MethodDeclaration methodDecl) {
for (Element elt : typeElt.getEnclosedElements()) {
if (elt.getKind() != ElementKind.METHOD) {
continue;
}
ExecutableElement candidate = (ExecutableElement) elt;
if (!candidate.getSimpleName().contentEquals(methodDecl.getName().getIdentifier())) {
continue;
}
List<? extends VariableElement> candidateParams = candidate.getParameters();
if (sameTypes(candidateParams, methodDecl.getParameters())) {
return candidate;
}
}
TypeElement superType = ElementUtils.getSuperClass(typeElt);
if (superType != null) {
ExecutableElement result = fakeOverriddenMethod(superType, methodDecl);
if (result != null) {
return result;
}
}
for (TypeMirror interfaceTypeMirror : typeElt.getInterfaces()) {
TypeElement interfaceElement = (TypeElement) ((DeclaredType) interfaceTypeMirror).asElement();
ExecutableElement result = fakeOverriddenMethod(interfaceElement, methodDecl);
if (result != null) {
return result;
}
}
return null;
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class AnnotationFileParser method findElement.
/**
* Looks for a constructor element in the typeElt and returns it if the element has the same
* signature as provided constructor declaration. In case constructor element is not found it
* returns null.
*
* @param typeElt type element where constructor element should be looked for
* @param constructorDecl constructor declaration with signature that should be found among
* constructors in the typeElt
* @return constructor element in typeElt with the same signature as the provided constructor
* declaration or null if constructor element is not found
*/
@Nullable
private ExecutableElement findElement(TypeElement typeElt, ConstructorDeclaration constructorDecl) {
if (skipNode(constructorDecl)) {
return null;
}
final int wantedMethodParams = (constructorDecl.getParameters() == null) ? 0 : constructorDecl.getParameters().size();
final String wantedMethodString = AnnotationFileUtil.toString(constructorDecl);
for (ExecutableElement method : ElementFilter.constructorsIn(typeElt.getEnclosedElements())) {
if (wantedMethodParams == method.getParameters().size() && ElementUtils.getSimpleSignature(method).equals(wantedMethodString)) {
return method;
}
}
stubWarnNotFound(constructorDecl, "Constructor " + wantedMethodString + " not found in type " + typeElt);
if (debugAnnotationFileParser) {
for (ExecutableElement method : ElementFilter.constructorsIn(typeElt.getEnclosedElements())) {
stubDebug(String.format(" %s", method));
}
}
return null;
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class SourceChecker method initChecker.
/**
* Initialize the checker.
*
* @see AbstractProcessor#init(ProcessingEnvironment)
*/
public void initChecker() {
// Grab the Trees and Messager instances now; other utilities
// (like Types and Elements) can be retrieved by subclasses.
@Nullable Trees trees = Trees.instance(processingEnv);
assert trees != null;
this.trees = trees;
this.messager = processingEnv.getMessager();
this.messagesProperties = getMessagesProperties();
this.visitor = createSourceVisitor();
// Validate the lint flags, if they haven't been used already.
if (this.activeLints == null) {
this.activeLints = createActiveLints(getOptions());
}
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class AnnotationFileElementTypes method getFakeOverride.
/**
* Returns the method type of the most specific fake override for the given element, when used as
* a member of the given type.
*
* @param elt element for which annotations are returned
* @param receiverType the type of the class that contains member (or a subtype of it)
* @return the most specific AnnotatedTypeMirror for {@code elt} that is a fake override, or null
* if there are no fake overrides
*/
@Nullable
public AnnotatedExecutableType getFakeOverride(Element elt, AnnotatedTypeMirror receiverType) {
if (parsing) {
throw new BugInCF("parsing while calling getFakeOverride");
}
if (elt.getKind() != ElementKind.METHOD) {
return null;
}
ExecutableElement method = (ExecutableElement) elt;
// This is a list of pairs of (where defined, method type) for fake overrides. The second
// element of each pair is currently always an AnnotatedExecutableType.
List<Pair<TypeMirror, AnnotatedTypeMirror>> candidates = annotationFileAnnos.fakeOverrides.get(method);
if (candidates == null || candidates.isEmpty()) {
return null;
}
TypeMirror receiverTypeMirror = receiverType.getUnderlyingType();
// A list of fake receiver types.
List<TypeMirror> applicableClasses = new ArrayList<>();
List<TypeMirror> applicableInterfaces = new ArrayList<>();
for (Pair<TypeMirror, AnnotatedTypeMirror> candidatePair : candidates) {
TypeMirror fakeLocation = candidatePair.first;
AnnotatedExecutableType candidate = (AnnotatedExecutableType) candidatePair.second;
if (factory.types.isSameType(receiverTypeMirror, fakeLocation)) {
return candidate;
} else if (factory.types.isSubtype(receiverTypeMirror, fakeLocation)) {
TypeElement fakeElement = TypesUtils.getTypeElement(fakeLocation);
switch(fakeElement.getKind()) {
case CLASS:
case ENUM:
applicableClasses.add(fakeLocation);
break;
case INTERFACE:
case ANNOTATION_TYPE:
applicableInterfaces.add(fakeLocation);
break;
default:
throw new BugInCF("What type? %s %s %s", fakeElement.getKind(), fakeElement.getClass(), fakeElement);
}
}
}
if (applicableClasses.isEmpty() && applicableInterfaces.isEmpty()) {
return null;
}
TypeMirror fakeReceiverType = TypesUtils.mostSpecific(!applicableClasses.isEmpty() ? applicableClasses : applicableInterfaces, factory.getProcessingEnv());
if (fakeReceiverType == null) {
StringJoiner message = new StringJoiner(System.lineSeparator());
message.add(String.format("No most specific fake override found for %s with receiver %s." + " These fake overrides are applicable:", elt, receiverTypeMirror));
for (TypeMirror candidate : applicableClasses) {
message.add(" class candidate: " + candidate);
}
for (TypeMirror candidate : applicableInterfaces) {
message.add(" interface candidate: " + candidate);
}
throw new BugInCF(message.toString());
}
for (Pair<TypeMirror, AnnotatedTypeMirror> candidatePair : candidates) {
TypeMirror candidateReceiverType = candidatePair.first;
if (factory.types.isSameType(fakeReceiverType, candidateReceiverType)) {
return (AnnotatedExecutableType) candidatePair.second;
}
}
throw new BugInCF("No match for %s in %s %s %s", fakeReceiverType, candidates, applicableClasses, applicableInterfaces);
}
use of org.checkerframework.checker.nullness.qual.Nullable in project SpongeCommon by SpongePowered.
the class SpongeBlockSnapshot method restore.
@Override
public boolean restore(final boolean force, final BlockChangeFlag flag) {
// TODO - rewrite with the PhaseTracker being the hook or use SpongeImplHooks to do the restore.
final Optional<ServerLevel> optionalWorld = Optional.ofNullable(this.world.get());
if (!optionalWorld.isPresent()) {
return false;
}
final ServerLevel world = optionalWorld.get();
// this way we guarantee an exit.
try (final PhaseContext<?> context = BlockPhase.State.RESTORING_BLOCKS.createPhaseContext(PhaseTracker.SERVER)) {
context.buildAndSwitch();
final BlockPos pos = VecHelper.toBlockPos(this.pos);
if (!net.minecraft.world.level.Level.isInWorldBounds(pos)) {
// Invalid position. Inline this check
return false;
}
final net.minecraft.world.level.block.state.BlockState current = world.getBlockState(pos);
final net.minecraft.world.level.block.state.BlockState replaced = (net.minecraft.world.level.block.state.BlockState) this.blockState;
if (!force && (current.getBlock() != replaced.getBlock() || current != replaced)) {
return false;
}
// being created during block change removals
if (!current.is(((net.minecraft.world.level.block.state.BlockState) this.blockState).getBlock())) {
world.removeBlockEntity(pos);
}
world.setBlock(pos, replaced, BlockChangeFlagManager.andNotifyClients(flag).getRawFlag());
if (this.compound != null) {
@Nullable BlockEntity te = world.getBlockEntity(pos);
if (te != null) {
te.load((net.minecraft.world.level.block.state.BlockState) this.blockState, this.compound);
} else {
// In cases like this, we need to directly just say "fuck it" and deserialize from the compound directly.
try {
te = BlockEntity.loadStatic((net.minecraft.world.level.block.state.BlockState) this.blockState, this.compound);
if (te != null) {
world.getChunk(pos).setBlockEntity(pos, te);
}
} catch (final Exception e) {
// Seriously? The mod should be broken then.
final PrettyPrinter printer = new PrettyPrinter(60).add("Unable to restore").centre().hr().add("A mod is not correctly deserializing a TileEntity that is being restored. ").addWrapped(60, "Note that this is not the fault of Sponge. Sponge is understanding that " + "a block is supposed to have a TileEntity, but the mod is breaking the contract" + "on how to re-create the tile entity. Please open an issue with the offending mod.").add("Here's the provided compound:");
printer.add();
try {
printer.addWrapped(80, "%s : %s", "This compound", this.compound);
} catch (final Throwable error) {
printer.addWrapped(80, "Unable to get the string of this compound. Printing out some of the entries to better assist");
}
printer.add().add("Desired World: " + this.worldKey).add("Position: " + this.pos).add("Desired BlockState: " + this.blockState);
printer.add();
printer.log(SpongeCommon.logger(), Level.ERROR);
// I mean, I guess. the block was set up, but not the tile entity.
return true;
}
}
if (te != null) {
te.setChanged();
}
}
// Finally, mark the location as being updated.
world.getChunkSource().blockChanged(pos);
return true;
}
}
Aggregations