def scan(self, asts): """Main method to initiate the scanning.""" # First build up list of all possible types for use by the rest # of the type checking process for ast in asts: self._t_env.add_type(ast.children[0].value) # Next visit the top level nodes - class or interface dcls for ast in asts: visit(self, ast) # If a class implements an interface, check it implements it correctly self._verify_implementations(asts)
def _add_members(self, symbol, node): """For a class or interface symbol, and it's corresponding ast node, add it's method and field symbols to the class or interface (methods only for interface) symbol. """ dcls = None try: dcls = node.children[3].children except IndexError: # It's an interface dcls = node.children[2].children except AttributeError: # The class body was empty return for dcl in sorted(dcls): # Sorted causes the field dcls to appear first, so after, the # parameters can be checked for name clashes dcl_s = visit(self, dcl) if dcl_s != None: if isinstance(dcl_s, MethodSymbol): symbol.add_method(dcl_s) elif isinstance(dcl_s, ConstructorSymbol): symbol.constructor = dcl_s else: # It's a field self._check_field_name(dcl_s) symbol.add_field(dcl_s)
def _scan_method_array(self, node): """Create a method symbol for a method which returns an array type. """ name = node.children[0].value type_ = self._get_method_node_type(node) type_ = ArrayType(type_, node.children[2].value) params = visit(self, node.children[3]) if params == None: params = [] method_s = MethodSymbol(name, type_, params) method_s.modifiers = node.modifiers return method_s
def _visit_constructor_dcl_node(self, node): """Creates a constructor symbol in much the same way as regular methods. The difference is constructors do not have return types. """ name = node.children[0].value # Create variable symbols for each parameter, and add them to # the method symbol params = visit(self, node.children[1]) if params == None: params = [] constructor_s = ConstructorSymbol(name, params) constructor_s.modifiers = node.modifiers return constructor_s
def _scan_method(self, node): """Helper method for scan_classes_methods which scans properties of the method, create a symbol for it, and returns it """ name = node.children[0].value type_ = self._get_method_node_type(node) # Create variable symbols for each parameter, and add them to # the method symbol params = visit(self, node.children[2]) if params == None: params = [] method_s = MethodSymbol(name, type_, params) try: method_s.modifiers = node.modifiers except AttributeError: # Abstract methods do not have modifiers pass return method_s