Example #1
0
/**
 * Checks for invalid methods (e.g., overloading vs. overriding)
 */
void typecheck::CheckScope::checkMethods(ClassNode* cls) {
  string* superName = cls->getSuper();
  if(superName == nullptr) {
    return;
  }
  Groot* groot = cls->getLexParent();

  /* For every method defined in this class... */
  for(auto method_kv : cls->getMethods()) {
    string methodSig = getMethodSig(cls, string(method_kv.first));

    /* Step up the inheritance tree, checking for another method with the same signature */
    while(superName != nullptr) {
      ClassNode* superClass = groot->getClasses()[*superName]; // Get the node for the symbol class. Note that cls->getLexParent() returns Groot.
      superName = superClass->getSuper();

      /* If this super doesn't have a method by the correct name, don't bother checking the signatures */
      if(superClass->getMethods().find(method_kv.first) == superClass->getMethods().end()) {
        continue;
      }

      if(methodSig != getMethodSig(superClass, method_kv.first)) {
        std::stringstream msg;
        msg << "Error: Method '" << method_kv.first << "' has a different signature from the super class";

        throw ScopeCheckErr(msg.str().c_str());
      }
    }
  }
}