Giter VIP home page Giter VIP logo

checker-framework's Introduction

JSpecify

An artifact of well-specified annotations to power static analysis checks and JVM language interop. Developed by consensus of the partner organizations listed at our main web site, jspecify.org.

Our current focus is on annotations for nullness analysis.

Status

Version 0.3 is relatively safe to depend on in your code. Or you can read a more detailed answer.

Things to read

See jspecify.org/docs/start-here.

checker-framework's People

Contributors

charlesz-chen avatar cpovirk avatar csgordon avatar davidlazar avatar dbrosoft avatar dependabot-preview[bot] avatar dependabot[bot] avatar emspishak avatar gokaco avatar jonathanburke avatar jthaine avatar jwaataja avatar jyluo avatar kelloggm avatar konne88 avatar maxi17 avatar mernst avatar msridhar avatar notnoop avatar panacekcz avatar smillst avatar smonteiro avatar solleks avatar spernsteiner avatar stefanheule avatar stephdietzel avatar t-rasmud avatar wmdietl avatar wmdietlgc avatar xingweitian avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

netdpb

checker-framework's Issues

Upstreaming: Leaving wildcard bounds as unbounded

00cc056 (or at least that's the main code)

I no longer remember all the context for this one, and it probably would be wise for me to make sure that the change is even still necessary. (I suspect that it is, if only to avoid warnings for using <?> with a type parameter whose bound is "unspecified nullness." But if that's the only fallout from reverting this change, we could probably do so.)

Anyway, the basic idea seems to be to stop treating wildcards as if they have a bound that matches the corresponding type parameters'. I think this is part of CF's approach to wildcards (which they use instead of capture conversion). I think we get away without it because of our own handling of that, which is in jspecify/jspecify-reference-checker@15e9517#diff-ce82a59b06d0d82bfc6d06835d1b06ac15619bc3a71617d32189d041f02ca9c0R399 and possibly other places.

Upstreaming: Ignoring annotations on wildcards and type parameters themselves

(as opposed to on their bounds)

As the latter commit explains, I quite possibly could have done this in our TypeAnnotator if I'd been thinking. That way, we wouldn't need to modify CF.

That said, this change isn't too important, since we already report an error for such annotations. But if they appear in unchecked code or if users suppress the error, it would be nice for them to still have no effect.

Upstreaming: Not inheriting annotations, somehow avoiding stub-file recursion

f3e9f21

Note that that links to jspecify/jspecify-reference-checker@2bab27e, which describes another problem solved by that commit. It doesn't seem that "not inheriting annotations" is necessarily a sufficient fix for that problem in general, but it works here. More to the point, if we someday restore inheriting annotations, we'll still need a way to avoid the recursion. (The linked commit does discuss some other options.)

Upstreaming: Customize the suppress-warnings prefix that is included in error messages

28089b9

Obviously this is minor, and obviously it is sometimes nice to be able to suppress only a more fine-grained category. For the moment, though, I am erred on the side of making the output shorter and making it clear how to suppress. If we end up wanting to stick with that approach, we'd want to upstream.

There may be other ways around this: Maybe we'd plug in our own Messager that munges the default message.

(Note that it is not sufficient to define a single message key, nullness=%s, and then use it for all errors we report. That's because CF itself issues errors with its own keys.)

Upstreaming: Eliminate parameter contravariance

ff45ce7

As noted in that commit, we may end up wanting to support it after all.

If so, then we have a different task ahead of us: Figure out if CF's behavior for "the Ordering.min/max case" (discussed in the commit message) qualifies as a bug, and either make CF's logic accommodate our subtyping logic or make our subtyping logic work around what it needs to.

And actually, we might need to do one of those anyway: It might be possible to produce a new failure in our prototype checker by changing the code to compare E[] and F[] using a subtype check instead of an equality check. Presumably we'd do that by writing a sample that uses the return type instead of a parameter.

It may be that the CF difficulty is here:

https://github.com/typetools/checker-framework/blob/fd0abaa8b8fea775aaf71057d93d9415355b665e/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeMirror.java#L1387

CF calls createType, but it probably it is not "adapting the formal parameter types of N to the the type parameters of M." (It's probably also not applying defaulting rules -- a separate issue that may also be worth a look at some point.)

Upstreaming: Use greatestLowerBound in CFAbstractValue

c5f5118

The upstream code is essentially implementing GLB, anyway, only by using isSubtype.

(It turned out to be nice that I had had to migrate from MultiGraphQualifierHierarchy to ElementQualifierHierarchy: That had forced me to implement greatestLowerBound myself instead of inheriting an implementation that would likely have had the same problem as the CFAbstractValue code.)

But! CFAbstractValue has a concept of a "backup." Still, I'm hoping that we could preserve that by upstreaming a slightly less aggressive version of the above commit: We would still verify that a <: b or vice versa. But then, instead of inserting whichever one we detect to be the subtype first, we would still insert greatestLowerBound(a, b). That would be equivalent to the existing code for reasonable type systems, but it would still work for our unreasonable type system :)

Upstreaming: More extensive assumptions of determinism

ad7d132

Unless I got confused, both that and -AassumePure/-AassumeSideEffectFree are necessary in order to get the results I'm hoping for.

When we look to upstream this, we should try the obvious alternative to my blunt approach: Instead of hardcoding if (true), make sure to propagate the value of allowNonDeterministic (which we always set to true and I don't think any framework code calls) to recursive fromNode and fromTree calls. Perhaps CF would even consider it a bug that they don't do this at present -- but I'm unsure, since I haven't thought through all the implications of undoing our purity/side-effect-free assumption.

Upstreaming: BaseTypeValidator change

https://github.com/jspecify/checker-framework/blame/2eea6f8242391624def3818289abc44c1ec4ae0b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeValidator.java#L562

This ignores parts of the checks in visitParameterizedType and notes that the check seems weird.

Steps:

  • investigate whether the EISOP behavior makes sense or needs adjusting,
  • investigate what different behavior the jspecify-reference-checker needs,
  • address by either adjusting upstream in general or adding a new helper method to allow downstream adjustment.

Meta-issue: What hacks could we remove from our checker if we made additional changes upstream?

So far, I've opened issues only for changes that I've suspected we absolutely need to make to CF in order to make our checker work.

But there are plenty of places in which our checker could be cleaner (read: less hacky) if we made additional changes to CF. Just to pick the most recent example, I can't imagine that anyone would feel great about how I default type-variable usages only conditionally. Perhaps CF could have native support for this. [update: I backed out my hack because it was -- who could have guessed? :) -- buggy. And I have replaced it with another upstreaming proposal, #7. But the general point stands. To offer a new example, I present another fragile-looking hack.]

But some of our needs make little sense to 99% of CF checkers. So, as with many of the changes we've already made in this CF fork, we may find it hard to argue for supporting them upstream. Still, it would be nice to eventually look into the possibility of replacing hacks with CF changes: Hacks often break somewhere down the line.

Upstreaming: Promote cast.unsafe from a warning to an error

9ab109c

I assume that we don't really need to upstream this: The built-in CF nullness checker reports a full error for cases like casting from @Nullable Object to int. It might well always do this in cases that are actually unsafe (although then... why issue a warning?). (The built-in CF nullness checker also doesn't report an error, so perhaps it takes some action to short-circuit the cast.unsafe check.) Presumably we could do the same. But for now, I made cast.unsafe an error in our copy.

Upstreaming: Additional configuration for substitution

d1aba1c

CF already lets us override the TypeVariableSubstitutor, and we do so.

But our larger changes to substitution rules require changes to behavior even "before" substitution occurs. Notable, @NullnessUnspecified T (which is how we currently represent the type of a plain T when it appears in non-null-aware code) does not always have a nullness of "unspecified." That's because, if the type is instantiated with T set to a nullable type, the result must be @Nullable T. Therefore, it's not guaranteed safe to, e.g., dereference a value of type @NullnessUnspecified T, even in "lenient mode."

To upstream our current changes, we probably need to add methods to AnnotatedTypeFactory for the fixupBoundAnnotations methods in AnnotatedTypeMirror and for AsSuperVisitor to call.

Additionally, though, note that these changes do not make sense in isolation. They may invalidate assumptions in other parts of CF, so perhaps other code should be updated, too. (For example, is any of this related to jspecify/jspecify-reference-checker@89725d4#diff-ce82a59b06d0d82bfc6d06835d1b06ac15619bc3a71617d32189d041f02ca9c0R351? Or maybe that's caused by some other change I've made? Or maybe it will go away once we have dataflow implemented?) Or maybe the changes are just too weird to upstream without significantly more work, which we'd have to discuss.

Links:

Upstreaming: Defaulting for bounds of unbounded wildcards

c24904e

At first glance, this looks straightforward (though it should come with a test). However, note that we change the value of boundType: Previously, it would match the type parameter's bound type (UPPER or UNBOUNDED, as the case may be). But in our commit, it is always UNBOUNDED. This may change behavior of existing code.

One possibility is to track "wildcard-site unboundedness" as a separate bit, used only to trigger our new UNBOUNDED_WILDCARD_UPPER_BOUND, while leaving boundType untouched to preserve existing behavior.

Usage: jspecify/jspecify-reference-checker@94bf778#diff-ce82a59b06d0d82bfc6d06835d1b06ac15619bc3a71617d32189d041f02ca9c0R541

(The only way I found to set this default was to modify the Checker Framework itself. In particular, I wasn't able to employ an approach like I did in jspecify/jspecify-reference-checker@8e46bea#diff-ce82a59b06d0d82bfc6d06835d1b06ac15619bc3a71617d32189d041f02ca9c0R288: IIUC, that code jumps between usages and declarations, so it can't track whether the wildcard itself appears in null-aware or non-null-aware code. Thus, it can't apply different defaults for the two cases.)

Rebase onto eisop

That should pick up at least a couple improvements:

  • better support for T extends @Nullable Object
  • an easier way to support package-level annotations that don't affect subpackages

I may be forgetting others.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.