def result(element): lhs_type = element.env.canonicalize_name(type_string(element[0])) rhs_type = element.env.canonicalize_name(type_string(element[2])) if is_integral_primitive(lhs_type) and is_integral_primitive(rhs_type): element.attrib["type"] = "int" return error_if(lhs_type != rhs_type != expected_type_string, "binary_expression type mismatch") element.attrib["type"] = expected_type_string
def get_type_for_declaration_site(self, element): decl_type_string = type_string(element) if (is_primitive(decl_type_string) or isarray(decl_type_string) or decl_type_string == "void"): return decl_type_string return self.findclass(decl_type_string).get("canonical_name")
def check_path_for_protected(self, path): if len(path) == 1: # Impossible to violate protected with a 1 length path return for x in range(0, len(path) - 1): previous_path_element = path[x] current_path_element = path[x + 1] if not "protected" in modifiers(current_path_element): continue if self.find_package_name() == \ current_path_element.env.find_package_name(): continue current_class_name = self.get_current_class_name() current_path_element_class_name = \ current_path_element.env.get_current_class_name() if previous_path_element.tag == "class": error_if(not self.is_subtype(current_class_name, current_path_element_class_name), "must be a subtype to access a proteced static member") else: previous_path_element_type = \ self.canonicalize_name(type_string(previous_path_element)) error_if(not self.is_subtype(previous_path_element_type, current_class_name), "must invoke on a subtype to access a protected member") error_if(not self.is_subtype(current_class_name, current_path_element_class_name), "Cannot invoke protected member in subtype")
def method(element): method_type = element.env.canonicalize_name(type_string(element)) block = element.find("block") if block is not None: return_statements = block.findall(".//return_statement") error_if(len(return_statements) == 0 and method_type != "void", "Missing return statement in function not returning void.") for return_statement in return_statements: return_statement_type = return_statement.attrib["type"] if method_type == "void": error_if(return_statement_type != "", "Void method returns a value.") else: error_if(not element.env.is_assignable(method_type, return_statement_type), "Cannot return '" + return_statement_type + "' in a method returning '" + method_type + "'") element.attrib["type"] = method_type
def get_declaration_site_for_name_internal(env, name, type, arglist, canBeClass=True): qualified_parts = name.split(".") if len(qualified_parts) == 1: path = [] if type == "Variable": path += [env.find_nonlocal(name)] if type == "Method": path += [env.find_method_by_name(name, arglist)] path = [x for x in path if x][:1] error_if(not path, "Could not find %s %s" % (type, name)) else: path = [] rhs = None # Initialize for x in range(1, len(qualified_parts) + 1): lhs = ".".join(qualified_parts[:x]) rhs = ".".join(qualified_parts[x:]) if env.find_nonlocal(lhs) is not None: path = [env.find_nonlocal(lhs)] break elif env.find_method_by_name(lhs, arglist) is not None and rhs == "": path = [env.find_method_by_name(lhs, arglist)] break # resolving LHS is a Class elif canBeClass and env.findclass(lhs) is not None: path = [env.findclass(lhs)] break error_if(len(path) == 0, "Cannot find declaration for %s %s" % (type, name)) if isvariable(path[-1]) or (path[-1].tag == "method" and rhs): if isarray(type_string(path[-1])): new_env = env.findclass("java.lang.$Array").env else: if isarray(type_string(path[-1])): new_env = env.findclass("java.lang.$Array").env else: error_if(is_primitive(type_string(path[-1])), "Method called on primitive.") new_env = path[-1].env.findclass( type_string(path[-1])).env else: new_env = path[-1].env path += get_declaration_site_for_name_internal(new_env, rhs, type, arglist, False) return path