예제 #1
0
    def _parse_function(self, function_data: Dict):
        func = Function()
        func.set_offset(function_data["src"], self._contract.slither)
        func.set_contract(self._contract)
        func.set_contract_declarer(self._contract)

        func_parser = FunctionSolc(func, function_data, self)
        self._contract.slither.add_function(func)
        self._functions_no_params.append(func_parser)
        self._functions_parser.append(func_parser)

        self._slither_parser.add_functions_parser(func_parser)
예제 #2
0
    def _parse_function(self, function_data: Dict):
        func = FunctionContract(self._contract.compilation_unit)
        func.set_offset(function_data["src"], self._contract.compilation_unit)
        func.set_contract(self._contract)
        func.set_contract_declarer(self._contract)

        func_parser = FunctionSolc(func, function_data, self, self._slither_parser)
        self._contract.compilation_unit.add_function(func)
        self._functions_no_params.append(func_parser)
        self._functions_parser.append(func_parser)

        self._slither_parser.add_function_or_modifier_parser(func_parser)
예제 #3
0
 def _parse_function(self, function):
     func = FunctionSolc(function, self)
     func.set_offset(function['src'], self.slither)
     self._functions_no_params.append(func)
    def parse_top_level_from_loaded_json(
        self, data_loaded: Dict, filename: str
    ):  # pylint: disable=too-many-branches,too-many-statements
        if "nodeType" in data_loaded:
            self._is_compact_ast = True

        if "sourcePaths" in data_loaded:
            for sourcePath in data_loaded["sourcePaths"]:
                if os.path.isfile(sourcePath):
                    self._compilation_unit.core.add_source_code(sourcePath)

        if data_loaded[self.get_key()] == "root":
            logger.error("solc <0.4 is not supported")
            return
        if data_loaded[self.get_key()] == "SourceUnit":
            self._parse_source_unit(data_loaded, filename)
        else:
            logger.error("solc version is not supported")
            return

        for top_level_data in data_loaded[self.get_children()]:
            if top_level_data[self.get_key()] == "ContractDefinition":
                contract = Contract(self._compilation_unit)
                contract_parser = ContractSolc(self, contract, top_level_data)
                if "src" in top_level_data:
                    contract.set_offset(top_level_data["src"], self._compilation_unit)

                self._underlying_contract_to_parser[contract] = contract_parser

            elif top_level_data[self.get_key()] == "PragmaDirective":
                if self._is_compact_ast:
                    pragma = Pragma(top_level_data["literals"])
                else:
                    pragma = Pragma(top_level_data["attributes"]["literals"])
                pragma.set_offset(top_level_data["src"], self._compilation_unit)
                self._compilation_unit.pragma_directives.append(pragma)
            elif top_level_data[self.get_key()] == "ImportDirective":
                if self.is_compact_ast:
                    import_directive = Import(top_level_data["absolutePath"])
                    # TODO investigate unitAlias in version < 0.7 and legacy ast
                    if "unitAlias" in top_level_data:
                        import_directive.alias = top_level_data["unitAlias"]
                else:
                    import_directive = Import(top_level_data["attributes"].get("absolutePath", ""))
                import_directive.set_offset(top_level_data["src"], self._compilation_unit)
                self._compilation_unit.import_directives.append(import_directive)

            elif top_level_data[self.get_key()] == "StructDefinition":
                st = StructureTopLevel()
                st.set_offset(top_level_data["src"], self._compilation_unit)
                st_parser = StructureTopLevelSolc(st, top_level_data, self)

                self._compilation_unit.structures_top_level.append(st)
                self._structures_top_level_parser.append(st_parser)

            elif top_level_data[self.get_key()] == "EnumDefinition":
                # Note enum don't need a complex parser, so everything is directly done
                self._parse_enum(top_level_data)

            elif top_level_data[self.get_key()] == "VariableDeclaration":
                var = TopLevelVariable()
                var_parser = TopLevelVariableSolc(var, top_level_data)
                var.set_offset(top_level_data["src"], self._compilation_unit)

                self._compilation_unit.variables_top_level.append(var)
                self._variables_top_level_parser.append(var_parser)
            elif top_level_data[self.get_key()] == "FunctionDefinition":
                func = FunctionTopLevel(self._compilation_unit)
                func_parser = FunctionSolc(func, top_level_data, None, self)

                self._compilation_unit.functions_top_level.append(func)
                self._functions_top_level_parser.append(func_parser)
                self.add_function_or_modifier_parser(func_parser)

            else:
                raise SlitherException(f"Top level {top_level_data[self.get_key()]} not supported")
