Skip to content
This repository was archived by the owner on Apr 4, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions python/selfie-lib/selfie_lib/CommentTracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from typing import Dict, Iterable, Tuple
from enum import Enum, auto
import threading
from selfie_lib.TypedPath import TypedPath
from selfie_lib.Slice import Slice


# Placeholder implementations for CallStack, SnapshotFileLayout, and FS
class CallStack:
pass


class SnapshotFileLayout:
def sourcePathForCall(self, location) -> "TypedPath":
# Placeholder return or raise NotImplementedError
raise NotImplementedError("sourcePathForCall is not implemented")


class WritableComment(Enum):
NO_COMMENT = auto()
ONCE = auto()
FOREVER = auto()

@property
def writable(self) -> bool:
return self != WritableComment.NO_COMMENT


class CommentTracker:
def __init__(self):
self.cache: Dict[TypedPath, WritableComment] = {}
self.lock = threading.Lock()

def pathsWithOnce(self) -> Iterable[TypedPath]:
with self.lock:
return [
path
for path, comment in self.cache.items()
if comment == WritableComment.ONCE
]

def hasWritableComment(self, call: CallStack, layout: SnapshotFileLayout) -> bool:
path = layout.sourcePathForCall(call)
with self.lock:
if path in self.cache:
comment = self.cache[path]
if comment.writable:
return True
else:
return False
else:
new_comment, _ = self.__commentAndLine(path)
self.cache[path] = new_comment
return new_comment.writable

@staticmethod
def commentString(typedPath: TypedPath) -> Tuple[str, int]:
comment, line = CommentTracker.__commentAndLine(typedPath)
if comment == WritableComment.NO_COMMENT:
raise ValueError("No writable comment found")
elif comment == WritableComment.ONCE:
return ("//selfieonce", line)
elif comment == WritableComment.FOREVER:
return ("//SELFIEWRITE", line)
else:
raise ValueError("Invalid comment type")

@staticmethod
def __commentAndLine(typedPath: TypedPath) -> Tuple[WritableComment, int]:
with open(typedPath.absolute_path, "r") as file:
content = Slice(file.read())
for comment_str in [
"//selfieonce",
"// selfieonce",
"//SELFIEWRITE",
"// SELFIEWRITE",
]:
index = content.indexOf(comment_str)
if index != -1:
lineNumber = content.baseLineAtOffset(index)
comment = (
WritableComment.ONCE
if "once" in comment_str
else WritableComment.FOREVER
)
return (comment, lineNumber)
return (WritableComment.NO_COMMENT, -1)
3 changes: 3 additions & 0 deletions python/selfie-lib/selfie_lib/TypedPath.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ class TypedPath:
def __init__(self, absolute_path: str):
self.absolute_path = absolute_path

def __hash__(self):
return hash(self.absolute_path)

@property
def name(self) -> str:
if self.absolute_path.endswith("/"):
Expand Down