better support for private classes in our model (CustomNamespace) and related classes (RBClass, RBMetaclass)
authorJakub Nesveda <jakubnesveda@seznam.cz>
Sat, 29 Nov 2014 15:15:24 +0100
changeset 765 d706c98adeb5
parent 764 5e1b8d096052
child 766 1313153656d9
better support for private classes in our model (CustomNamespace) and related classes (RBClass, RBMetaclass) Althought its still fully complete in coparison to real classes, it offers now decent set of functionality
CustomNamespace.st
CustomNamespaceTests.st
CustomRBAbstractClassTests.st
CustomRBMetaclassTests.st
CustomRBMethodTests.st
CustomTestCaseMethodCodeGenerator.st
CustomTestCaseMethodCodeGeneratorTests.st
abbrev.stc
extensions.st
jn_refactoring_custom.st
patches/patches.rc
refactoring_custom.rc
--- a/CustomNamespace.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/CustomNamespace.st	Sat Nov 29 15:15:24 2014 +0100
@@ -151,6 +151,27 @@
     "Created: / 19-11-2014 / 21:20:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 ! !
 
+!CustomNamespace methodsFor:'changes'!
+
+defineClass: aString
+    "Defines a class withing this model by its definition string.
+    Here is same behaviour as in RBNamespace, but we added private
+    class support."
+    | change |
+
+    change := super defineClass: aString.
+    change privateInClassName notNil ifTrue: [ 
+        | class |
+
+        class := self classNamed: change changeClassName.
+        class owningClass: (self classNamed: change privateInClassName)
+    ].
+
+    ^ change
+
+    "Created: / 29-11-2014 / 14:39:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
 !CustomNamespace methodsFor:'code creation'!
 
 createClass
--- a/CustomNamespaceTests.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/CustomNamespaceTests.st	Sat Nov 29 15:15:24 2014 +0100
@@ -947,6 +947,45 @@
     "Modified: / 10-10-2014 / 15:33:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 !
 
