예제 #1
0
 def check_path_for_static(self, path):
     static_context = is_static_context(self.tree)
     for path_index in xrange(len(path)):
         path_element = path[path_index]
         if isvariable(path_element) or is_method(path_element):
             if not path_index:
                 if path_element.tag in ["field", "method"]:
                     error_if(is_static_context(path_element),
                           "Non-static access to static member.")
                     error_if(statisicity_mismatch(static_context,
                                                   is_static_context(path_element)),
                           "Direct statisicity mismatch.")
             elif path_index > 0:
                 previous_element = path[path_index - 1]
                 if is_class(previous_element):
                     error_if(not is_static_context(path_element),
                           "Cannot access non-static from static context.")
                 elif isvariable(previous_element):
                     error_if(is_static_context(path_element),
                           "Cannot access static from non-static context.")
예제 #2
0
def check_field_initializers(tree):
    #Check the rules specified in Section 8.3.2.3 of the Java Language
    #Specification regarding forward references. The initializer of a
    #non-static field must not use (i.e. read) by simple name (i.e. without an
    #explicit this) itself or a non-static field declared later in the same
    #class.

    #The declaration of a member needs to appear before it is used only if the
    #member is an instance (respectively static) field of a class or interface
    #C and all of the following conditions hold:

    #The usage occurs in an instance (respectively static) variable initializer
    #of C or in an instance (respectively static) initializer of C.

    #The usage is not on the left hand side of an assignment.
    #C is the innermost class or interface enclosing the usage.
    fields = tree.findall(".//field")
    for x in xrange(len(fields)):
        field = fields[x]
        forward_references = fields[x:]
        forward_reference_names = []
        for forward_reference in forward_references:
            forward_reference_names.append(
                name_to_str(forward_reference.find(".//variable")))

        potential_elements = set()
        expression_element = field.find("expression")
        if expression_element is not None:
            for child in expression_element.findall(".//name"):
                child_name = name_to_str(child).split(".")[0]
                if child_name in forward_reference_names:
                    potential_elements.add(child)
            valid_references = field.findall(".//left_hand_side/name")
            valid_references += \
                field.findall(".//class_instance_creation_expression/name")
            for child in valid_references:
                for subchild in child.getiterator():
                    potential_elements.discard(subchild)
            error_if(len(potential_elements),
                  "Forward reference not allowed in initializer.")

        if static_declaration(field):
            for name in field.findall(".//name"):
                if hasattr(child, "declaration") and isvariable(child.declaration):
                    field.env.get_declaration_site_for_variable_name(name_to_str(name),name)
예제 #3
0
        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