/** * Defines the requirements for a valid class scope * Throws a ScopeCheckErr exception if there's a problem. */ void typecheck::CheckScope::checkClass(typecheck::ClassNode* cls) { string* superName = cls->getSuper(); if(superName == nullptr) { return; } /* Register the super class if it exists, but flag it as unimplemented. If the class already exists in the confirmedClasses map, don't reset it (we don't want to stomp a value of true with a value of false) */ if(confirmedClasses.find(*superName) == confirmedClasses.end()) { confirmedClasses.insert(std::pair<string, bool>(*superName, false)); } /* Make sure there aren't any attributes defined in this class that are also defined in its parent. */ Groot* groot = cls->getLexParent(); for(auto attr_kv : cls->getMembers()) { /* Step up the inheritance tree, checking for variables with similar names */ while(superName != nullptr) { ClassNode* superClass = groot->getClasses()[*superName]; // Get the node for the symbol class. Note that cls->getLexParent() returns Groot. /* If the this super class has the same variable, throw error */ if(superClass->getMembers().count(attr_kv.first) >= 1) { std::stringstream msg; msg << "Error: Instance variable '" << attr_kv.first << "' already exists in a super class '" << *superName << "'" << endl; throw ScopeCheckErr(msg.str().c_str()); } superName = superClass->getSuper(); } } }