Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change get_global_offset_from_line to also take an optional character position #201

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from
20 changes: 13 additions & 7 deletions crytic_compile/crytic_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def __init__(self, target: Union[str, AbstractPlatform], **kwargs: str):
# We decided to favor the running time versus memory
self._cached_offset_to_line: Dict[Filename, Dict[int, Tuple[int, int]]] = dict()
# Lines are indexed from 1
self._cached_line_to_offset: Dict[Filename, Dict[int, int]] = defaultdict(dict)
self._cached_line_to_offset: Dict[Filename, Dict[Tuple[int, int], int]] = defaultdict(dict)

# Return the line from the line number
# Note: line 1 is at index 0
Expand Down Expand Up @@ -254,16 +254,19 @@ def _get_cached_offset_to_line(self, file: Filename) -> None:
acc = 0
lines_delimiters: Dict[int, Tuple[int, int]] = dict()
for line_number, x in enumerate(source_code):
self._cached_line_to_offset[file][line_number + 1] = acc

for i in range(acc, acc + len(x)):
lines_delimiters[i] = (line_number + 1, i - acc + 1)
line_and_char_position = (line_number + 1, i - acc + 1)
lines_delimiters[i] = line_and_char_position
self._cached_line_to_offset[file][line_and_char_position] = i

acc += len(x)
lines_delimiters[acc] = (len(source_code) + 1, 0)
self._cached_offset_to_line[file] = lines_delimiters

def get_line_from_offset(self, filename: Union[Filename, str], offset: int) -> Tuple[int, int]:
def get_line_and_character_from_offset(
self, filename: Union[Filename, str], offset: int
) -> Tuple[int, int]:
"""Return the line from a given offset

Args:
Expand All @@ -283,12 +286,15 @@ def get_line_from_offset(self, filename: Union[Filename, str], offset: int) -> T
lines_delimiters = self._cached_offset_to_line[file]
return lines_delimiters[offset]

def get_global_offset_from_line(self, filename: Union[Filename, str], line: int) -> int:
"""Return the global offset from a given line
def get_global_offset_from_line_and_character(
self, filename: Union[Filename, str], line: int, char_position: int = 1
) -> int:
"""Return the global offset from a given line and charater

Args:
filename (Union[Filename, str]): filename
line (int): line
char_position (int): Line offset. Added to the global offset of the line starting position

Returns:
int: global offset
Expand All @@ -300,7 +306,7 @@ def get_global_offset_from_line(self, filename: Union[Filename, str], line: int)
if file not in self._cached_line_to_offset:
self._get_cached_offset_to_line(file)

return self._cached_line_to_offset[file][line]
return self._cached_line_to_offset[file][(line, char_position)]

def _get_cached_line_to_code(self, file: Filename) -> None:
"""Compute the cached lines
Expand Down
6 changes: 3 additions & 3 deletions crytic_compile/platform/truffle.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
if stderr:
LOGGER.error(stderr)
if not os.path.isdir(os.path.join(self._target, build_directory)):
if os.path.isdir(os.path.join(self._target, "node_modules")):
if not os.path.isdir(os.path.join(self._target, "node_modules")):
raise InvalidCompilation(
f"External dependencies {build_directory} {self._target} not found, please install them. (npm install)"
"External dependencies not found, please install them. (npm install)"
)
raise InvalidCompilation("`truffle compile` failed. Can you run it?")
raise InvalidCompilation(f"`truffle compile` failed. Can you run It? Output:\n{stdout}")
filenames = glob.glob(os.path.join(self._target, build_directory, "*.json"))

optimized = None
Expand Down