예제 #5
0
    def parse_top_level_from_loaded_json(self, data_loaded: Dict,
                                         filename: str):  # pylint: disable=too-many-branches,too-many-statements,too-many-locals
        if "nodeType" in data_loaded:
            self._is_compact_ast = True

        if "sourcePaths" in data_loaded:
            for sourcePath in data_loaded["sourcePaths"]:
                if os.path.isfile(sourcePath):
                    self._compilation_unit.core.add_source_code(sourcePath)

        if data_loaded[self.get_key()] == "root":
            logger.error("solc <0.4 is not supported")
            return
        if data_loaded[self.get_key()] == "SourceUnit":
            self._parse_source_unit(data_loaded, filename)
        else:
            logger.error("solc version is not supported")
            return

        if self.get_children() not in data_loaded:
            return
        scope = self.compilation_unit.get_scope(filename)

        for top_level_data in data_loaded[self.get_children()]:
            if top_level_data[self.get_key()] == "ContractDefinition":
                contract = Contract(self._compilation_unit, scope)
                contract_parser = ContractSolc(self, contract, top_level_data)
                scope.contracts[contract.name] = contract
                if "src" in top_level_data:
                    contract.set_offset(top_level_data["src"],
                                        self._compilation_unit)

                self._underlying_contract_to_parser[contract] = contract_parser

            elif top_level_data[self.get_key()] == "PragmaDirective":
                if self._is_compact_ast:
                    pragma = Pragma(top_level_data["literals"], scope)
                    scope.pragmas.add(pragma)
                else:
                    pragma = Pragma(top_level_data["attributes"]["literals"],
                                    scope)
                    scope.pragmas.add(pragma)
                pragma.set_offset(top_level_data["src"],
                                  self._compilation_unit)
                self._compilation_unit.pragma_directives.append(pragma)
            elif top_level_data[self.get_key()] == "ImportDirective":
                if self.is_compact_ast:
                    import_directive = Import(
                        Path(top_level_data["absolutePath"], ),
                        scope,
                    )
                    scope.imports.add(import_directive)
                    # TODO investigate unitAlias in version < 0.7 and legacy ast
                    if "unitAlias" in top_level_data:
                        import_directive.alias = top_level_data["unitAlias"]
                    if "symbolAliases" in top_level_data:
                        symbol_aliases = top_level_data["symbolAliases"]
                        _handle_import_aliases(symbol_aliases,
                                               import_directive, scope)
                else:
                    import_directive = Import(
                        Path(
                            top_level_data["attributes"].get(
                                "absolutePath", ""), ),
                        scope,
                    )
                    scope.imports.add(import_directive)
                    # TODO investigate unitAlias in version < 0.7 and legacy ast
                    if ("attributes" in top_level_data
                            and "unitAlias" in top_level_data["attributes"]):
                        import_directive.alias = top_level_data["attributes"][
                            "unitAlias"]
                import_directive.set_offset(top_level_data["src"],
                                            self._compilation_unit)
                self._compilation_unit.import_directives.append(
                    import_directive)

                get_imported_scope = self.compilation_unit.get_scope(
                    import_directive.filename)
                scope.accessible_scopes.append(get_imported_scope)

            elif top_level_data[self.get_key()] == "StructDefinition":
                scope = self.compilation_unit.get_scope(filename)
                st = StructureTopLevel(self.compilation_unit, scope)
                st.set_offset(top_level_data["src"], self._compilation_unit)
                st_parser = StructureTopLevelSolc(st, top_level_data, self)
                scope.structures[st.name] = st

                self._compilation_unit.structures_top_level.append(st)
                self._structures_top_level_parser.append(st_parser)

            elif top_level_data[self.get_key()] == "EnumDefinition":
                # Note enum don't need a complex parser, so everything is directly done
                self._parse_enum(top_level_data, filename)

            elif top_level_data[self.get_key()] == "VariableDeclaration":
                var = TopLevelVariable(scope)
                var_parser = TopLevelVariableSolc(var, top_level_data, self)
                var.set_offset(top_level_data["src"], self._compilation_unit)

                self._compilation_unit.variables_top_level.append(var)
                self._variables_top_level_parser.append(var_parser)
                scope.variables[var.name] = var
            elif top_level_data[self.get_key()] == "FunctionDefinition":
                scope = self.compilation_unit.get_scope(filename)
                func = FunctionTopLevel(self._compilation_unit, scope)
                scope.functions.add(func)
                func.set_offset(top_level_data["src"], self._compilation_unit)
                func_parser = FunctionSolc(func, top_level_data, None, self)

                self._compilation_unit.functions_top_level.append(func)
                self._functions_top_level_parser.append(func_parser)
                self.add_function_or_modifier_parser(func_parser)

            elif top_level_data[self.get_key()] == "ErrorDefinition":
                scope = self.compilation_unit.get_scope(filename)
                custom_error = CustomErrorTopLevel(self._compilation_unit,
                                                   scope)
                custom_error.set_offset(top_level_data["src"],
                                        self._compilation_unit)

                custom_error_parser = CustomErrorSolc(custom_error,
                                                      top_level_data, self)
                scope.custom_errors.add(custom_error)
                self._compilation_unit.custom_errors.append(custom_error)
                self._custom_error_parser.append(custom_error_parser)

            elif top_level_data[
                    self.get_key()] == "UserDefinedValueTypeDefinition":
                assert "name" in top_level_data
                alias = top_level_data["name"]
                assert "underlyingType" in top_level_data
                underlying_type = top_level_data["underlyingType"]
                assert ("nodeType" in underlying_type and
                        underlying_type["nodeType"] == "ElementaryTypeName")
                assert "name" in underlying_type

                original_type = ElementaryType(underlying_type["name"])

                user_defined_type = TypeAliasTopLevel(original_type, alias,
                                                      scope)
                user_defined_type.set_offset(top_level_data["src"],
                                             self._compilation_unit)
                scope.user_defined_types[alias] = user_defined_type

            else:
                raise SlitherException(
                    f"Top level {top_level_data[self.get_key()]} not supported"
                )