diff --git a/source/rock/backend/cnaughty/ClassDeclWriter.ooc b/source/rock/backend/cnaughty/ClassDeclWriter.ooc index 49d81768..f59be199 100644 --- a/source/rock/backend/cnaughty/ClassDeclWriter.ooc +++ b/source/rock/backend/cnaughty/ClassDeclWriter.ooc @@ -72,7 +72,8 @@ ClassDeclWriter: abstract class extends Skeleton { } for(vDecl in cDecl variables) { - if(vDecl isExtern()) continue; + // ignore extern and virtual variables (usually properties) + if(vDecl isExtern() || vDecl isVirtual()) continue; current nl(). app(vDecl getType()). app(" "). app(vDecl getName()). app(';') } diff --git a/source/rock/middle/BinaryOp.ooc b/source/rock/middle/BinaryOp.ooc index f8bde2f1..5bf91f8f 100644 --- a/source/rock/middle/BinaryOp.ooc +++ b/source/rock/middle/BinaryOp.ooc @@ -148,13 +148,17 @@ BinaryOp: class extends Expression { // Left side is a property access? Replace myself with a setter call. // Make sure we're not in the getter/setter. - if(left instanceOf(VariableAccess) && left as VariableAccess ref instanceOf(PropertyDecl) \ - && left as VariableAccess ref as PropertyDecl inOuterSpace(trail)) { + if(left instanceOf(VariableAccess) && left as VariableAccess ref instanceOf(PropertyDecl)) { leftProperty := left as VariableAccess ref as PropertyDecl - fCall := FunctionCall new(left as VariableAccess expr, leftProperty getSetterName(), token) - fCall getArguments() add(right) - trail peek() replace(this, fCall) - return Responses OK + if(leftProperty inOuterSpace(trail)) { + fCall := FunctionCall new(left as VariableAccess expr, leftProperty getSetterName(), token) + fCall getArguments() add(right) + trail peek() replace(this, fCall) + return Responses OK + } else { + // We're in a setter/getter. This means the property is not virtual. + leftProperty setVirtual(false) + } } cast : Cast = null diff --git a/source/rock/middle/PropertyDecl.ooc b/source/rock/middle/PropertyDecl.ooc index eafad7ec..2e8fd1f3 100644 --- a/source/rock/middle/PropertyDecl.ooc +++ b/source/rock/middle/PropertyDecl.ooc @@ -10,11 +10,15 @@ PropertyDecl: class extends VariableDecl { setter: FunctionDecl = null cls: ClassDecl = null resolved := false + virtual := true // see `VariableAccess resolve` and `BinaryOp resolve` init: func ~pDecl (.type, .name, .token) { init(type, name, null, token) } + isVirtual: func -> Bool { virtual } + setVirtual: func (=virtual) {} + setSetter: func (=setter) {} setGetter: func (=getter) {} diff --git a/source/rock/middle/VariableAccess.ooc b/source/rock/middle/VariableAccess.ooc index ab17dc06..0248b0dd 100644 --- a/source/rock/middle/VariableAccess.ooc +++ b/source/rock/middle/VariableAccess.ooc @@ -160,16 +160,22 @@ VariableAccess: class extends Expression { } // Simple property access? Replace myself with a getter call. - // Make sure we're not in a getter/setter yet (the trail would - // contain `ref` then) - if(ref && ref instanceOf(PropertyDecl) && ref as PropertyDecl inOuterSpace(trail)) { - // Test that we're not part of an assignment (which will be replaced by a setter call) - // TODO: This should be nicer. - if(!(trail peek() instanceOf(BinaryOp) && trail peek() as BinaryOp type == OpTypes ass)) { - property := ref as PropertyDecl - fCall := FunctionCall new(expr, property getGetterName(), token) - trail peek() replace(this, fCall) - return Responses OK + if(ref && ref instanceOf(PropertyDecl)) { + // Make sure we're not in a getter/setter yet (the trail would + // contain `ref` then) + if(ref as PropertyDecl inOuterSpace(trail)) { + // Test that we're not part of an assignment (which will be replaced by a setter call) + // TODO: This should be nicer. + if(!(trail peek() instanceOf(BinaryOp) && trail peek() as BinaryOp type == OpTypes ass)) { + property := ref as PropertyDecl + fCall := FunctionCall new(expr, property getGetterName(), token) + trail peek() replace(this, fCall) + return Responses OK + } + } else { + // We are in a setter/getter and we're having a variable access. That means + // the property is not virtual. + ref as PropertyDecl setVirtual(false) } } diff --git a/source/rock/middle/VariableDecl.ooc b/source/rock/middle/VariableDecl.ooc index dcb7e200..de02f7f8 100644 --- a/source/rock/middle/VariableDecl.ooc +++ b/source/rock/middle/VariableDecl.ooc @@ -51,6 +51,11 @@ VariableDecl: class extends Declaration { ) } + /** If `true`, the property should not be added to the instance struct as a member. + Ordinary variables never are virtual. Properties can be. + */ + isVirtual: func -> Bool { false } + setOwner: func (=owner) {} setExpr: func (=expr) {} diff --git a/tests b/tests index 82b0fda4..a363182f 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 82b0fda4aed39f399e2036940747720363d07e03 +Subproject commit a363182f80e1292eb9b68742a561797652d30b65