Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
60 changes: 32 additions & 28 deletions codeflash/lsp/lsp_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import logging
import sys
from dataclasses import dataclass
from typing import Any, Callable, Optional
from typing import Any, Callable

from codeflash.lsp.helpers import is_LSP_enabled
from codeflash.lsp.lsp_message import LspTextMessage
from codeflash.lsp.lsp_message import LspTextMessage, message_delimiter

root_logger = None

Expand Down Expand Up @@ -43,16 +43,19 @@ def add_heading_tags(msg: str, tags: LspMessageTags) -> str:
return msg


def extract_tags(msg: str) -> tuple[Optional[LspMessageTags], str]:
def extract_tags(msg: str) -> tuple[LspMessageTags, str]:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was optimized by codeflash extension

delimiter = "|"
parts = msg.split(delimiter)
if len(parts) == 2:
first_delim_idx = msg.find(delimiter)
if first_delim_idx != -1 and msg.count(delimiter) == 1:
tags_str = msg[:first_delim_idx]
content = msg[first_delim_idx + 1 :]
tags = {tag.strip() for tag in tags_str.split(",")}
message_tags = LspMessageTags()
tags = {tag.strip() for tag in parts[0].split(",")}
if "!lsp" in tags:
message_tags.not_lsp = True
# manually check and set to avoid repeated membership tests
if "lsp" in tags:
message_tags.lsp = True
if "!lsp" in tags:
message_tags.not_lsp = True
if "force_lsp" in tags:
message_tags.force_lsp = True
if "loading" in tags:
Expand All @@ -67,9 +70,9 @@ def extract_tags(msg: str) -> tuple[Optional[LspMessageTags], str]:
message_tags.h3 = True
if "h4" in tags:
message_tags.h4 = True
return message_tags, delimiter.join(parts[1:])
return message_tags, content

return None, msg
return LspMessageTags(), msg


supported_lsp_log_levels = ("info", "debug")
Expand All @@ -86,31 +89,32 @@ def enhanced_log(
actual_log_fn(msg, *args, **kwargs)
return

is_lsp_json_message = msg.startswith('{"type"')
is_lsp_json_message = msg.startswith(message_delimiter)
is_normal_text_message = not is_lsp_json_message

# extract tags only from the text messages (not the json ones)
tags, clean_msg = extract_tags(msg) if is_normal_text_message else (None, msg)
# Extract tags only from text messages
tags, clean_msg = extract_tags(msg) if is_normal_text_message else (LspMessageTags(), msg)

lsp_enabled = is_LSP_enabled()
lsp_only = tags and tags.lsp

if not lsp_enabled and not lsp_only:
# normal logging
actual_log_fn(clean_msg, *args, **kwargs)
return

#### LSP mode ####
final_tags = tags if tags else LspMessageTags()

unsupported_level = level not in supported_lsp_log_levels
if not final_tags.force_lsp and (final_tags.not_lsp or unsupported_level):
return

# ---- Normal logging path ----
if not tags.lsp:
if not lsp_enabled: # LSP disabled
actual_log_fn(clean_msg, *args, **kwargs)
return
if tags.not_lsp: # explicitly marked as not for LSP
actual_log_fn(clean_msg, *args, **kwargs)
return
if unsupported_level and not tags.force_lsp: # unsupported level
actual_log_fn(clean_msg, *args, **kwargs)
return

# ---- LSP logging path ----
if is_normal_text_message:
clean_msg = add_heading_tags(clean_msg, final_tags)
clean_msg = add_highlight_tags(clean_msg, final_tags)
clean_msg = LspTextMessage(text=clean_msg, takes_time=final_tags.loading).serialize()
clean_msg = add_heading_tags(clean_msg, tags)
clean_msg = add_highlight_tags(clean_msg, tags)
clean_msg = LspTextMessage(text=clean_msg, takes_time=tags.loading).serialize()

actual_log_fn(clean_msg, *args, **kwargs)

Expand Down
9 changes: 4 additions & 5 deletions codeflash/lsp/lsp_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
json_primitive_types = (str, float, int, bool)
max_code_lines_before_collapse = 45

# \u241F is the message delimiter becuase it can be more than one message sent over the same message, so we need something to separate each message
message_delimiter = "\u241f"


@dataclass
class LspMessage:
Expand All @@ -32,12 +35,8 @@ def type(self) -> str:

def serialize(self) -> str:
data = self._loop_through(asdict(self))
# Important: keep type as the first key, for making it easy and fast for the client to know if this is a lsp message before parsing it
ordered = {"type": self.type(), **data}
return (
json.dumps(ordered)
+ "\u241f" # \u241F is the message delimiter becuase it can be more than one message sent over the same message, so we need something to separate each message
)
return message_delimiter + json.dumps(ordered) + message_delimiter


@dataclass
Expand Down
1 change: 0 additions & 1 deletion codeflash/optimization/function_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,6 @@ def line_profiler_step(
self, code_context: CodeOptimizationContext, original_helper_code: dict[Path, str], candidate_index: int
) -> dict:
try:
logger.info("Running line profiling to identify performance bottlenecks…")
console.rule()

test_env = self.get_test_env(
Expand Down
Loading