【发布时间】:2015-03-26 08:04:25
【问题描述】:
我没有对我的任何模块进行重大更改,但突然间编译我的很多模块时开始失败。
我收到以下错误
borders.d(190): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
borders.d(191): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\image.d(117): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\image.d(121): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\image.d(121): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\imagebutton.d(45): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\imagebutton.d(59): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\imagebutton.d(73): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\imagebutton.d(89): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\imagebutton.d(100): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\imagebutton.d(110): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
controls\labelbutton.d(78): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\labelbutton.d(89): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\textbox.d(245): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
controls\textbox.d(247): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
controls\textbox.d(259): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
controls\textbox.d(309): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\textbox.d(310): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
controls\textbox.d(324): Error: function aeri.context.Context.size (Point newSize) is not callable using argument types ()
controls\textbox.d(325): Error: function aeri.context.Context.position (Point newPosition) is not callable using argument types ()
只是为了展示导致它的原因的示例。这是来自borders.d的代码sn-p
this(Context parent, Paint topPaint, Paint rightPaint, Paint bottomPaint, Paint leftPaint) {
super();
if (!parent)
throw new BorderException("Pass a context to render the border around.");
m_parent = parent;
m_topPaint = topPaint;
m_rightPaint = rightPaint;
m_bottomPaint = bottomPaint;
m_leftPaint = leftPaint;
position = parent.position; // Line 190
size = parent.size; // Line 191
}
现在让我们看看Context.position 和Context.size
override void size(Point newSize) {
super.size = newSize;
if (m_backgroundPaint != transparent) {
m_backgroundShape = new RectangleShape(Vector2f(cast(float)super.width, cast(float)super.height));
m_backgroundShape.fillColor = m_backgroundPaint.toSfmlColor();
m_backgroundShape.position = Vector2f(cast(float)super.x, cast(float)super.y);
}
if (m_border) {
m_border.size = Point(super.size);
}
}
override void position(Point newPosition) {
super.position = newPosition;
if (m_backgroundShape) {
m_backgroundShape.position = Vector2f(cast(float)super.x, cast(float)super.y);
}
if (m_border) {
m_border.position = Point(super.position);
}
}
那些是二传手。
Context 继承了一个名为 Space 的类,该类具有用于位置和大小的 getter / setter。 Context 只覆盖了 setter,但 getter 是相同的,应该从 Space 调用。似乎它甚至根本没有从Space 获得属性。正如您所看到的,它在应该获取 getter 时尝试获取 setter。然而,所有这些代码都更早地工作了。
这是Space中的属性。
Point position() { return m_position; }
void position(Point newPos) {
m_position = newPos;
}
Point size() { return m_size; }
void size(Point newSize) {
m_size = newSize;
}
注意:我将我的所有属性都包装如下,以防您想知道为什么找不到 @property。
@property {
// properties
}
我真的不知道是什么原因造成的,这让我认为这与编译器分析模块的顺序有关?
我仍在尝试自己解决此问题,但我无法发现问题所在,并且在我更改了 Space 中的一些行之后,一切似乎都崩溃了,但没有一个成员。
如果您想知道image.d、imagebutton.d、labelbutton.d 和textbox.d 中的错误是由同一件事引起的。它们都继承 Context 并覆盖大小/位置。
所以继承基本上是这样的:
x (ex. Image, ImageButton, LabelButton, TextBox etc.)
----Control
--------Context
------------Space
LabelButton 和 ImageButton 继承 Button 继承 Control。
Control 不会覆盖任何来自Context 的成员,因此所有对Control 的调用都直接转到Context。 Button 也是如此,除了它有一些用于处理鼠标事件的内部成员(在 Context 中处理,但它调用它。)
这里是Control 类和Button 类以防万一。
class Control : Context {
protected:
this(string name) {
super(name);
}
}
...
class Button : Control {
private:
bool m_intersecting = false;
bool m_focused = false;
void handleMouseReleased(Context context, Mouse.Button button) {
m_focused = m_intersecting;
if (m_focused && button == Mouse.Button.Left) {
foreach (event; m_onClick) {
if (event)
event.exec();
}
}
}
void handleMouseMove(Context context, Point position){
m_intersecting = super.intersect(position);
}
protected:
this(string name) {
super(name);
super.onMouseReleased(new MouseClickEvent(&handleMouseReleased));
super.onMouseMove(new PositionEvent(&handleMouseMove));
}
private Action[] m_onClick;
public void onClick(Action event) {
if (!validMessageThread)
throw new MessageException("Cannot register an event outside of the application thread / render thread");
m_onClick ~= event;
}
}
如果您需要更多信息或代码,请告诉我。但是我认为这应该足够了。属性/属性调用的继承和覆盖之前工作得很好。
【问题讨论】:
-
不确定这是否是原因,但您是否更新到新的编译器? (dmd 2067.0)。如果是这样,可能值得降级到 2066.1 看看它是否能修复它。
-
如果您使用
git,您可以使用git blame查找编译开始失败的点。如果您可以将其本地化为一个小的更改,那么了解和解决问题会容易得多。 -
在函数声明中直接添加
@property是否有效?您可以尝试使用-property运行 DMD,它强制执行@property的o.prop = x语法,也许这会提供更好的消息。 -
还要确保这些 getter 不是私有的,我认为最近关于私有方法的查找方式发生了变化,这可能是造成这种情况的原因。
-
我的编译器不是最新的。事实上,自去年以来我还没有更新我的编译器。这一切都在早些时候起作用,然后突然发生了这种情况。我也没有使用 git。使用 -property 编译也不起作用。手动声明@property 也没有改变任何东西。最后,它们都在类的公共范围内声明。我发现了它的原因,它似乎是一个编译器错误。显然这是因为 Context 覆盖了位置/大小(仅设置器),然后它永远不会在空间中向下查找 getter。如果我在上下文中注释掉位置/大小,那么它会起作用。
标签: inheritance properties d overriding