| Introduction | How to use | ClassLoader | Serialization | Reflection | Attributes | Mechanism |
One of the most interessting features of C# are
Attributes, which works like a Compiler-Plugin
interface. It can be used to implement some sort
of Aspect-Programming features.
Which each declarative language element of ACDK Attributes
can be connected.
ACDK_CLASSATTRIBUTE(acdk.tools.mc.StringTagAttribute("Key1", "Val1"))
ACDK_CLASSATTRIBUTE(acdk.tools.mc.StringTagAttribute("Key2", "Val2"))
class TestClass
: extends acdk::lang::Object
{
ACDK_WITH_METAINFO(TestClass)
public:
ACDK_METHODATTRIBUTE(acdk.tools.mc.StringTagAttribute("Key3", "Val3"))
void foo();
};
|
These Attributes can be listed at runtime:
void listAttributes(IN(acdk::lang::dmi::RMetaObject) mo)
{
RMetaAttributeArray maa = mo->getMetaAttributes();
System::out->println("MetaAttributes of element:");
for (int i = 0; i < maa->length(); ++i)
{
RMetaAttribute ma = maa[i];
System::out->print(ma->name);
if (ma->value != Nil)
{
System::out->println(": " + ma->value->toString());
}
else
{
System::out->println(": Nil");
}
}
}
RObject obj = new TestClass();
RClass cls = obj->getClass();
listAttributes(cls);
RMethod method = cls->getDeclaredMethod("foo", new ClassArray(0));
listAttributes(method);
|
The MetaAttributes has two API levels.
On the underlying level MetaAttributes are connected
with acdk::lang::dmi::ClazzInfo and the other
C based Meta database. On top of these API resides the higher
API for reflection using acdk::lang::Class and the classes
of the unit acdk::lang::reflect.
The class acdk::lang::dmi::MetaAttribute has
an key, used to identify the attribute, and a value.
The base interface for all classes, which holds the the MetaAttributes
is acdk::lang::dmi::MetaObject.
This interface is implemented by:
In future releases:
The attribute defined by ACDK_CLASSATTRIBUTE(...), ACDK_METHODATTRIBUTE(...)
etc. are not hardwired constants, but represents a code fragmant in
expressed in a tiny language ACDKScript. ACDKScript instruments normal
ACDK classes via DMI. The class will be loaded via ClassLoader.
The expression:
ACDK_METHODATTRIBUTE(acdk.tools.mc.StringTagAttribute("Key3", "Val3"))
will be evaluated as:
new acdk.tools.mc.StringTagAttribute("Key3", "Val3");
which is in C++:
new acdk::tools::mc::StringTagAttribute("Key3", "Val3");
the resulting class in ACDK_CLASSATTRIBUTE(...) must be derived
from acdk::tools::mc::CodeAttribute and overwrite the apply(...)
methods.
The acdkmc Metacompiler calls the apply methods after it parses the
class definitions. The apply methods can:
If you want introduce own macros, in the ACDK headers -
for instance to insert method/member declarations - you have
to follow following rules to avoid to confuse the ACDK Metacompiler
acdkmc:
- Start your define with ACDK_. ACDK_MYUNIT_DEF is OK.
- Take care, that the comple define statement has ballance brackets:
ACDK_MYUNIT_DEF(my text() continues) is OK, ACDK_MYUNIT_DEF(my "text)" continues)
will confuse the acdkmc!
With the StringTagAttribute strings can be attached to an ACDK language
element.
ACDK_CLASSATTRIBUTE(acdk.tools.mc.StringTagAttribute("Key", "Value"))
Will attach the string attribute "Value" under the "Key" at the next following
class definition.
For polymorphic methods (methods with same name, but different
parameters) acdkmc will be generate alternative names with simply
adding numbers to the name. These names can be used from DMI Client/Servers
which doesn't support polymorphic methods.
Before numbering the methods, the methods
with parameter with default values will split into multiple method definitions.
void foo(int i, int j = 1, int k = 2);
int foo(IN(RString) str);
|
The resulting methods definitions are:
void foo(int i, int j, int k); // no altname
void foo(int i, int j); // altname: foo1
void foo(int i); // altname: foo2
int foo(IN(RString) str); // altname: foo3
|
To control the alternative name of the methods the attribute
acdk.tools.mc.MethodAltNameAttribute can be used:
class AClass
: extends acdk::lang::Object
{
ACDK_WITH_METAINFO(AClass)
public:
// version of next method with 3 parameters
ACDK_METHODATTRIBUTE(acdk.tools.mc.MethodAltNameAttribute("fooWith3IntParams", 3)
// CfgScript allows named parameters with the syntax:
// ': NameOfParam = Value'
ACDK_METHODATTRIBUTE(acdk.tools.mc.MethodAltNameAttribute(: altName = "fooWith2IntParams",
: paramCount = 2))
ACDK_METHODATTRIBUTE(acdk.tools.mc.MethodAltNameAttribute(: altName = "fooWith1IntParam",
: paramCount = 1))
void foo(int i, int j = 1, int k = 2);
ACDK_METHODATTRIBUTE(acdk.tools.mc.MethodAltNameAttribute("fooWithStringParam"))
int foo(IN(RString) str);
};
|
Via the DMI invoke method the methods are available via names
fooWith3IntParams, fooWith2IntParams, fooWith1IntParam and fooWithStringParam.
For example in Perl:
my $aclass = acdk::new("AClass");
$aclass->fooWith1IntParam(42);
|
or in C++:
RObject obj = Object::New("AClass");
obj->invoke("fooWithStringParam", "ACDK");
|
In C++-calls, not using DMI, the alternative names are not available,
but also not be necessary, because the C++-Compiler does the correct resolution
of the polymorphic functions.
The Attribute acdk.tools.mc.McConfigAttribute -
or with the short name McConfig - controls the ACDK MetaCompiler.
- Enables or disable generating Metainfo for fields
for a class or a single field.
- Enables or disable generating Metainfo for methods
for a class or a single method.
Sample:
namespace acdk {
namespace tools {
namespace aunit {
ACDK_DECL_CLASS(McConfigTest);
/**
Dummy class to Test MetaCompiler with Attributes
*/
// don't generate Metainfo for methods or fields by default
ACDK_CLASSATTRIBUTE(McConfig(:GenMethod = false, :GenField = false))
class ACDK_TOOLS_TESTUNIT_PUBLIC McConfigTest
: extends acdk::lang::Object
{
ACDK_WITH_METAINFO(McConfigTest)
public:
int firstMember; // not metainfo will be available for firstMember
// for the next field MetaInfo should be generated
ACDK_FIELDATTRIBUTE(McConfig(:GenField = true)) // metainfo will be available
int secondMember;
void firstMethod() {} // not metainfo will be available for firstMethod
// for the next method MetaInfo should be generated
ACDK_METHODATTRIBUTE(McConfig(:GenMethod = true))
void secondMethod(){} // metainfo will be available
};
} //namespace aunit
} // namespace tools
} // namespace acdk
|
Classes which are marked with ACDK_WITH_METAINFO will have MetaInfo
available. You can use McConfig as ClassAttribute to change this
default behaivor.
If by default metainfo for members and methods should be available,
you can also use the pseudo-keyword 'foreign' to mark a method or
a field as unknown to the MetaCompiler.
|