如何在存根中注释隐式参数
How do I annotate an implicit parameter in a stub
我正在尝试使用 Nullness Checker 构建 JPanel 的子类。
class MyView<R extends @NonNull Object> extends JPanel {
// ...
// constructor calls this method:
@RequiresNonNull({"labelPanel", "fieldPanel", "checkBoxPanel"})
private void makeTopPanel(@UnderInitialization MyView<R> this) {
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(labelPanel, BorderLayout.LINE_START);
topPanel.add(fieldPanel, BorderLayout.CENTER);
topPanel.add(checkBoxPanel, BorderLayout.LINE_END);
// Error here: [method.invocation.invalid] call to add(java.awt.Component,java.lang.Object)
// not allowed on the given receiver.
add(topPanel, BorderLayout.PAGE_START);
setBorder(new MatteBorder(1, 0, 0, 0, Color.black));
}
}
错误消息是这样说的:
error: [method.invocation.invalid] call to add(java.awt.Component,java.lang.Object) not allowed
on the given receiver.
found : @UnderInitialization @NonNull Container
required: @Initialized @NonNull Container
问题似乎是添加方法假定 this
已初始化。但是在构造函数中调用 Container 的 add 方法是非常安全的。所以为了防止这个错误,我想创建一个带有注释隐式参数的存根文件:
package java.awt;
public class Container extends Component {
public void add(@UnknownInitialization Container, @NonNull Component, @NonNull Object);
}
好像没有把这里的add()
方法识别为java.awt.Container.add(Component, Object)
方法
这是完整的存根文件:
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import javax.swing.border.Border;
import java.awt.Component;
import java.awt.Container;
package javax.swing;
public class Timer {
public Timer(int delay, @Nullable ActionListener listener);
}
public class JOptionPane {
public static void showMessageDialog(@Nullable Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException;
}
package java.awt;
public class Container extends Component {
public void setBorder(@UnknownInitialization JComponent this, @Nullable Border border);
public void add(@UnknownInitialization Container this, @NonNull Component, @NonNull Object);
}
我知道我可以用注释抑制警告,但存根文件感觉更简洁。有什么方法可以修复这个存根文件吗?
有两个问题。
第一个问题是您的存根文件格式不正确。
行
public void add(@UnknownInitialization Container this, @NonNull Component, @NonNull Object);
应该是
public void add(@UnknownInitialization Container this, @NonNull Component comp, @NonNull Object constraints);
因为 Java 方法声明需要形式参数名称。
此外,它缺少 import
语句:
import org.checkerframework.checker.nullness.qual.NonNull;
第二个问题是您一定没有传递-Astubs=...
命令行参数,否则您会收到关于存根文件格式错误的警告。 (你没有说你是如何调用 javac
,这将有助于诊断你的问题。)
当我纠正这些问题时,检查器框架按预期工作。
运行命令
$CHECKERFRAMEWORK/checker/bin/javac -processor nullness -g MyView.java
发出警告,
$CHECKERFRAMEWORK/checker/bin/javac -processor nullness -g MyView.java -Astubs=mystub.astub
不发出警告。
更正后的文件(即它们是完整的并且更小)出现在下面。
MyView.java:
import java.awt.BorderLayout;
import javax.swing.JPanel;
import org.checkerframework.checker.initialization.qual.UnderInitialization;
class MyView extends JPanel {
MyView() {
makeTopPanel();
}
private void makeTopPanel(@UnderInitialization MyView this) {
JPanel topPanel = new JPanel(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
}
}
mystub.astub:
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import javax.swing.border.Border;
import java.awt.Component;
import java.awt.Container;
package javax.swing;
public class Timer {
public Timer(int delay, @Nullable ActionListener listener);
}
public class JOptionPane {
public static void showMessageDialog(@Nullable Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException;
}
package java.awt;
public class Container extends Component {
public void setBorder(@UnknownInitialization JComponent this, @Nullable Border border);
public void add(@UnknownInitialization Container this, @NonNull Component comp, @NonNull Object constraints);
}
我正在尝试使用 Nullness Checker 构建 JPanel 的子类。
class MyView<R extends @NonNull Object> extends JPanel {
// ...
// constructor calls this method:
@RequiresNonNull({"labelPanel", "fieldPanel", "checkBoxPanel"})
private void makeTopPanel(@UnderInitialization MyView<R> this) {
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(labelPanel, BorderLayout.LINE_START);
topPanel.add(fieldPanel, BorderLayout.CENTER);
topPanel.add(checkBoxPanel, BorderLayout.LINE_END);
// Error here: [method.invocation.invalid] call to add(java.awt.Component,java.lang.Object)
// not allowed on the given receiver.
add(topPanel, BorderLayout.PAGE_START);
setBorder(new MatteBorder(1, 0, 0, 0, Color.black));
}
}
错误消息是这样说的:
error: [method.invocation.invalid] call to add(java.awt.Component,java.lang.Object) not allowed
on the given receiver.
found : @UnderInitialization @NonNull Container
required: @Initialized @NonNull Container
问题似乎是添加方法假定 this
已初始化。但是在构造函数中调用 Container 的 add 方法是非常安全的。所以为了防止这个错误,我想创建一个带有注释隐式参数的存根文件:
package java.awt;
public class Container extends Component {
public void add(@UnknownInitialization Container, @NonNull Component, @NonNull Object);
}
好像没有把这里的add()
方法识别为java.awt.Container.add(Component, Object)
方法
这是完整的存根文件:
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import javax.swing.border.Border;
import java.awt.Component;
import java.awt.Container;
package javax.swing;
public class Timer {
public Timer(int delay, @Nullable ActionListener listener);
}
public class JOptionPane {
public static void showMessageDialog(@Nullable Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException;
}
package java.awt;
public class Container extends Component {
public void setBorder(@UnknownInitialization JComponent this, @Nullable Border border);
public void add(@UnknownInitialization Container this, @NonNull Component, @NonNull Object);
}
我知道我可以用注释抑制警告,但存根文件感觉更简洁。有什么方法可以修复这个存根文件吗?
有两个问题。
第一个问题是您的存根文件格式不正确。
行
public void add(@UnknownInitialization Container this, @NonNull Component, @NonNull Object);
应该是
public void add(@UnknownInitialization Container this, @NonNull Component comp, @NonNull Object constraints);
因为 Java 方法声明需要形式参数名称。
此外,它缺少 import
语句:
import org.checkerframework.checker.nullness.qual.NonNull;
第二个问题是您一定没有传递-Astubs=...
命令行参数,否则您会收到关于存根文件格式错误的警告。 (你没有说你是如何调用 javac
,这将有助于诊断你的问题。)
当我纠正这些问题时,检查器框架按预期工作。 运行命令
$CHECKERFRAMEWORK/checker/bin/javac -processor nullness -g MyView.java
发出警告,
$CHECKERFRAMEWORK/checker/bin/javac -processor nullness -g MyView.java -Astubs=mystub.astub
不发出警告。
更正后的文件(即它们是完整的并且更小)出现在下面。
MyView.java:
import java.awt.BorderLayout;
import javax.swing.JPanel;
import org.checkerframework.checker.initialization.qual.UnderInitialization;
class MyView extends JPanel {
MyView() {
makeTopPanel();
}
private void makeTopPanel(@UnderInitialization MyView this) {
JPanel topPanel = new JPanel(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
}
}
mystub.astub:
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import javax.swing.border.Border;
import java.awt.Component;
import java.awt.Container;
package javax.swing;
public class Timer {
public Timer(int delay, @Nullable ActionListener listener);
}
public class JOptionPane {
public static void showMessageDialog(@Nullable Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException;
}
package java.awt;
public class Container extends Component {
public void setBorder(@UnknownInitialization JComponent this, @Nullable Border border);
public void add(@UnknownInitialization Container this, @NonNull Component comp, @NonNull Object constraints);
}