+test_define_class_with_private_class
+    | expectedClass actualClass |
+
+    expectedClass := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    model defineClass: 'DummyClass01 subclass:#DummyPrivate01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyClass01'.    
+
+    actualClass := (model classNamed: #DummyClass01::DummyPrivate01) owningClass.   
+
+    self assert: expectedClass = actualClass
+
+    "Modified: / 29-11-2014 / 14:49:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_define_class_without_private_class
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.    
+
+    actualClass := (model classNamed: #DummyClass01) owningClass.   
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:51:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
 test_empty_class_definition_string
     | expectedDefinition actualDefinition |
 
--- a/CustomRBAbstractClassTests.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/CustomRBAbstractClassTests.st	Sat Nov 29 15:15:24 2014 +0100
@@ -24,12 +24,12 @@
 setUp
 
     mock := CustomMock new.
-    model := RBNamespace new.
+    model := CustomNamespace new.
     rbClass := mock mockOf: RBAbstractClass.
     rbClass model: model.
 
     "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
-    "Modified: / 04-10-2014 / 13:46:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-11-2014 / 14:40:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 !
 
 tearDown
@@ -750,6 +750,89 @@
     "Created: / 05-10-2014 / 00:13:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 !
 
+test_owning_class
+    | expectedClass actualClass |
+
+    expectedClass := RBClass new.
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    rbClass := model classNamed: #DummyClass01.  
+    rbClass owningClass: expectedClass.
+
+    actualClass := rbClass owningClass.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:27:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_from_definition_string
+    | expectedClass actualClass |
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    model defineClass: 'Object subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyClass01'.
+
+    expectedClass := model classNamed: #DummyClass01.  
+
+    rbClass := model classNamed: #DummyClass01::DummyPrivateClass01.  
+
+    actualClass := rbClass owningClass.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_or_yourself_none_owner
+    | expectedClass actualClass |
+
+    rbClass := model classNamed: self class name.  
+    expectedClass := rbClass.
+
+    actualClass := rbClass owningClassOrYourself.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:59:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_or_yourself_owner
+    | expectedClass actualClass |
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    expectedClass := model classNamed: #DummyClass01.
+    rbClass := model classNamed: self class name.  
+    rbClass owningClass: expectedClass.
+
+    actualClass := rbClass owningClassOrYourself.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:56:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
 test_package_custom
     | expectedPackage actualPackage |
 
@@ -863,6 +946,34 @@
     "Created: / 16-11-2014 / 16:58:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 !
 
+test_top_owning_class
+    | expectedClass actualClass |
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    model defineClass: 'Object subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyClass01'.
+
+    expectedClass := model classNamed: #DummyClass01.  
+
+    rbClass := model classNamed: #DummyClass01::DummyPrivateClass01.  
+    rbClass owningClass: expectedClass.
+
+    actualClass := rbClass topOwningClass.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:12:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
 test_with_all_superclasses_do_for_one_superclass
     | expectedClassNames actualClassNames |
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CustomRBMetaclassTests.st	Sat Nov 29 15:15:24 2014 +0100
@@ -0,0 +1,254 @@
+"{ Package: 'jn:refactoring_custom' }"
+
+TestCase subclass:#CustomRBMetaclassTests
+	instanceVariableNames:'rbClass mock model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+CustomRBMetaclassTests subclass:#MockPrivateClass01
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRBMetaclassTests
+!
+
+CustomRBMetaclassTests::MockPrivateClass01 subclass:#MockPrivateClass03
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRBMetaclassTests::MockPrivateClass01
+!
+
+Object subclass:#MockPrivateClass02
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRBMetaclassTests
+!
+
+!CustomRBMetaclassTests class methodsFor:'documentation'!
+
+documentation
+"
+    Test extensions in RBMetaclass.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+
+"
+! !
+
+!CustomRBMetaclassTests methodsFor:'initialization & release'!
+
+setUp
+
+    mock := CustomMock new.
+    model := RBNamespace new.
+    rbClass := mock mockOf: RBMetaclass.
+    rbClass model: model.
+
+    "Created: / 29-11-2014 / 02:28:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll
+
+    "Created: / 29-11-2014 / 02:28:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMetaclassTests methodsFor:'tests'!
+
+test_owning_class_empty
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:37:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_model_class
+    | expectedClass actualClass |
+
+    expectedClass := RBClass new.
+    rbClass owningClass: expectedClass.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:43:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_model_metaclass
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    rbClass owningClass: expectedClass theMetaclass.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_real_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    rbClass owningClass: self class.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:42:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_real_metaclass
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    rbClass owningClass: self class theMetaclass.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:37:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #CustomRBMetaclassTests.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 02:31:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-11-2014 / 12:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class_with_different_superclass
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #CustomRBMetaclassTests.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass02.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:20:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class_without_owner
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+
+    rbClass realClass: CustomRBMetaclassTests.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:21:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_01
+    | expectedClass actualClass |
+
+    expectedClass := self class.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:34:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_02
+    | expectedClass actualClass |
+
+    expectedClass := self class.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 class owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:35:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_03
+    | expectedClass actualClass |
+
+    expectedClass := self class.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 theMetaclass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:35:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_04
+    | expectedClass actualClass |
+
+    expectedClass := self class.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 theNonMetaclass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:35:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_empty
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+    actualClass := rbClass topOwningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:53:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_with_real_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #CustomRBMetaclassTests.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01.
+    actualClass := rbClass topOwningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:04:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_with_real_class_two_level
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #CustomRBMetaclassTests.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01 myMockPrivateClass03.
+    actualClass := rbClass topOwningClass.
+
+    self assert: (rbClass realClass name) = #CustomRBMetaclassTests::MockPrivateClass01::MockPrivateClass03.
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:05:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMetaclassTests::MockPrivateClass01 class methodsFor:'accessing'!
+
+myMockPrivateClass03
+    "Returns my private class (for testing purposes)"
+
+    ^ MockPrivateClass03
+
+    "Created: / 29-11-2014 / 14:08:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- a/CustomRBMethodTests.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/CustomRBMethodTests.st	Sat Nov 29 15:15:24 2014 +0100
@@ -335,16 +335,18 @@
     "Created: / 08-10-2014 / 19:36:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 !
 
-test_mclass_for_model_class
+test_mclass
     | expectedClass actualClass |
 
-    expectedClass := 'unkwnown'.
+    expectedClass := RBClass new. 
+    rbMethod modelClass: expectedClass.
 
-    actualClass := rbMethod mclass owningClassOrYourself.
+    actualClass := rbMethod mclass.
 
     self assert: expectedClass = actualClass
 
-    "Created: / 19-11-2014 / 09:54:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Created: / 25-11-2014 / 22:27:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 27-11-2014 / 23:18:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 !
 
 test_method_arg_names_none_arg
--- a/CustomTestCaseMethodCodeGenerator.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/CustomTestCaseMethodCodeGenerator.st	Sat Nov 29 15:15:24 2014 +0100
@@ -107,17 +107,14 @@
     "Created: / 15-10-2014 / 09:04:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 ! !
 
-!CustomTestCaseMethodCodeGenerator methodsFor:'executing'!
+!CustomTestCaseMethodCodeGenerator methodsFor:'executing - private'!
 
 buildInContext: aCustomContext
 
     aCustomContext selectedMethods do:[ :method | 
         | class className testClass |
 
-        class := method modelClass realClass owningClassOrYourself.
-        "/ TODO implement these missing methods in RBMethod
-        "/ and replace it with:
-        "/ class := method mclass owningClassOrYourself.
+        class := method mclass owningClassOrYourself.
 
         className := class theNonMetaclass name.
         (className endsWith: 'Tests') ifFalse: [ 
@@ -145,10 +142,8 @@
     ].
 
     "Created: / 24-08-2014 / 16:24:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
-    "Modified: / 19-11-2014 / 09:55:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
-! !
-
-!CustomTestCaseMethodCodeGenerator methodsFor:'executing - private'!
+    "Modified: / 29-11-2014 / 15:01:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
 
 configureInContext:aCustomContext
 
--- a/CustomTestCaseMethodCodeGeneratorTests.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/CustomTestCaseMethodCodeGeneratorTests.st	Sat Nov 29 15:15:24 2014 +0100
@@ -15,6 +15,27 @@
 
 !CustomTestCaseMethodCodeGeneratorTests methodsFor:'tests'!
 
+test_generate_test_method_for_class
+    | expectedSource method class testClass |
+
+    class := model createClassImmediate: #MockClassForTestCase01 superClassName: #Object.
+    testClass := model createClassImmediate: #MockClassForTestCase01Tests.
+    method := model createMethodImmediate: class source: 'selector_01 ^ 1'.
+
+    context selectedMethods: (Array with: method).  
+
+    expectedSource := 'test_selector_01
+    "/ something selector_01.    
+
+    self assert:1 = 2.'.
+
+    generatorOrRefactoring executeInContext: context.  
+
+    self assertMethodSource:expectedSource atSelector:#test_selector_01 forClass:testClass
+
+    "Created: / 29-11-2014 / 15:04:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
 test_generate_test_method_for_private_class
     | expectedSource privateClass method superclass testClass |
 
--- a/abbrev.stc	Sat Nov 29 02:25:49 2014 +0100
+++ b/abbrev.stc	Sat Nov 29 15:15:24 2014 +0100
@@ -23,6 +23,7 @@
 CustomRBAbstractClassTests CustomRBAbstractClassTests jn:refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
 CustomRBClassTests CustomRBClassTests jn:refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
 CustomRBLocalSourceCodeFormatterTests CustomRBLocalSourceCodeFormatterTests jn:refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+CustomRBMetaclassTests CustomRBMetaclassTests jn:refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
 CustomRBMethodTests CustomRBMethodTests jn:refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
 CustomRefactoryBuilder CustomRefactoryBuilder jn:refactoring_custom 'Interface-Refactoring-Custom' 0
 CustomRefactoryClassChangeTests CustomRefactoryClassChangeTests jn:refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
--- a/extensions.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/extensions.st	Sat Nov 29 15:15:24 2014 +0100
@@ -301,6 +301,37 @@
 
 !RBAbstractClass methodsFor:'accessing'!
 
+owningClass
+    "see Behavior >> owningClass"
+
+    ^ self theMetaclass owningClass
+
+    "Created: / 29-11-2014 / 13:17:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+owningClass: aClass
+    "Sets the owning class which is actually stored in the metaclass"
+
+    self theMetaclass owningClass: aClass
+
+    "Created: / 29-11-2014 / 13:21:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+owningClassOrYourself
+    "see Behavior >> owningClassOrYourself"
+
+    self owningClass notNil ifTrue:[^ self topOwningClass].
+    ^ self
+
+    "Created: / 29-11-2014 / 13:44:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
 package
     "see Class >> package ( same purpose, but for model class )"
     | package |
@@ -398,6 +429,16 @@
     "Modified (comment): / 16-11-2014 / 16:58:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 ! !
 
+!RBAbstractClass methodsFor:'queries'!
+
+topOwningClass
+    "see Behavior >> topOwningClass"
+
+    ^ self theMetaclass topOwningClass
+
+    "Created: / 29-11-2014 / 13:48:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
 !RBAbstractClass methodsFor:'enumerating'!
 
 withAllSuperclassesDo:aBlock
@@ -443,6 +484,37 @@
 
 !RBMetaclass methodsFor:'accessing'!
 
+owningClass
+    "see PrivateMetaclass >> owningClass"
+    | owningClass |
+
+    owningClass := self objectAttributeAt: #owningClass.
+    owningClass isNil ifTrue: [ 
+        self realClass notNil ifTrue: [ 
+            ^ self model classFor: self realClass owningClass
+        ]
+    ].
+
+    ^ owningClass.
+
+    "Created: / 29-11-2014 / 02:20:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+owningClass: aClass
+    "see owningClass"
+
+    self 
+        objectAttributeAt: #owningClass 
+        put: (self model classFor: aClass theNonMetaclass)
+
+    "Created: / 29-11-2014 / 02:23:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-11-2014 / 13:38:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
 theMetaClass
     "alias for metaclass - sqeak compatibility"
 
@@ -461,6 +533,22 @@
     "Created: / 26-09-2014 / 21:28:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
 ! !
 
+!RBMetaclass methodsFor:'queries'!
+
+topOwningClass
+    "see PrivateMetaclass >> topOwningClass"
+    | outerOwner |
+
+    self owningClass isNil ifTrue:[^ nil].
+
+    (outerOwner := self owningClass owningClass) notNil ifTrue:[
+        ^ self owningClass topOwningClass
+    ].
+    ^ self owningClass
+
+    "Created: / 29-11-2014 / 13:52:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
 !RBMethod methodsFor:'accessing'!
 
 category: aCategoryName
@@ -495,6 +583,17 @@
 
 !RBMethod methodsFor:'accessing'!
 
+mclass
+    "see Method >> mclass
+    Returns instace of RBClass, RBMetaclass or nil when unknown"
+
+    ^ self modelClass
+
+    "Created: / 27-11-2014 / 23:20:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
 methodArgNames
     "Returns collection of method argument names"
 
--- a/jn_refactoring_custom.st	Sat Nov 29 02:25:49 2014 +0100
+++ b/jn_refactoring_custom.st	Sat Nov 29 15:15:24 2014 +0100
@@ -120,6 +120,7 @@
         (CustomRBAbstractClassTests autoload)
         (CustomRBClassTests autoload)
         (CustomRBLocalSourceCodeFormatterTests autoload)
+        (CustomRBMetaclassTests autoload)
         (CustomRBMethodTests autoload)
         CustomRefactoryBuilder
         (CustomRefactoryClassChangeTests autoload)
@@ -277,6 +278,14 @@
         RBAbstractClass privateClassesAt:
         RBAbstractClass realSharedPoolNames
         RBAbstractClass topNameSpace
+        RBMetaclass owningClass
+        RBMetaclass owningClass:
+        RBMethod mclass
+        RBAbstractClass owningClass
+        RBAbstractClass owningClass:
+        RBAbstractClass owningClassOrYourself
+        RBAbstractClass topOwningClass
+        RBMetaclass topOwningClass
     )
 ! !
 
--- a/patches/patches.rc	Sat Nov 29 02:25:49 2014 +0100
+++ b/patches/patches.rc	Sat Nov 29 15:15:24 2014 +0100
@@ -25,7 +25,7 @@
       VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
       VALUE "ProductName", "LibraryName\0"
       VALUE "ProductVersion", "6.2.4.1420\0"
-      VALUE "ProductDate", "Tue, 25 Nov 2014 20:39:21 GMT\0"
+      VALUE "ProductDate", "Sat, 29 Nov 2014 14:09:00 GMT\0"
     END
 
   END
--- a/refactoring_custom.rc	Sat Nov 29 02:25:49 2014 +0100
+++ b/refactoring_custom.rc	Sat Nov 29 15:15:24 2014 +0100
@@ -25,7 +25,7 @@
       VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
       VALUE "ProductName", "ProductName\0"
       VALUE "ProductVersion", "6.2.4.1420\0"
-      VALUE "ProductDate", "Tue, 25 Nov 2014 20:39:18 GMT\0"
+      VALUE "ProductDate", "Sat, 29 Nov 2014 14:08:56 GMT\0"
     END
 
   END