Struct_Class::Struct_Class(const Class &classData) : constantPoolTable(classData.constantPool()) , fieldPoolTable(classData.fields()) , methodPoolTable(classData.methods()) , inheritedStaticDataSize(0) , inheritedInstanceDataSize(0) , staticDataHandle(0) , ownStaticDataSize(classData.staticDataSize()) , ownInstanceDataSize(classData.instanceDataSize()) , className(classData.name()) { }
void IntModDtorMembers::beforeSemanticCheck(Node* node) { /// Check to apply only to non-static destructors SprFunction* fun = node->as<SprFunction>(); if ( !fun || getName(fun) != "dtor" ) REP_INTERNAL(node->location(), "IntModDtorMembers modifier can be applied only to destructors"); if ( !fun->hasThisParameters() ) REP_INTERNAL(node->location(), "IntModDtorMembers cannot be applied to static destructors"); // If we have a body, make sure it's a local space if ( !fun->body() ) return; // nothing to do LocalSpace* body = fun->body()->as<LocalSpace>(); if ( !body ) REP_INTERNAL(node->location(), "Destructor body is not a local space (needed by IntModDtorMembers)"); // Get the class Class* cls = getParentClass(fun->context()); CHECK(node->location(), cls); // Generate the dtor calls in reverse order of the fields; add them to the body of the destructor CompilationContext* context = body->childrenContext(); const Location& loc = body->location(); for ( Node* field: boost::adaptors::reverse(cls->fields()) ) { // Make sure we destruct only fields of the current class Class* cls2 = getParentClass(field->context()); if ( cls2 != cls ) continue; if ( field->type()->noReferences() == 0 ) { Node* fieldRef = mkFieldRef(loc, mkMemLoad(loc, mkThisExp(loc)), field); fieldRef->setContext(context); Node* call = mkOperatorCall(loc, fieldRef, "dtor", nullptr); call->setContext(context); body->addChild(call); } } }
TEST(OOModel, JavaLibraryAndHelloWorldTest) { Model::Model model; Project* prj = dynamic_cast<Project*> (model.createRoot("Project")); model.beginModification(prj, "build simple java library and a hello world app"); prj->setName("HelloWorld"); // Build a simple Java Library Library* java = prj->libraries()->append<Library>(); java->setName("Java"); Class* string = java->classes()->append<Class>(); string->setName("String"); string->setVisibility(Visibility::PUBLIC); Module* io = java->modules()->append<Module>(); io->setName("io"); Class* printstream = io->classes()->append<Class>(); printstream->setName("PrintStream"); printstream->setVisibility(Visibility::PUBLIC); Method* println = printstream->methods()->append<Method>(); println->setName("println"); println->setVisibility(Visibility::PUBLIC); FormalArgument* arg = println->arguments()->append<FormalArgument>(); arg->setName("x"); NamedType* argType = arg->setType<NamedType>(); argType->type()->ref()->set("class:String"); Class* system = java->classes()->append<Class>(); system->setName("System"); system->setVisibility(Visibility::PUBLIC); Field* out = system->fields()->append<Field>(); out->setName("out"); out->setVisibility(Visibility::PUBLIC); out->setStorageSpecifier(StorageSpecifier::CLASS_VARIABLE); NamedType* outtype = out->setType<NamedType>(); outtype->type()->ref()->set("class:PrintStream"); outtype->type()->setPrefix<ReferenceExpression>()->ref()->set("mod:io"); // Build a simple HelloWorld Application Class* hello = prj->classes()->append<Class>(); hello->setName("HelloWorld"); hello->setVisibility(Visibility::PUBLIC); Method* main = hello->methods()->append<Method>(); main->setName("main"); main->setVisibility(Visibility::PUBLIC); main->setStorageSpecifier(StorageSpecifier::CLASS_VARIABLE); //TODO make an array argument MethodCallStatement* callPrintln = main->items()->append<MethodCallStatement>(); StringLiteral* helloStr = callPrintln->arguments()->append<StringLiteral>(); helloStr->setValue("Hello World"); callPrintln->ref()->set("met:println"); VariableAccess* va = callPrintln->setPrefix<VariableAccess>(); va->ref()->set("field:out"); ReferenceExpression* ref = va->setPrefix<ReferenceExpression>(); ref->ref()->set("lib:Java,class:System"); model.endModification(); CHECK_STR_EQUAL("Java", java->name()); CHECK_CONDITION(callPrintln->methodDefinition() != nullptr); CHECK_CONDITION(callPrintln->methodDefinition() == println); }