def return_statement(node): '''Check statement: return E''' if not isinstance(node, ast_return.ASTReturn): return None method = type_checker.get_param('cur_method') # If there is an expression, make sure it is typeable. expr_type = None if len(node.expressions) != 0: expr_type = type_checker.get_type(node.expressions[0]) # Constructors have no return type, so you can't return something in one: if method.is_constructor and expr_type: return None # void methods should return nothing: if method.return_type == ast_type.ASTType.ASTVoid and not expr_type: return True # constructors should return nothing: if method.is_constructor and not expr_type: return True # The type you return must be assignable to the current method return type: if not _is_assignable(method.return_type, expr_type): return None return ast_type.ASTType.ASTVoid
def _valid_protected_access(encl_type, instance_type = None): '''Check if protected access is valid. JLS 6.6: Protected access is allowed if: - The access is done from within the same package as the type declaring the property. OR - The class containing the property is a subtype of the class delcaring the property, and - (For instance property access) The type of the variable with the instance property is a subtype of the calling type. ''' cur_type = type_checker.get_param('cur_class') # If the access is from the same package, then it is permitted. if ast_node.ASTUtils.is_in_package( cur_type.package_name, encl_type.package_name): return True # If the calling type is not a subtype of the enclosing type, them the access # is not permitted. if not ast_node.ASTUtils.is_subtype(cur_type, encl_type): return False if instance_type is not None: # If we're doing an instance property access and the instance variable is # not a subtype of the type doing the access, then the access is not # permitted. if not ast_node.ASTUtils.is_subtype(instance_type, cur_type): return False return True
def constructor(node): '''new D(E1, E2, .., Ek) types to D''' if not isinstance(node, ast_expression.ASTClassInstanceCreation): return None # You can't instantiate abstract classes. if node.type_node.definition.is_abstract: return None short_name = node.type_node.identifier.parts[-1] env = node.type_node.definition.environment param_types = [type_checker.get_type(x) for x in node.arguments] method_sig = (short_name, param_types) method, enclosing_type = env.lookup_method(method_sig, constructor=True) if method is not None: if method.is_protected: # JLS 6.6.2. A protected constructor can be accessed only from within the # package in which it is defined. if enclosing_type.package_name != \ type_checker.get_param('cur_class').package_name: return None return node.type_node # No matching constructor found. Whoops...! return None