typetools / checker-framework

Pluggable type-checking for Java
http://checkerframework.org/
Other
1.01k stars 352 forks source link

Lambda, anonymous inner classes and named inner class not treated the same #4579

Open jpschewe opened 3 years ago

jpschewe commented 3 years ago

I'm using checker framework 3.12.0 with OpenJDK 11.

openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment (build 11.0.10+9-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.10+9-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

I would expect ananonymous inner class and a named inner class to be treated the same by the initialization checker, however I'm finding that isn't the case. I would also expect a lambda to be treated the same way. In the below code I have added an ActionListener each of 3 ways: lambda, named inner class, anonymous inner class. Why are these not all treated the same?

package net.mtu.eggplant.checker;

import org.checkerframework.checker.initialization.qual.UnderInitialization;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.JButton;

public class LambdaInitialization {

  public LambdaInitialization() {
    final JButton button = new JButton();

    // this reports a warning about under initialization
    button.addActionListener(l -> doAction());

    // this reports no warnings
    button.addActionListener(new ListenerClass());

    // this reports a warning about under initialization
    button.addActionListener(new ActionListener() {
      public void actionPerformed(final ActionEvent e) {
        doAction();
      }
    });
  }

  private void doAction() {
    System.out.println("Action");
  }

  private class ListenerClass implements ActionListener {

    @Override
    public void actionPerformed(final ActionEvent e) {
      doAction();
    }
  }

}
/home/jpschewe/projects/checker-bugs/src/main/java/net/mtu/eggplant/checker/LambdaInitialization.java:17: error: [method.invocation.invalid] call to doAction() not allowed on the given receiver.
    button.addActionListener(l -> doAction());
                                          ^
  found   : @UnderInitialization(net.mtu.eggplant.checker.LambdaInitialization.class) @NonNull LambdaInitialization
  required: @Initialized @NonNull LambdaInitialization
/home/jpschewe/projects/checker-bugs/src/main/java/net/mtu/eggplant/checker/LambdaInitialization.java:25: error: [method.invocation.invalid] call to doAction() not allowed on the given receiver.
        doAction();
                ^
  found   : @UnderInitialization(net.mtu.eggplant.checker.LambdaInitialization.class) @NonNull LambdaInitialization
  required: @Initialized @NonNull LambdaInitialization
mernst commented 3 years ago

I committed a test case as Issue4579.java.