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